<?php class TreeDropdownField extends FormField { protected $sourceObject, $keyField, $labelField, $filterFunc; protected $treeBaseID = 0; /** * Create a new tree dropdown field. * @param name The name of the field. * @param title The label of the field. * @param sourceObject The object-type to list in the tree. Must be a 'heirarchy' object. * @param keyField The column of that object-type to return as the field value. Defaults to ID * @param labelField The column to show as the human-readable value in the tree. Defaults to Title */ function __construct($name, $title, $sourceObject = "Group", $keyField = "ID", $labelField = "Title") { $this->sourceObject = $sourceObject; $this->keyField = $keyField; $this->labelField = $labelField; parent::__construct($name, $title); } function setFilterFunction($filterFunc) { $this->filterFunc = $filterFunc; } /** * Set the root node of the tree. Defaults to 0, ie, the whole tree */ function setTreeBaseID($treeBaseID) { $this->treeBaseID = $treeBaseID; } function Field() { Requirements::javascript("jsparty/tree/tree.js"); Requirements::css("jsparty/tree/tree.css"); Requirements::javascript("sapphire/javascript/TreeSelectorField.js"); if($this->value) { $record = DataObject::get_by_id($this->sourceObject, $this->value); $title = $record->Title; } else { $title = "(Choose)"; } $id = $this->id(); return <<<HTML <div id="TreeDropdownField_$id" class="TreeDropdownField single"><input id="$id" type="hidden" name="$this->name" value="$this->value" /><span class="items">$title</span><a href="#" title="open" class="editLink"> </a></div> HTML; } /** * Return the site tree */ function gettree() { if($this->treeBaseID) $obj = DataObject::get_by_id($this->sourceObject, $this->treeBaseID); else $obj = singleton($this->sourceObject); if($this->filterFunc) $obj->setMarkingFilterFunction($this->filterFunc); else if($this->sourceObject == 'Folder') $obj->setMarkingFilter('ClassName', 'Folder'); $obj->markPartialTree(); // If we've already got values selected, make sure that we've got them in our tree if($_REQUEST['forceValues']) { $forceValues = split(" *, *", trim($_REQUEST['forceValues'])); foreach($forceValues as $value) { $obj->markToExpose($this->getByKey($value)); } } $eval = '"<li id=\"selector-' . $this->name . '-$child->' . $this->keyField . '\" class=\"$child->class" . $child->markingClasses() . "\"><a>" . $child->' . $this->labelField . ' . "</a>"'; echo $obj->getChildrenAsUL("class=\"tree\"", $eval, null, true); } /** * Return a subtree via Ajax */ public function getsubtree() { if($this->keyField == "ID") $obj = DataObject::get_by_id($this->sourceObject, $_REQUEST['SubtreeRootID']); else $obj = DataObject::get_one($this->sourceObject, "$this->keyField = '$_REQUEST[SubtreeRootID]'"); if(!$obj) user_error("Can't find database record $this->sourceObject with $this->keyField = $_REQUEST[SubtreeRootID]", E_USER_ERROR); if($this->filterFunc) $obj->setMarkingFilterFunction($this->filterFunc); $obj->markPartialTree(); $eval = '"<li id=\"selector-' . $this->name . '-$child->' . $this->keyField . '\" class=\"$child->class" . $child->markingClasses() . "\"><a>" . $child->' . $this->labelField . ' . "</a>"'; $tree = $obj->getChildrenAsUL("", $eval, null, true); echo substr(trim($tree), 4,-5); } public function getByKey($key) { if(!is_numeric($key)) { return false; } if($this->keyField == 'ID') { return DataObject::get_by_id($this->sourceObject, $key); } else { return DataObject::get_one($this->sourceObject, "$this->keyField = '$key'"); } } /** * Return the stack of values to be traversed to find the given key in the database */ public function getstack() { if($this->keyField == "ID") $page = DataObject::get_by_id($this->sourceObject, $_REQUEST['SubtreeRootID']); else $page = $this->getByKey($_REQUEST['SubtreeRootID']); while($page->ParentID) { echo $ids[] = $page->ID; $page = $page->Parent; } $ids[] = $page->ID; echo implode(",", array_reverse($ids)); } function performReadonlyTransformation() { $fieldName = $this->labelField; $source = array( $this->value => $this->getByKey($this->value)->$fieldName ); $field = new LookupField($this->name, $this->title, $source); $field->setValue($this->value); $field->setForm($this->form); return $field; } } ?>