diff --git a/src/Forms/TreeDropdownField.php b/src/Forms/TreeDropdownField.php index c5c3945c0..99a519dee 100644 --- a/src/Forms/TreeDropdownField.php +++ b/src/Forms/TreeDropdownField.php @@ -387,7 +387,6 @@ class TreeDropdownField extends FormField $isSubTree = false; $this->search = $request->requestVar('search'); - $flatlist = $request->requestVar('flatList'); $id = (is_numeric($request->latestParam('ID'))) ? (int)$request->latestParam('ID') : (int)$request->requestVar('ID'); @@ -450,10 +449,11 @@ class TreeDropdownField extends FormField // Set title formatter $customised = function (DataObject $child) use ($isSubTree) { + $title = ($child->hasMethod('getMenuTitle')) ? $child->geMenuTitle() : $child->getTitle(); return [ 'name' => $this->getName(), 'id' => $child->obj($this->keyField), - 'title' => $child->getTitle(), + 'title' => $title, 'treetitle' => $child->obj($this->labelField), 'disabled' => $this->nodeIsDisabled($child), 'isSubTree' => $isSubTree @@ -466,7 +466,7 @@ class TreeDropdownField extends FormField $json = $markingSet ->getChildrenAsArray($customised); - if ($flatlist) { + if ($request->requestVar('flatList')) { // format and filter $json here $json['children'] = $this->flattenChildrenArray($json['children']); } @@ -590,7 +590,7 @@ class TreeDropdownField extends FormField $contextString = implode('/', $parentTitles); $child['contextString'] = ($contextString !== '') ? $contextString .'/' : ''; - $child['children'] = []; + unset($child['children']); if (!$this->search || in_array($child['id'], $this->realSearchIds)) { $output[] = $child; @@ -719,16 +719,15 @@ class TreeDropdownField extends FormField public function getSchemaStateDefaults() { $data = parent::getSchemaStateDefaults(); - // Check label for field $record = $this->Value() ? $this->objectForKey($this->Value()) : null; - $selectedlabel = null; // Ensure cache is keyed by last modified date of the underlying list $data['data']['cacheKey'] = DataList::create($this->sourceObject)->max('LastEdited'); if ($record) { + $title = ($record->hasMethod('getMenuTitle')) ? $record->geMenuTitle() : $record->getTitle(); $data['data']['valueObject'] = [ 'id' => $record->getField($this->keyField), - 'title' => $record->getTitle(), + 'title' => $title, 'treetitle' => $record->obj($this->labelField)->getSchemaValue(), ]; } @@ -744,6 +743,7 @@ class TreeDropdownField extends FormField 'showSearch' => $this->showSearch, 'emptyString' => $this->getEmptyString(), 'hasEmptyDefault' => $this->getHasEmptyDefault(), + 'multiple' => false, ]); return $data; diff --git a/src/Forms/TreeMultiselectField.php b/src/Forms/TreeMultiselectField.php index 85380bae8..8e4bb1276 100644 --- a/src/Forms/TreeMultiselectField.php +++ b/src/Forms/TreeMultiselectField.php @@ -5,9 +5,11 @@ namespace SilverStripe\Forms; use SilverStripe\Core\Convert; use SilverStripe\Control\Controller; use SilverStripe\ORM\ArrayList; +use SilverStripe\ORM\DataList; use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObjectInterface; use SilverStripe\ORM\FieldType\DBHTMLText; +use SilverStripe\Security\Group; use SilverStripe\View\ViewableData; use stdClass; @@ -54,52 +56,105 @@ use stdClass; */ class TreeMultiselectField extends TreeDropdownField { - public function __construct($name, $title = null, $sourceObject = "SilverStripe\\Security\\Group", $keyField = "ID", $labelField = "Title") - { + public function __construct( + $name, + $title = null, + $sourceObject = Group::class, + $keyField = "ID", + $labelField = "Title" + ) { parent::__construct($name, $title, $sourceObject, $keyField, $labelField); $this->removeExtraClass('single'); $this->addExtraClass('multiple'); $this->value = 'unchanged'; } + + public function getSchemaDataDefaults() + { + $data = parent::getSchemaDataDefaults(); + + $data['data'] = array_merge($data['data'], [ + 'hasEmptyDefault' => false, + 'multiple' => true, + ]); + return $data; + } + + public function getSchemaStateDefaults() + { + $data = parent::getSchemaStateDefaults(); + unset($data['data']['valueObject']); + + $items = $this->getItems(); + $values = []; + foreach ($items as $item) { + if ($item instanceof DataObject) { + $values[] = [ + 'id' => $item->getField($this->keyField), + 'title' => $item->getTitle(), + 'parentid' => $item->ParentID, + 'treetitle' => $item->obj($this->labelField)->getSchemaValue(), + ]; + } else { + $values[] = $item; + } + } + $data['data']['valueObjects'] = $values; + + // cannot rely on $this->value as this could be a many-many relationship + $value = array_column($values, 'id'); + $data['value'] = ($value) ? $value : 'unchanged'; + + return $data; + } /** * Return this field's linked items + * @return ArrayList|DataList $items */ public function getItems() { + $items = new ArrayList(); + // If the value has been set, use that - if ($this->value != 'unchanged' && is_array($this->sourceObject)) { - $items = array(); - $values = is_array($this->value) ? $this->value : preg_split('/ *, */', trim($this->value)); - foreach ($values as $value) { - $item = new stdClass; - $item->ID = $value; - $item->Title = $this->sourceObject[$value]; - $items[] = $item; - } - return $items; - - // Otherwise, look data up from the linked relation - } if ($this->value != 'unchanged' && is_string($this->value)) { - $items = new ArrayList(); - $ids = explode(',', $this->value); - foreach ($ids as $id) { - if (!is_numeric($id)) { - continue; - } - $item = DataObject::get_by_id($this->sourceObject, $id); - if ($item) { + if ($this->value != 'unchanged') { + if (is_array($this->sourceObject)) { + $values = is_array($this->value) ? $this->value : preg_split('/ *, */', trim($this->value)); + + foreach ($values as $value) { + $item = new stdClass; + $item->ID = $value; + $item->Title = $this->sourceObject[$value]; $items->push($item); } + return $items; } - return $items; - } elseif ($this->form) { + + // Otherwise, look data up from the linked relation + if (is_string($this->value)) { + $ids = explode(',', $this->value); + foreach ($ids as $id) { + if (!is_numeric($id)) { + continue; + } + $item = DataObject::get_by_id($this->sourceObject, $id); + if ($item) { + $items->push($item); + } + } + return $items; + } + } + + if ($this->form) { $fieldName = $this->name; $record = $this->form->getRecord(); if (is_object($record) && $record->hasMethod($fieldName)) { return $record->$fieldName(); } } + + return $items; } /** @@ -161,7 +216,7 @@ class TreeMultiselectField extends TreeDropdownField { // Detect whether this field has actually been updated if ($this->value !== 'unchanged') { - $items = array(); + $items = []; $fieldName = $this->name; $saveDest = $record->$fieldName(); @@ -173,8 +228,10 @@ class TreeMultiselectField extends TreeDropdownField E_USER_ERROR ); } - - if ($this->value) { + + if (is_array($this->value)) { + $items = $this->value; + } elseif ($this->value) { $items = preg_split("/ *, */", trim($this->value)); }