* @license http://www.contenido.org/license/LIZENZ.txt * @link http://www.4fb.de * @link http://www.contenido.org * @since file available since contenido release <= 4.6 * * {@internal * created 2003-05-20 * modified 2008-06-30, Dominik Ziegler, add security fix * * $Id$: * }} * */ if(!defined('CON_FRAMEWORK')) { die('Illegal call'); } /** * Class TreeItem * Class to create tree-based items * * The treeitem class allows you to logically store * tree-based structures. * * Example: * * Let's have a tree with 3 nodes. It's important that * we always have a "root" key. * * $root = new TreeItem("root", 1); * $item1 = new TreeItem("node1",2); * $item2 = new TreeItem("node2",3); * $item3 = new TreeItem("node3",4); * * $root->addItem($item1); * $root->addItem($item2); * $root->addItem($item3); * * This represents the tree we described above. * * If you know the ID of the item you want to add * to, there's no need to have a specific item handy, * but rather you can use the "addItemToID" function. */ class TreeItem { /** * Sub Items for this tree item * @var array */ var $subitems; /** * Determinates if this tree item is collapsed * @var boolean */ var $collapsed; /** * ID for this item * @var string */ var $id; /** * Name for this item * @var string */ var $name; /** * Icon for the collapsed item * @var string */ var $collapsed_icon; /** * Icon for the expanded item * @var string */ var $expanded_icon; /** * Icon for last node in a branch * @var string */ var $lastnode_icon; /** * Contains the level of this item * @var integer */ var $level; /** * Contains custom entries * @var array */ var $custom; /** * Contains the parent of this item * @var array */ var $parent; /** * Constructor Function * Creates a new, independant tree item. * @param string $name The name of that item * @param string $id The unique ID of that item * @param boolean $collapsed Is this item collapsed by default */ function __construct($name ="", $id="", $collapsed = false) { $this->name = $name; $this->id = $id; $this->collapsed = $collapsed; $this->subitems = array(); $this->collapsed_icon = 'images/but_plus.gif'; $this->expanded_icon = 'images/but_minus.gif'; $this->lastnode_icon = 'images/but_lastnode.gif'; $this->parent = -1; } /** * addItem * Adds a new subitem to this item. * @param object $item the item to add */ function addItem(&$item) { $this->subitems[count($this->subitems)] = &$item; $item->parent = $this->id; } /** * addItemToID * Adds a new subitem to a specific item with an ID. * Traverses all subitems to find the correct item. * @param object $item the item to add * @param string $id the ID to add the item to */ function addItemToID($item, $id) { if ($this->id == $id) { $this->subitems[count($this->subitems)] = &$item; $item->parent = $this->id; } else { foreach (array_keys($this->subitems) as $key) { $this->subitems[$key]->addItemToID($item, $id); } } } /** * getItemByID * Retrieves a specific item by its ID. Note that this * function traverses all subitems to find the correct item. * @param string $id the ID to find * @return object The item, or false if nothing was found */ function &getItemByID($id) { if ($this->id == $id) { return ($this); } else { foreach (array_keys($this->subitems) as $key) { $retObj = &$this->subitems[$key]->getItemByID($id); if ($retObj->id == $id) { return ($retObj); } } } return false; } /** * removeItem * Removes an item with a specific ID. * @param string $id the ID to find */ function removeItem ($id) { foreach (array_keys($this->subitems) as $key) { if ($this->subitems[$key]->id == $id) { unset($this->subitems[$key]); } } } /** * isCustomAttributeSet * checks if a specific custom attribute is set * @param string $item the attribute name to find */ function isCustomAttributeSet ($item) { if (array_key_exists($item, $this->custom)) { return true; } else { foreach (array_keys($this->subitems) as $key) { if ($this->subitems[$key]->isCustomAttributeSet($item)) { return true; } } } return false; } /** * markExpanded * Marks an item as expanded. Traverses all subitems * to find the ID. Note that only the item with $id is * expanded, but not its childs. * @param string $id the ID to expand, or an array with all id's */ function markExpanded ($id) { if (is_array($id)) { if (in_array($this->id, $id)) { $this->collapsed = false; } foreach (array_keys($this->subitems) as $key) { $this->subitems[$key]->markExpanded($id); } } else { if ($this->id == $id) { $this->collapsed = false; return true; } else { foreach (array_keys($this->subitems) as $key) { $this->subitems[$key]->markExpanded($id); } } } } /** * expandAll * Expands all items, starting from the $start item. * @param string $start the ID to start expanding from */ function expandAll ($start = -2) { if ($start != $this->id) { $this->collapsed = false; } foreach (array_keys($this->subitems) as $key) { $this->subitems[$key]->expandAll(); } } /** * collapseAll * Collapses all items, starting from the $start item. * @param string $start the ID to start collapsing from */ function collapseAll ($start = -2) { if ($start != $this->id) { $this->collapsed = true; } foreach (array_keys($this->subitems) as $key) { $this->subitems[$key]->collapseAll(); } } /** * markCollapsed * Marks an item as collpased. Traverses all subitems * to find the ID. Note that only the item with $id is * collapsed, but not its childs. * @param string $id the ID to collapse */ function markCollapsed($id) { if ($this->id == $id) { $this->collapsed = true; } else { foreach (array_keys($this->subitems) as $key) { $this->subitems[$key]->markCollapsed($id); } } } /** * traverse * traverses the tree starting from this item, and returning * all objects as $objects. * @param object $objects all found objects * @param integer $level Level to start on */ function traverse (&$objects, $level = 0) { $objects[count($objects)] = &$this; $this->level = $level; if ($this->collapsed == false) { foreach (array_keys($this->subitems) as $key) { $this->subitems[$key]->traverse($objects, $level + 1); } } } /** * Starts iterating at root node and flattens the tree into an array */ function getFlatTree($item, &$flat_tree) { foreach ($item->subitems as $curItem) { $curItem->custom['vertline']=array(); $flat_tree[] = $curItem; $this->getFlatTree($curItem, $flat_tree); } } function hasCollapsedNode($item_id) { $parentNodeList=array(); $this->getTreeParentNodes($parentNodeList, $item_id); $collapsedList=array(); $this->getRealCollapsedList($collapsedList); if(sizeof(array_intersect($parentNodeList, $collapsedList)) > 0) { return TRUE; } else { return FALSE; } } /** * Returns a list of the id of all parent nodes of the given node **/ function getTreeParentNodes(&$parentNodes, $id) { $curItem = $this->getItemByID($id); $parentId = $curItem->parent; if($parentId && $parentId != -1) { $parentNodes[] = $parentId; $this->getTreeParentNodes($parentNodes, $parentId); } } /** * Returns a list of the id of all parent nodes of the given node * Not using the nodes of hierarchical tree, but flat tree !! **/ function getParentNodes(&$parentNodes, $stop_id) { $flat_tree = array(); $this->getFlatTree($this, $flat_tree); foreach($flat_tree as $key => $value) { if($value->id != $stop_id) { $parentNodes[] = $value->id; } else { break; } } } /** * getCollapsedList thinks if a node has no subnodes it is collapsed * I don't think so **/ function getRealCollapsedList(&$list) { $this->getCollapsedList($list); $cleared_list=array(); // remove all nodes that have no subnodes foreach($list as $key) { $item=$this->getItemByID($key); if(sizeof($item->subitems) > 0) { $cleared_list[]=$key; } } } /** * getCollapsedList * Returns all items (as ID array) which are collapsed. * @param array $list Contains the list with all collapsed items */ function getCollapsedList(&$list) { if ($this->collapsed == true) { $list[] = $this->id; } foreach (array_keys($this->subitems) as $key) { $this->subitems[$key]->getCollapsedList($list); } } /** * getExpandedList * Returns all items (as ID array) which are expanded. * @param array $list Contains the list with all expanded items */ function getExpandedList(&$list) { if ($this->collapsed == false && !in_array($this->id, $list)) { $list[] = $this->id; } foreach (array_keys($this->subitems) as $key) { $this->subitems[$key]->getExpandedList($list); } } /** * Set method for custom array * * @param string $key * @param string|int $content */ public function setCustom($key, $content) { $this->custom[$key] = $content; } /** * Set method for _collapsed_icon variable * * @param string $iconPath */ public function setCollapsedIcon($iconPath) { if (cSecurity::isString($iconPath)) { $this->collapsed_icon = $iconPath; } } /** * Set method for _expanded_icon variable * * @param string $iconPath */ public function setExpandedIcon($iconPath) { if (cSecurity::isString($iconPath)) { $this->expanded_icon = $iconPath; } } } ?>