Skip to content

Instantly share code, notes, and snippets.

@CanRau
Last active January 14, 2016 19:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CanRau/e07307fbb5f8daf2c698 to your computer and use it in GitHub Desktop.
Save CanRau/e07307fbb5f8daf2c698 to your computer and use it in GitHub Desktop.
<?php namespace ProcessWire;
/**
* An Inputfield for handling relational Page inputs
*
* Delegates the actual input control to a user-defined Inputfield derived from InputfieldSelect
*
* @method PageArray getSelectablePages(Page $page)
* @method PageArray findPagesCode(Page $page)
*
* Can be accessed from $this or from $field:
*
* @property int $template_id
* @property int $parent_id
* @property string $inputfield
* @property string $labelFieldName Field name to use for label (note: this will be "." if $labelFieldFormat is in use).
* @property string $labelFieldFormat Formatting string for $page->getMarkup() as alternative to $labelFieldName
* @property string $findPagesCode
* @property string $findPagesSelector
* @property int|bool $addable
* @property int|bool $allowUnpub
*
*
* <><><><><><><><><><> ADDED by Can <><><><><><><><><><>
* Put this file into /site/modules/ (optionally within a subfolder)
*
* required PW version >= 2.5.14
* Blog post about multiple module copies https://processwire.com/blog/posts/processwire-core-updates-2.5.14/
*
* For PW 3 devns it seems not necessary to choose the file, PW just takes the file of /site/modules/
*
* To use with PW < 3 devns remove namespace from the top
*
*/
class InputfieldPage extends Inputfield implements ConfigurableModule {
protected $inputfieldWidget = null;
protected static $defaultInputfieldClasses = array(
// default options
'InputfieldSelect',
'InputfieldSelectMultiple',
'InputfieldCheckboxes',
'InputfieldRadios',
'InputfieldAsmSelect',
'InputfieldPageListSelect',
'InputfieldPageAutocomplete',
);
protected static $defaultConfig = array(
'parent_id' => 0,
'template_id' => 0,
'inputfield' => '',
'labelFieldName' => '',
'labelFieldFormat' => '',
'findPagesCode' => '',
'findPagesSelector' => '',
'addable' => 0,
'allowUnpub' => 0, // This option configured by FieldtypePage:Advanced
);
/**
* Contains true when this module is in configuration state (via it's getConfigInputfields function)
*
*/
protected $configMode = false;
/**
* True when processInput is currently processing
*
*/
protected $processInputMode = false;
/**
* PageArray of pages that were added in the request
*
*/
protected $pagesAdded;
protected $classesAdded = array();
public static function getModuleInfo() {
return array(
'title' => 'Page',
'version' => 106,
'summary' => 'Select one or more pages',
'permanent' => true,
);
}
public function __construct() {
$this->set('inputfieldClasses', self::$defaultInputfieldClasses);
parent::__construct();
}
public function init() {
foreach(self::$defaultConfig as $key => $value) {
$this->set($key, $value);
}
$this->attr('value', new PageArray());
parent::init();
}
public function addClass($class, $property = 'class') {
if($property == 'class') {
$this->classesAdded[] = $class;
}
return parent::addClass($class, $property);
}
public function setAttribute($key, $value) {
if($key == 'value') {
if(is_string($value) || is_int($value)) {
// setting the value attr from a string, whether 1234 or 123|446|789
if(ctype_digit("$value")) {
// i.e. "1234"
$a = new PageArray();
$page = wire('pages')->get((int) $value);
if($page->id) $a->add($page);
$value = $a;
} else if(strpos($value, '|') !== false) {
// i.e. 123|456|789
$a = new PageArray();
foreach(explode('|', $value) as $id) {
if(!ctype_digit("$id")) continue;
$page = wire('pages')->get((int) $id);
if($page->id) $a->add($page);
}
$value = $a;
} else {
// unrecognized format
}
}
}
return parent::setAttribute($key, $value);
}
/**
* Is the given $page valid for the given $field?
*
* Note that this validates all but findPagesCode (eval) based page selections.
* This is primarily for use by FieldtypePage, but kept here since the config options
* it uses to check are part of this module's config.
*
* If false is returned and given an $editPage, a reason for the false will be populated
* to the $editPage->_isValidPage property.
*
* @param Page $page
* @param Field|string|int $field Field instance of field name (string) or ID
* @param Page $editPage Page being edited
* @return bool
* @throws WireException
*
*/
public static function isValidPage(Page $page, $field, Page $editPage = null) {
if(!$field instanceof Field) $field = wire('fields')->get($field);
if(!$field instanceof Field) throw new WireException('isValidPage requires a valid Field or field name');
if($editPage && $page->id == $editPage->id) {
$editPage->set('_isValidPage', "Page is referencing itself and circular page reference not allowed");
return false; // prevent circular reference
}
if(wire('pages')->cloning) {
return true; // bypass check when clong is active
}
$valid = true;
if($field->findPagesSelector) {
$selector = $field->findPagesSelector;
if($editPage) $selector = self::getFindPagesSelector($editPage, $selector);
if(!$page->matches($selector)) {
if($editPage) $editPage->set('_isValidPage', "Page $page does not match findPagesSelector: $selector");
$valid = false;
}
}
if($field->findPagesCode) {
// TODO: we don't currently validate these
}
if($field->parent_id && $field->parent_id != $page->parent_id) {
if(version_compare(PHP_VERSION, '5.3.8') >= 0) {
if(is_subclass_of($field->inputfield, 'InputfieldPageListSelection')) {
// parent_id represents a root parent
$rootParent = wire('pages')->get($field->parent_id);
if(!$page->parents()->has($rootParent)) $valid = false;
} else {
// parent_id represents a direct parent
$valid = false;
}
if(!$valid && $editPage) $editPage->set('_isValidPage', "Page $page does not have required parent $field->parent_id");
} else {
// PHP version prior to 5.3.8
$reflector = new ReflectionClass($field->inputfield);
$valid = $reflector->implementsInterface('InputfieldPageListSelection');
}
}
if($field->template_id && $page->template->id != $field->template_id) {
$valid = false;
if($editPage) $editPage->set('_isValidPage', "Page $page does not have required template $field->template_id");
}
return $valid;
}
/**
* Execute the findPagesCode
*
* @param Page $page The page being edited
* @return PageArray (hopefully)
*
*/
protected function ___findPagesCode(Page $page) {
if(empty($this->findPagesCode)) return new PageArray();
$pages = $this->wire('pages'); // so that it is locally scoped to the eval
return eval($this->findPagesCode);
}
public function has($key) {
// ensures it accepts any config value (like those for delegate inputfields)
return true;
}
/**
* Return PageArray of selectable pages for this input
*
* @param Page $page The Page being edited
* @return PageArray
*
*/
public function ___getSelectablePages(Page $page) {
$statusUnder = $this->allowUnpub ? Page::statusTrash : Page::statusUnpublished;
if($this->configMode) {
$children = new PageArray();
} else if($this->findPagesSelector) {
// a find() selector
$instance = $this->processInputMode ? $this : null;
$selector = self::getFindPagesSelector($page, $this->findPagesSelector, $instance);
$children = $this->pages->find($selector);
} else if($this->findPagesCode) {
// php statement that returns a PageArray or a Page (to represent a parent)
$children = $this->findPagesCode($page);
if($children instanceof Page) $children = $children->children(); // @teppokoivula
} else if($this->parent_id) {
$parent = $this->fuel('pages')->get($this->parent_id);
if($parent) $children = $this->template_id ? $parent->children("templates_id={$this->template_id}, check_access=0, status<$statusUnder") : $parent->children("check_access=0, status<$statusUnder");
} else if($this->template_id) {
$children = $this->pages->find("templates_id={$this->template_id}, check_access=0, status<$statusUnder");
} else {
$children = new PageArray();
}
if($children->has($page)) $children->remove($page); // don't allow page being edited to be selected
return $children;
}
/**
* Populate any variables in findPagesSelector
*
* @param Page $page
* @param string $selector
* @param Inputfield $inputfield
* @return string
*
*/
protected static function getFindPagesSelector(Page $page, $selector, $inputfield = null) {
// if an $inputfield is passed in, then we want to retrieve dependent values directly
// from the form, rather than from the $page
if($inputfield) {
// locate the $form
$n = 0;
$form = $inputfield;
do {
$form = $form->getParent();
if(++$n > 10) break;
} while($form && $form->className() != 'InputfieldForm');
} else $form = null;
// find variables identified by: page.field or page.field.subfield
if(strpos($selector, '=page.') !== false) {
preg_match_all('/=page\.([_.a-zA-Z0-9]+)/', $selector, $matches);
foreach($matches[0] as $key => $tag) {
$field = $matches[1][$key];
$subfield = '';
if(strpos($field, '.')) list($field, $subfield) = explode('.', $field);
$value = null;
if($form && (!$subfield || $subfield == 'id')) {
// attempt to get value from the form, to account for ajax changes that would not yet be reflected on the page
$in = $form->get($field);
if($in) $value = $in->attr('value');
}
if(is_null($value)) $value = $page->get($field);
if(is_object($value) && $subfield) $value = $value->$subfield;
if(is_array($value)) $value = implode('|', $value);
$selector = str_replace($tag, "=$value", $selector);
}
}
return $selector;
}
public function getInputfield() {
if($this->inputfieldWidget && ((string) $this->inputfieldWidget) == $this->inputfield) return $this->inputfieldWidget;
$inputfield = $this->wire('modules')->get($this->inputfield);
if(!$inputfield) return null;
if($this->derefAsPage) $inputfield->set('maxSelectedItems', 1);
$page = $this->page;
$process = $this->wire('process');
if($process && $process instanceof WirePageEditor) $page = $process->getPage();
$inputfield->attr('name', $this->attr('name'));
$inputfield->attr('id', $this->attr('id'));
$inputfield->label = $this->label;
$inputfield->description = $this->description;
if($this->collapsed == Inputfield::collapsedYesAjax ||
($this->collapsed == Inputfield::collapsedBlankAjax && $this->isEmpty())) {
// quick exit when possible due to ajax field, and not being time to render or process it
if($this->getParent()) {
// limit only to inputfields that have a parent, to keep out of other form contexts like Lister
$renderInputfieldAjax = $this->wire('input')->get('renderInputfieldAjax');
$processInputfieldAjax = $this->wire('input')->post('processInputfieldAjax');
if(!is_array($processInputfieldAjax)) $processInputfieldAjax = array();
if($renderInputfieldAjax != $this->attr('id') && !in_array($this->attr('id'), $processInputfieldAjax)) {
$this->inputfieldWidget = $inputfield;
return $inputfield;
}
}
}
if(method_exists($inputfield, 'addOption')) {
$children = $this->getSelectablePages($page);
if($children) foreach($children as $child) {
$label = '';
if(strlen($this->labelFieldFormat) && $this->labelFieldName == '.') {
$label = $child->getMarkup($this->labelFieldFormat);
} else if($this->labelFieldName === '.') {
// skip
} else if($this->labelFieldName) {
$label = $child->get($this->labelFieldName);
}
if(!strlen($label)) $label = $child->name;
if($child->hasStatus(Page::statusUnpublished)) $label .= ' ' . $this->_('(unpublished)');
$inputfield->addOption($child->id, $label);
}
} else {
if($this->parent_id) {
$inputfield->parent_id = $this->parent_id;
} else if($this->findPagesCode) {
// @teppokoivula: use findPagesCode to return single parent page
$child = $this->findPagesCode($page);
if($child instanceof Page) $inputfield->parent_id = $child->id;
}
if($this->template_id) $inputfield->template_id = $this->template_id;
if($this->findPagesSelector) $inputfield->findPagesSelector = $this->findPagesSelector;
if(strlen($this->labelFieldFormat) && $this->labelFieldName === '.') {
$inputfield->labelFieldName = $this->labelFieldFormat;
$inputfield->labelFieldFormat = $this->labelFieldFormat;
} else {
$inputfield->labelFieldName = $this->labelFieldName == '.' ? 'name' : $this->labelFieldName;
$inputfield->labelFieldFormat = '';
}
}
$ids = array();
$value = $this->attr('value');
if($value instanceof Page) $inputfield->attr('value', $value->id); // derefAsPage
else if($value instanceof PageArray) foreach($value as $v) $inputfield->attr('value', $v->id); // derefAsPageArray
// pass long any relevant configuration items
foreach($this->data as $key => $value) {
if(in_array($key, array('value', 'collapsed')) || array_key_exists($key, self::$defaultConfig)) continue;
if($key == 'required' && empty($this->data['defaultValue'])) continue; // for default value support with InputfieldSelect
$inputfield->set($key, $value);
}
$this->inputfieldWidget = $inputfield;
return $inputfield;
}
public function renderReady(Inputfield $parent = null, $renderValueMode = false) {
parent::renderReady($parent, $renderValueMode);
$inputfield = $this->getInputfield();
if(!$inputfield) {
$this->error("Not fully configured / currently nonfunctional");
return false;
}
$this->addClass('InputfieldNoFocus', 'wrapClass');
return $inputfield->renderReady($this, $renderValueMode);
}
public function ___render() {
$inputfield = $this->getInputfield();
if(!$inputfield) return $this->name;
$classes = InputfieldWrapper::getClasses();
$class = $inputfield->className();
if(isset($classes[$class]['item_content'])) $class .= " " . $classes[$class]['item_content'];
foreach($this->classesAdded as $addClass) $inputfield->addClass($addClass);
$out = "\n<div class='$class'>";
$out .= $inputfield->render();
$out .= $this->renderAddable();
if($this->findPagesSelector) {
$selector = $this->wire('sanitizer')->entities($this->findPagesSelector);
$formatName = '';
if(strlen($this->labelFieldFormat) && $this->labelFieldName === '.') {
/** @var ProcessPageSearch $pps */
$formatName = "page_$this->name";
$pps = $this->wire('modules')->get('ProcessPageSearch');
$pps->setDisplayFormat($formatName, $this->labelFieldFormat);
}
$labelFieldName = $this->labelFieldName == '.' ? 'name' : $this->labelFieldName;
$out .= "<input " .
"type='hidden' " .
"class='findPagesSelector' " .
"data-formatname='$formatName' " .
"data-label='$labelFieldName' " .
"value='$selector' />";
}
$out .= "\n</div>";
return $out;
}
protected function ___renderAddable() {
if(!$this->addable || !$this->parent_id || !$this->template_id) return '';
if($this->labelFieldName && $this->labelFieldName != 'title') return '';
$parent = $this->wire('pages')->get($this->parent_id);
$test = new Page();
$test->template = wire('templates')->get($this->template_id);
$test->parent = $parent;
$test->id = -1; // prevents permissions check from failing
if(!$parent->addable($test)) return '';
if(!$test->publishable()) return '';
$inputfield = wire('modules')->get($this->inputfield);
if(!$inputfield) return '';
$key = "_{$this->name}_add_items";
if($inputfield instanceof InputfieldHasArrayValue) {
// multi value
$description = $this->_('Enter the titles of the items you want to add, one per line. They will be created and added to your selection when you save the page.');
$input = "<textarea id='$key' name='$key' rows='5'></textarea>";
} else {
// single value
$description = $this->_('Enter the title of the item you want to add. It will become selected when you save the page.');
$input = "<input type='text' name='$key' id='$key' />";
}
$notes = sprintf($this->_('New pages will be added to %s'), $parent->path);
$label ="<i class='fa fa-plus-circle'></i> " . $this->_('Create New');
$out = "\n<div class='InputfieldPageAdd'>" .
"\n\t<p class='InputfieldPageAddButton'><a href='#'>$label</a></p>" .
"\n\t<p class='InputfieldPageAddItems'>" .
"\n\t\t<label class='description' for='$key'>$description</label>" .
"\n\t\t$input" .
"\n\t\t<span class='detail'>$notes</span>" .
"\n\t</p>" .
"\n</div>";
return $out;
}
public function ___renderValue() {
if($this->labelFieldName == '.') {
$labelFieldFormat = $this->labelFieldFormat;
$labelFieldName = 'title|name';
} else {
$labelFieldFormat = '';
$labelFieldName = $this->labelFieldName ? $this->labelFieldName : 'title';
$labelFieldName .= "|name";
}
$value = $this->attr('value');
if(is_array($value) || $value instanceof PageArray) {
$out = '<ul class="PageArray">';
foreach($value as $p) {
$of = $p->of();
$p->of(true);
$v = $labelFieldFormat ? $p->getMarkup($labelFieldFormat) : $p->get($labelFieldName);
if(!strlen($v)) $v = $p->get('name');
$out .= "<li>$v</li>";
$p->of($of);
}
$out .= "</ul>";
} else if($value instanceof Page) {
$of = $value->of();
$value->of(true);
$out = $labelFieldFormat ? $value->getMarkup($labelFieldFormat) : $value->get($labelFieldName);
if(!strlen($out)) $out = $value->get('name');
$value->of($of);
} else {
$out = $value;
}
return $out;
}
public function ___processInput(WireInputData $input) {
$this->processInputMode = true;
$inputfield = $this->getInputfield();
if(!$inputfield) return $this;
$inputfield->processInput($input);
$value = $this->attr('value');
$existingValueStr = $value ? "$value" : '';
$newValue = null;
$value = $inputfield->value;
if(is_array($value)) {
$newValue = new PageArray();
foreach($value as $v) {
$id = (int) $v;
if(!$id) continue;
if($id > 0) {
// existing page
$page = $this->wire('pages')->get($id);
if($page->hasStatus(Page::statusUnpublished) && !$this->allowUnpub) continue; // disallow unpublished
} else {
// placeholder for new page, to be sorted later
$page = new NullPage();
}
$newValue->add($page);
}
} else if($value) {
$newValue = $this->wire('pages')->get((int) $value);
if($newValue->hasStatus(Page::statusUnpublished) && !$this->allowUnpub) $newValue = null; // disallow unpublished
}
$this->setAttribute('value', $newValue);
$this->processInputAddPages($input);
// if pages were added, re-sort them in case they were dragged to a different order
// an example of this would be when used with the InputfieldPageAutocomplete
if(count($this->pagesAdded) && is_array($value)) {
$sortedValue = new PageArray();
foreach($newValue as $page) {
if($page->id < 1) $page = $this->pagesAdded->shift();
if($page->id && !$sortedValue->has($page)) $sortedValue->add($page);
}
$newValue = $sortedValue;
$this->setAttribute('value', $newValue);
}
if("$newValue" != "$existingValueStr") {
$this->trackChange('value');
}
$this->processInputMode = false;
return $this;
}
/**
* Check for the addable pages option and process if applicable
*
* @param WireInputData $input
*
*/
protected function ___processInputAddPages($input) {
$this->pagesAdded = new PageArray();
if(!$this->addable || !$this->parent_id || !$this->template_id) return;
$user = wire('user');
$key = "_{$this->name}_add_items";
$value = trim($input->$key);
if(empty($value)) return;
$parent = $this->pages->get($this->parent_id);
$sort = $parent->numChildren;
$titles = explode("\n", $value);
$publishable = false;
$n = 0;
foreach($titles as $title) {
/**
* added by Can
*/
if (strpos($title, ':') !== false) {
$titles = explode(':', $title);
list($title, $title_de) = $titles;
$german = $this->wire->languages->get('de');
}
/**
* added by Can
*/
// check if there is an existing page using this title
$existingPage = $parent->child("include=all, templates_id={$this->template_id}, title=" . $this->sanitizer->selectorValue($title));
if($existingPage->id) {
// use existing page
$this->pagesAdded->add($existingPage);
if($this->value instanceof PageArray) {
$this->value->add($existingPage);
continue;
} else {
$this->value = $existingPage;
break;
}
}
// create a new page
$page = new Page();
$page->template = $this->template_id;
$page->parent = $parent;
$page->title = trim($title);
/**
* added by Can
*/
if (isset($title_de)) {
$page->setLanguageValue($german, 'title', $title_de);
$page->setLanguageValue($german, 'name', $title_de);
$page->set("status$german->id", 1);
}
/**
* added by Can
*/
$page->sort = $sort++;
$page->id = -1; // prevents the permissions check from failing
// on first iteration perform a page-context access check
if(!$n && (!$parent->addable($page) || !$page->publishable())) {
$this->error("No access to add {$page->template} pages to {$parent->path}");
break;
}
$page->id = 0;
try {
$page->save();
$this->message(sprintf($this->_('Added page %s'), $page->path));
if($this->value instanceof PageArray) $this->value->add($page);
else $this->value = $page;
$this->pagesAdded->add($page);
$this->trackChange('value');
$n++;
} catch(Exception $e) {
$error = sprintf($this->_('Error adding page "%s"'), $page->title);
if($user->isSuperuser()) $error .= " - " . $e->getMessage();
$this->error($error);
break;
}
if($this->value instanceof Page) break;
}
}
public function isEmpty() {
$value = $this->attr('value');
if($value instanceof Page) {
// derefAsPage
return $value->id < 1;
} else if($value instanceof PageArray) {
// derefAsPageArray
if(!count($value)) return true;
} else {
// null
return true;
}
return false;
}
public function ___getConfigInputfields() {
// let the module know it's being used for configuration purposes
$this->configMode = true;
$exampleLabel = $this->_('Example:') . ' ';
$defaultLabel = ' ' . $this->_('(default)');
$inputfields = parent::___getConfigInputfields();
$fieldset = wire('modules')->get('InputfieldFieldset');
$fieldset->label = $this->_('Selectable Pages');
$fieldset->attr('name', '_selectable_pages');
$field = $this->modules->get('InputfieldPageListSelect');
$field->setAttribute('name', 'parent_id');
$field->label = $this->_('Parent of selectable page(s)');
$field->attr('value', (int) $this->parent_id);
$field->description = $this->_('Select the parent of the pages that are selectable.');
$field->required = false;
$fieldset->append($field);
$field = $this->modules->get('InputfieldSelect');
$field->setAttribute('name', 'template_id');
$field->label = $this->_('Template of selectable page(s)');
$field->attr('value', (int) $this->template_id);
$field->description = $this->_('Select the template of the pages that are selectable. May be used instead of, or in addition to, the parent above. NOTE: Not compatible with PageListSelect input field types.'); // Description for Template of selectable pages
foreach($this->templates as $template) $field->addOption($template->id, $template->name);
$field->collapsed = Inputfield::collapsedBlank;
$fieldset->append($field);
$field = $this->modules->get('InputfieldText');
$field->attr('name', 'findPagesSelector');
$field->label = $this->_('Custom selector to find selectable pages');
$field->attr('value', $this->findPagesSelector);
$field->description = $this->_('If you want to find selectable pages using a ProcessWire selector rather than selecting a parent page or template (above) then enter the selector to find the selectable pages. This selector will be passed to a $pages->find("your selector"); statement. NOTE: Not currently compatible with PageListSelect input field types.'); // Description for Custom selector to find selectable pages
$extra = $this->_('While this overrides parent and template selections above, those selections are still used for validation (de-select them if you do not want that behavior).'); // Additional notes
$field->description .= ' ' . $extra;
$field->notes = $exampleLabel . $this->_('parent=/products/, template=product, sort=name'); // Example of Custom selector to find selectable pages
$field->collapsed = Inputfield::collapsedBlank;
$fieldset->append($field);
$field = $this->modules->get('InputfieldTextarea');
$field->attr('name', 'findPagesCode');
$field->label = $this->_('Custom PHP code to find selectable pages');
$field->attr('value', $this->findPagesCode);
$field->attr('rows', 4);
$field->description = $this->_('If you want to find selectable pages using a PHP code snippet rather than selecting a parent page or template (above) then enter the code to find the selectable pages. This statement has access to the $page and $pages API variables, where $page refers to the page being edited.'); // Description for Custom PHP to find selectable pages 1
$field->description .= ' ' . $this->_('The snippet should return either a PageArray, Page or NULL. If it returns a Page, children of that Page are used as selectable pages. Using this is optional, and if used, it overrides the parent/template/selector fields above.'); // Description for Custom PHP to find selectable pages 2
$field->description .= ' ' . $extra;
$field->description .= ' ' . $this->_('NOTE: Not compatible with PageListSelect or Autocomplete input field types.'); // Description for Custom PHP to find selectable pages 3
$field->notes = $exampleLabel . $this->_('return $page->parent->parent->children("name=locations")->first()->children();'); // Example of Custom PHP code to find selectable pages
$field->collapsed = Inputfield::collapsedBlank;
$fieldset->append($field);
$inputfields->append($fieldset);
$field = $this->modules->get('InputfieldSelect');
$field->setAttribute('name', 'labelFieldName');
$field->setAttribute('value', $this->labelFieldName);
$field->label = $this->_('Label field');
$field->required = true;
$field->description = $this->_('Select the page field that you want to be used in generating the labels for each selectable page.'); // Description for Label Field
$field->notes = $this->_('Select "Custom format" if you want to specify multiple fields, or other fields you do not see above.');
$field->addOption('.', $this->_('Custom format (multiple fields)' . ' ...'));
$field->columnWidth = 50;
if($this->fuel('fields')->get('title')) {
$field->addOption('title', 'title' . $defaultLabel);
$field->addOption('name', 'name');
$titleIsDefault = true;
} else {
$field->addOption('name', 'name' . $defaultLabel);
$titleIsDefault = false;
}
$field->addOption('path', 'path');
foreach($this->fuel('fields') as $f) {
if(!$f->type instanceof FieldtypeText) continue;
if($f->type instanceof FieldtypeTextarea) continue;
if($titleIsDefault && $f->name == 'title') continue;
$field->addOption($f->name);
}
$inputfields->append($field);
$field = $this->modules->get('InputfieldText');
$field->attr('name', 'labelFieldFormat');
$field->attr('value', $this->labelFieldFormat);
$field->label = $this->_('Custom page label format');
$field->description = $this->_('Specify one or more field names surrounded by curly {brackets} along with any additional characters, spacing or punctuation.'); // Description for custom page label format
$field->notes = $this->_('Example: {parent.title} - {title}, {date}');
$field->columnWidth = 50;
$field->showIf = 'labelFieldName=.';
$field->required = true;
$field->requiredIf = 'labelFieldName=.';
$inputfields->add($field);
if(!$this->inputfield) $this->inputfield = 'InputfieldSelect';
$field = $this->modules->get('InputfieldSelect');
$field->setAttribute('name', 'inputfield');
$field->setAttribute('value', $this->inputfield);
$field->label = $this->_('Input field type');
$field->description = $this->_('The type of field that will be used to select a page. Select one that is consistent with the single page vs. multi-page needs you chose in the "details" tab of this field.'); // Description for Inputfield field type
$field->description .= ' ' . $this->_('Some input types may provide additional configuration options. After selecting an input field type, and then saving your changes, additional configuration options may appear below this section.'); // Description 2 for Inputfield field type
$field->required = true;
$field->notes = '* ' . $this->_('Types indicated with an asterisk are for multiple page selection.') . "\n" .
'+ ' . $this->_('Types indicated with a plus assume a "parent" to be the root of a tree, rather than an immediate parent.');
foreach($this->inputfieldClasses as $class) {
$module = $this->modules->get($class);
$label = str_replace("Inputfield", '', $class);
if($module instanceof InputfieldHasArrayValue) $label .= "*";
if(is_subclass_of($module, 'InputfieldPageListSelection')) $label .= "+";
$field->addOption($class, $label);
}
$inputfields->append($field);
$inputfield = $this->getInputfield();
if($inputfield) {
// then call again, knowing the module has it's config populated
$inputfield->hasFieldtype = true; // tell it it's under control of a parent, regardless of whether this one is hasFieldtype true or not.
foreach($inputfield->___getConfigInputfields() as $f) {
if(in_array($f->name, array('required', 'collapsed', 'columnWidth')) || array_key_exists($f->name, self::$defaultConfig)) continue;
if($f->name && $inputfields->getChildByName($f->name)) continue; // if we already have the given field, skip over it to avoid duplication
$inputfields->add($f);
}
}
if($this->hasFieldtype !== false) {
$field = $this->modules->get('InputfieldCheckbox');
$field->attr('name', 'addable');
$field->attr('value', 1);
$field->label = $this->_('Allow new pages to be created from field?');
$field->description = $this->_('If checked, an option to add new page(s) will also be present if the indicated requirements are met.');
$field->notes =
$this->_('1. Both a parent and template must be selected above.') . "\n" .
$this->_('2. The editing user must have access to create/publish these pages.') . "\n" .
$this->_('3. The label-field must be set to "title (default)".');
if($this->addable) $field->attr('checked', 'checked');
else $field->collapsed = Inputfield::collapsedYes;
$inputfields->append($field);
}
$this->configMode = false; // reverse what was set at the top of this function
return $inputfields;
}
static public function getModuleConfigInputfields(array $data) {
$name = 'inputfieldClasses';
if(!isset($data[$name]) || !is_array($data[$name])) $data[$name] = self::$defaultInputfieldClasses;
$fields = new InputfieldWrapper();
$modules = Wire::getFuel('modules');
$field = $modules->get("InputfieldAsmSelect");
$field->attr('name', $name);
foreach(Wire::getFuel('modules')->find('className^=Inputfield') as $inputfield) {
$field->addOption($inputfield->className(), str_replace('Inputfield', '', $inputfield->className()));
}
$field->attr('value', $data[$name]);
$field->label = __('Inputfield modules available for page selection', __FILE__);
$field->description = __('Select the Inputfield modules that may be used for page selection. These should generally be Inputfields that allow you to select one or more options.', __FILE__); // Description
$fields->append($field);
return $fields;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment