Source of file HierarchicalCheckboxSetField.php
Size: 8,591 Bytes - Last Modified: 2021-12-24T06:19:09+00:00
/var/www/docs.ssmods.com/process/src/code/HierarchicalCheckboxSetField.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338 | <?php /** * Hierarchical Checkbox Set Field */ class HierarchicalCheckboxSetField extends CheckboxSetField { protected $childsource; protected $childfilter = null; protected $childsort = null; protected $disableparentswithchildren = false; function __construct($name, $title = "", $source = array(), $childsource = null , $value = "", $form = null, $childfilter = null) { parent::__construct($name, $title, $source, $value, $form); $this->childsource = $childsource; $this->childfilter = $childfilter; } /** * @todo Explain different source data that can be used with this field, * e.g. SQLMap, DataObjectSet or an array. */ public function Field($properties = array()) { Requirements::css(FRAMEWORK_DIR . '/css/CheckboxSetField.css'); $source = $this->source; $values = $this->value; // Get values from the join, if available if(is_object($this->form)) { $record = $this->form->getRecord(); if(!$values && $record && $record->hasMethod($this->name)) { $funcName = $this->name; $join = $record->$funcName(); if($join) { foreach($join as $joinItem) { $values[] = $joinItem->ID; } } } } $items = array(); // Source is not an array if(!is_array($source) && !is_a($source, 'SQLMap')) { if(is_array($values)) { $items = $values; } else { // Source and values are DataObject sets. if($values && is_a($values, 'SS_List')) { foreach($values as $object) { if(is_a($object, 'DataObject')) { $items[] = $object->ID; } } } elseif($values && is_string($values)) { $items = explode(',', $values); $items = str_replace('{comma}', ',', $items); } } } else { // Sometimes we pass a singluar default value thats ! an array && !SS_List if($values instanceof SS_List || is_array($values)) { $items = $values; } else { if($values === null) { $items = array(); } else { $items = explode(',', $values); $items = str_replace('{comma}', ',', $items); } } } $odd = 0; $options = array(); $source = $this->getSourceItems(); if($source) { foreach($source as $value => $item) { if($item instanceof DataObject) { $value = $item->ID; $title = $item->Title; } else { $title = $item; } $itemID = $this->getItemHTMLID($value); $odd = ($odd + 1) % 2; $extraClass = $odd ? 'odd' : 'even'; $extraClass .= ' val' . preg_replace('/[^a-zA-Z0-9\-\_]/', '_', $value); $data = array( 'ID' => $itemID, 'Class' => $extraClass, 'Name' => "{$this->name}[{$value}]", 'Value' => $value, 'Title' => $title, 'isChecked' => in_array($value, $items) || in_array($value, $this->defaultItems), 'isDisabled' => $this->disabled || in_array($value, $this->disabledItems) ); if($children = $this->getChildOptions($item)){ $data['HasChildren'] = true; $data['ChildOptions'] = $children; } $options[] = new ArrayData($data); } } $properties = array_merge($properties, array('Options' => new ArrayList($options))); return $this->customise($properties)->renderWith($this->getTemplates()); } function getChildOptions($item){ if(!is_a($item, 'DataObject') || !$this->childsource) { return false; } $output = ''; $children = $item->{$this->childsource}(); if($this->childfilter) { $children = $children->where($this->childfilter); } if(!$children->exists()) { return false; } if($this->childsort){ $children = $children->sort($this->childsort); } $values = $this->getValueIDs(); $parentid = $item->ID; $options = array(); foreach($children as $item) { $title = $item->Title; $value = $item->ID; $data = array( 'ID' => $this->getItemHTMLID($item->ID), 'Class' => '',//$extraClass, 'Name' => "{$this->name}[{$parentid}][{$value}]", 'Value' => $item->ID, 'Title' => $title, 'isChecked' => in_array($item->ID, $values) || in_array($item->ID, $this->defaultItems), 'isDisabled' => $this->disabled || in_array($value, $this->disabledItems) ); $options[] = new ArrayData($data); } return new ArrayList($options); } protected function getSourceItems() { $source = $this->source; if(is_array($source)) { unset($source['']); } if($source == null){ $source = array(); } return $source; } protected function getValueIDs() { $values = $this->value; //get value from record relation, if possible if($values && is_a($values, 'SS_List')) { $ids = array(); foreach($values as $object) { if(is_a($object, 'DataObject')) { $ids[] = $object->ID; } } return $ids; } if(is_array($values)){ return $values; } if(is_string($values)){ return explode(",", $values); } return array($values); } protected function getItemHTMLID($id) { return $this->ID() . '_' . preg_replace('/[^a-zA-Z0-9]/', '', $id); } function disableParentsWithChildren($setting = true){ $this->disableparentswithchildren = $setting; return $this; } function setChildFilter($filter) { $this->childfilter = $filter; return $this; } function setChildSort($sort) { $this->childsort = $sort; return $this; } /** * Save the current value of this CheckboxSetField into a DataObject. * If the field it is saving to is a has_many or many_many relationship, * it is saved by setByIDList(), otherwise it creates a comma separated * list for a standard DB text/varchar field. * * @param DataObject $record The record to save into */ function saveInto(DataObjectInterface $record) { $fieldname = $this->name ; //check if dataobject has a field name the same as this->name if($fieldname && $record && ($record->has_many($fieldname) || $record->many_many($fieldname))) { $idList = array(); if($this->value) foreach($this->value as $id => $bool) { if($bool){ $idList[] = $id; } //TODO: include support for setting $record->has_many($this->childsorce) and many_many($this->childsource) values } $record->$fieldname()->setByIDList($idList); } elseif($fieldname && $record) { if($this->value) { $record->$fieldname = $this->dataValue(); } else { $record->$fieldname = ''; } } } /** * Return the HierarchicalCheckboxSetField value as an string * selected item keys, with sub arrays in square brackets. * * TODO: would this be better as JSON, or some specific format? * current format: 1,2,3[2,3,4,6],3,5[3,23],4 * JSON: 1,2,3,4,5:{3,5,6} * * @return string */ function dataValue() { if($this->value && is_array($this->value)) { return serialize($this->value); } return ''; } /** * Helper function for building values string. */ protected function subDataValues(array $items){ $filtered = array(); foreach($items as $key => $item) { if($item && is_array($item)){ $filtered[] = $key."[".$this->subDataValues($item)."]"; }elseif($item) { $filtered[] = str_replace(",", "{comma}", $item); } } return implode(',', $filtered); } /** * Transforms the source data for this CheckboxSetField * into a comma separated list of values. * * @return ReadonlyField */ function performReadonlyTransformation() { $values = ''; $data = array(); $items = $this->value; if($this->source) { foreach($this->source as $source) { if(is_object($source)) { $sourceTitles[$source->ID] = $source->Title; } } } if($items) { // Items is a DO Set if(is_a($items, 'DataObjectSet')) { foreach($items as $item) { $data[] = $item->Title; } if($data){ $values = implode(', ', $data); } // Items is an array or single piece of string (including comma seperated string) } else { if(!is_array($items)) { $items = split(' *, *', trim($items)); } foreach($items as $item) { if(is_array($item) && isset($item['Title'])) { $data[] = $item['Title']; }elseif(is_array($item)){ //TODO: do something with sub-array } elseif(is_array($this->source) && !empty($this->source[$item])) { $data[] = $this->source[$item]; } elseif(is_a($this->source, 'ComponentSet')) { $data[] = $sourceTitles[$item]; } else { $data[] = $item; } } $values = implode(', ', $data); } } $title = ($this->title) ? $this->title : ''; $field = new ReadonlyField($this->name, $title, $values); $field->setForm($this->form); return $field; } function ExtraOptions() { return FormField::ExtraOptions(); } } |