";
$out .= "" . $this->_('Children were found that may be added to this table. Check the box next to any you would like to add.') . " ";
if(count($this->orphans) > 1) $out .= " " . $this->_('Select all') . " ";
foreach($this->orphans as $item) {
$label = $item->title;
if(!strlen($label)) $label = $item->name;
$out .= "";
}
$out .= "
";
}
}
return $out;
}
/**
* Render non-editable value
*
* @return string
*
*/
public function ___renderValue() {
$this->renderValueMode = true;
$out = $this->render();
$this->renderValueMode = false;
return $out;
}
/**
* Render the outputted PageTable
";
}
/**
* Get the value for the given Page field identified by $column
*
* @param Page $item
* @param array $fields
* @param $column
* @return mixed|object|string
*
*/
protected function getItemValue(Page $item, array $fields, $column) {
$fieldName = $column;
$subfieldName = '';
if(strpos($column, '.') !== false) list($fieldName, $subfieldName) = explode('.', $column);
if(isset($fields[$column])) {
// custom
/** @var Field $field */
$field = $fields[$column];
$v = $item->getFormatted($fieldName);
$value = (string) $field->type->markupValue($item, $field, $v, $subfieldName);
} else {
// native
$value = $item->get($fieldName);
if(is_object($value) && $subfieldName) {
$value = $this->objectToString($value, $subfieldName);
$fieldName = $subfieldName;
}
if($fieldName == 'modified' || $fieldName == 'created' || $fieldName == 'published') {
$value = wireDate($this->_('Y-m-d H:i'), (int) $value); // Date format for created/modified/published
}
}
return $value;
}
/**
* Render an item edit link surrounded by the given output
*
* @param Page $item
* @param string $out
* @param string $url Optional
* @return string
*
*/
protected function renderItemLink(Page $item, $out, $url = '') {
if(!$url) $url = $this->getItemEditURL($item);
return "$out";
}
/**
* Get an item edit URL
*
* @param Page $item
* @return string
*
*/
protected function getItemEditURL(Page $item) {
return $this->wire('config')->urls->admin . "page/edit/?id=$item->id&modal=1&context=PageTable";
}
/**
* Convert an object to a string for rendering in a table
*
* @param $object
* @param string $property Property to display from the object (default=title|name)
* @return string
*
*/
protected function objectToString($object, $property = '') {
if($object instanceof WireArray) {
if(!$property) $property = 'title|name';
if($property == 'count') {
$value = $object->count();
} else {
$value = $object->implode("\n", $property);
}
} else if($property) {
$value = $object->$property;
if(is_object($value)) $value = $this->objectToString($value);
} else {
$value = (string) $object;
}
$value = $this->wire('sanitizer')->entities(strip_tags($value));
$value = nl2br($value);
return $value;
}
/**
* Process input submitted to a PageTable Inputfield
*
* @param WireInputData $input
* @return $this
*
*/
public function ___processInput(WireInputData $input) {
$name = $this->attr('name');
$deleteName = $name . '__delete';
$deleteIDs = explode('|', $input->$deleteName);
$ids = explode('|', $input->$name);
/** @var PageArray $value */
$value = $this->attr('value');
$sorted = $this->wire('pages')->newPageArray();
$changed = false;
// trash items that have been deleted
foreach($deleteIDs as $id) {
foreach($value as $item) {
/** @var Page $item */
if($id != $item->id) continue;
if(!$item->deleteable()) continue;
$value->remove($item);
$this->wire('pages')->trash($item);
$changed = true;
}
}
foreach($ids as $id) {
if(in_array($id, $deleteIDs)) continue;
foreach($value as $item) {
if($id == $item->id) $sorted->add($item);
}
}
// add in new items that may have been added after a sort
foreach($value as $item) {
if(!in_array($item->id, $ids)) $sorted->add($item);
}
// check for orphans that may have been added
$orphanInputName = $name . '__add_orphan';
$orphanIDs = $input->$orphanInputName;
if($orphanIDs && count($orphanIDs) && $this->orphans) {
$numOrphansAdded = 0;
foreach($orphanIDs as $orphanID) {
foreach($this->orphans as $orphan) {
if($orphan->id == $orphanID) {
$sorted->add($orphan);
$numOrphansAdded++;
}
}
}
if($numOrphansAdded) {
$this->message(sprintf($this->_('Added %d existing page(s) to table'), $numOrphansAdded) . " ($this->name)");
}
}
if("$value" != "$sorted") $changed = true;
if($changed) {
$this->setAttribute('value', $sorted);
$this->trackChange('value');
}
// check if we need to setup a name format for any pages
foreach($value as $n => $item) {
$name = $this->wire('pages')->setupPageName($item, array('format' => $this->nameFormat));
if($name) {
$this->message("Auto assigned name '$name' to item #" . ($n+1), Notice::debug);
$item->save();
}
}
return $this;
}
/**
* Set a property to this Inputfield
*
* @param string $key
* @param mixed $value
* @return $this
*
*/
public function set($key, $value) {
if($key == 'template_id' && $value) {
// convert template_id to $this->rowTemplates array
if(!is_array($value)) $value = array($value);
foreach($value as $id) {
$template = $this->wire('templates')->get($id);
if($template) $this->rowTemplates[$id] = $template;
}
return $this;
} else {
return parent::set($key, $value);
}
}
/**
* Set an attribute to the Inputfield
*
* In this case we capture set to the 'value' attribute to make sure it can only be a PageArray
*
* @param array|string $key
* @param int|string $value
* @return $this
* @throws WireException
*
*/
public function setAttribute($key, $value) {
if($key == 'value') {
if($value === null) $value = $this->wire('pages')->newPageArray();
if(!$value instanceof PageArray) throw new WireException('This Inputfield only accepts a PageArray for its value attribute.');
}
return parent::setAttribute($key, $value);
}
public function setOrphans(PageArray $orphans) {
$this->orphans = $orphans;
}
/**
* Determine a default set of columns for the PageTable based on the fields defined in the defined template
*
* @return string of newline separated field names
*
*/
protected function getConfigDefaultColumns() {
$out = '';
if(!count($this->rowTemplates)) return $out;
$fieldCounts = array();
foreach($this->rowTemplates as $template) {
foreach($template->fieldgroup as $field) {
if(!isset($fieldCounts[$field->name])) $fieldCounts[$field->name] = 1;
else $fieldCounts[$field->name]++;
}
}
// sort most used to least used
if(count($this->rowTemplates) > 1) arsort($fieldCounts);
$n = 0;
foreach(array_keys($fieldCounts) as $fieldName) {
$out .= $fieldName . "\n";
if(++$n >= 5) break;
}
return trim($out);
}
/**
* Get field configuration for input tab
*
* @return InputfieldWrapper
*
*/
public function ___getConfigInputfields() {
$inputfields = parent::___getConfigInputfields();
$f = $this->wire('modules')->get('InputfieldTextarea');
$f->attr('name', 'columns');
$f->label = $this->_('Table fields to display in admin');
$f->description = $this->_('Enter the names of the fields (1 per line) that you want to display as columns in the table. To specify a column width for the field, specify "field_name=30" where "30" is the width (in percent) of the column. When specifying widths, make the total of all columns add up to 100.'); // Columns description
$f->notes = $this->_('You may specify any native or custom field. You may also use subfields (field.subfield) with fields that contain multiple properties, like page references.') . ' '; // Columns notes
$columns = $this->columns ? $this->columns : $this->getConfigDefaultColumns();
$f->attr('value', $columns);
if(count($this->rowTemplates)) {
$options = array();
foreach($this->rowTemplates as $template) {
foreach($template->fieldgroup as $item) $options[$item->name] = $item->name;
}
$f->notes .= $this->_('Custom fields assigned to your selected templates include the following:') . ' **';
$f->notes .= implode(', ', $options) . '**';
} else {
$f->notes .= $this->_('To see a list of possible custom fields here, select a template on the Details tab, Save, and come back here.');
}
$inputfields->add($f);
$f = $this->wire('modules')->get('InputfieldText');
$f->attr('name', 'nameFormat');
$f->attr('value', $this->nameFormat);
$f->label = $this->_('Automatic Page Name Format');
$f->description = $this->_('When populated, pages will be created automatically using this name format whenever a user clicks the "Add New" button. If left blank, the user will be asked to enter a name for the page before it is created.'); // page name format description
$f->notes = $this->_('If the name format contains any non-alphanumeric characters, it is considered to be a [PHP date](http://www.php.net/manual/en/function.date.php) format. If it contains only alphanumeric characters then it will be used directly, with a number appended to the end (when necessary) to ensure uniqueness.'); // page name format notes
$f->notes .= ' ' . $this->_('Example: **Ymd:His** is a good name format for date/time based page names.');
$f->collapsed = Inputfield::collapsedBlank;
$inputfields->add($f);
$f = $this->wire('modules')->get('InputfieldRadios');
$f->attr('name', 'noclose');
$f->label = $this->_('Modal edit window behavior');
$f->addOption(0, $this->_('Automatically close on save (default)'));
$f->addOption(1, $this->_('Keep window open, close manually'));
$f->attr('value', (int) $this->noclose);
if(!$this->noclose) $f->collapsed = Inputfield::collapsedYes;
$inputfields->add($f);
return $inputfields;
}
}