774 Zeilen
Kein EOL
15 KiB
PHP
774 Zeilen
Kein EOL
15 KiB
PHP
<?php
|
|
/**
|
|
* Project:
|
|
* Contenido Content Management System
|
|
*
|
|
* Description:
|
|
* Logical cTreeItem
|
|
*
|
|
* Requirements:
|
|
* @con_php_req 5.0
|
|
*
|
|
*
|
|
* @package Contenido Backend classes
|
|
* @version 1.12
|
|
* @author Bjoern Behrens
|
|
* @copyright four for business AG <www.4fb.de>
|
|
* @license http://www.contenido.org/license/LIZENZ.txt
|
|
* @link http://www.4fb.de
|
|
* @link http://www.contenido.org
|
|
*
|
|
* {@internal
|
|
* created 2006-10-05
|
|
*
|
|
* $Id: class.ctreeitem.php 2 2011-07-20 12:00:48Z oldperl $
|
|
* }}
|
|
*
|
|
*/
|
|
|
|
if(!defined('CON_FRAMEWORK')) {
|
|
die('Illegal call');
|
|
}
|
|
|
|
|
|
/**
|
|
* class cTreeItem
|
|
*
|
|
*/
|
|
class cTreeItem
|
|
{
|
|
/**
|
|
* 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;
|
|
|
|
/**
|
|
* Contains the level of this item
|
|
* @var integer
|
|
*/
|
|
var $_level;
|
|
|
|
/**
|
|
* Contains custom entries
|
|
* @var array
|
|
*/
|
|
var $_attributes;
|
|
|
|
/**
|
|
* Contains the parent of this item
|
|
* @var array
|
|
*/
|
|
var $_parent;
|
|
|
|
/**
|
|
* Contains the next item
|
|
* @var array
|
|
*/
|
|
var $_next;
|
|
|
|
/**
|
|
* Contains the previous item
|
|
* @var array
|
|
*/
|
|
var $_previous;
|
|
|
|
|
|
function cTreeItem ($id = "", $name = "", $collapsed = false)
|
|
{
|
|
$this->_id = $id;
|
|
$this->_name = $name;
|
|
$this->_collapsed = $collapsed;
|
|
$this->_subitems = array();
|
|
$this->_parent = false;
|
|
$this->_next = false;
|
|
$this->_previous = false;
|
|
$this->_attributes = array();
|
|
}
|
|
/**
|
|
* Imports a table from an array of arrays. Array format:
|
|
* array(
|
|
* array("id" => "Item ID", "name" => "Item name", "level" => 1, "collapsed" => true|false, "attributes" => array("attr_name" => "attr_value"))
|
|
* );
|
|
*
|
|
* The entries "collapsed" and "attributes" are optional!
|
|
*
|
|
* @param array flat_array See above
|
|
* @return void
|
|
* @access public
|
|
*/
|
|
function importTable( $flat_array )
|
|
{
|
|
$lastobj[0] = $this->_id;
|
|
$currentlevel = 1;
|
|
|
|
if (!is_array($flat_array))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
foreach ($flat_array as $item)
|
|
{
|
|
$mitem[$item["id"]] = new cTreeItem($item["id"], $item["name"]);
|
|
|
|
if ($item["level"] > $currentlevel)
|
|
{
|
|
$currentlevel++;
|
|
}
|
|
|
|
if ($item["level"] < $currentlevel)
|
|
{
|
|
$currentlevel= $item["level"];
|
|
}
|
|
|
|
if (is_array($item["attributes"]))
|
|
{
|
|
$mitem[$item["id"]]->setAttributes($item["attributes"]);
|
|
}
|
|
|
|
if (array_key_exists("collapsed", $item))
|
|
{
|
|
$mitem[$item["id"]]->setCollapsed($item["collapsed"]);
|
|
}
|
|
|
|
/* Set payload object */
|
|
if (array_key_exists("payload", $item))
|
|
{
|
|
$mitem[$item["id"]]->setPayloadObject($item["payload"]);
|
|
}
|
|
|
|
|
|
if (is_object($mitem[$lastobj[$currentlevel-1]]))
|
|
{
|
|
$mitem[$lastobj[$currentlevel-1]]->addItem($mitem[$item["id"]]);
|
|
} else {
|
|
$this->addItemToID($lastobj[$currentlevel-1], $mitem[$item["id"]]);
|
|
}
|
|
|
|
$lastobj[$currentlevel] = $item["id"];
|
|
|
|
}
|
|
|
|
} // end of member function importTree
|
|
|
|
function importStructuredArray ($array)
|
|
{
|
|
$i = array();
|
|
|
|
$lastid = 1;
|
|
$level = 1;
|
|
|
|
$this->_flattenArray($array, $i, $lastid, $level);
|
|
|
|
|
|
$this->importTable($i);
|
|
|
|
}
|
|
|
|
function _flattenArray ($sourcearray, &$destarray, &$lastid, &$level)
|
|
{
|
|
if ($lastid == false)
|
|
{
|
|
$lastid = 1;
|
|
}
|
|
|
|
if ($level == false)
|
|
{
|
|
$level = 1;
|
|
}
|
|
|
|
if (!is_array($sourcearray))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
foreach ($sourcearray as $id => $item)
|
|
{
|
|
$lastid++;
|
|
$destarray[$lastid]["id"] = $item["class"].".".$id;
|
|
|
|
/* Name should be fetched via the meta object */
|
|
$meta = $item["object"]->getMetaObject();
|
|
|
|
if (is_object($meta))
|
|
{
|
|
$destarray[$lastid]["name"] = $meta->getName();
|
|
}
|
|
|
|
$destarray[$lastid]["level"] = $level;
|
|
$destarray[$lastid]["payload"] = $item["object"];
|
|
|
|
if (count($item["items"]) > 0)
|
|
{
|
|
$level++;
|
|
$this->_flattenArray($item["items"], $destarray, $lastid, $level);
|
|
$level--;
|
|
}
|
|
}
|
|
}
|
|
/**
|
|
* Exports a tree as an array of arrays. Array format:
|
|
* array(
|
|
* array("id" => "Item ID", "name" => "Item name", "level" => 1, "attributes" => array("attr_name" => "attr_value"))
|
|
* );
|
|
*
|
|
* @return array
|
|
* @access public
|
|
*/
|
|
function exportTree( )
|
|
{
|
|
/* TODO: Function can't work... work in progress...
|
|
$myobj->traverse($objlist);
|
|
*/
|
|
} // end of member function exportTree
|
|
|
|
/**
|
|
* adds an item as a subitem to the current item
|
|
*
|
|
* @param cTreeItem item item object to add
|
|
* @return void
|
|
* @access public
|
|
*/
|
|
function addItem( &$item )
|
|
{
|
|
/* Update last item */
|
|
if ($lastitem = end($this->_subitems) !== false)
|
|
{
|
|
$this->_subitems[key($this->_subitems)]->_next = $item->_id;
|
|
}
|
|
|
|
$this->_subitems[count($this->_subitems)] = &$item;
|
|
$item->_parent = $this->_id;
|
|
$item->_previous = $lastitem->_id;
|
|
} // end of member function addItem
|
|
|
|
/**
|
|
* adds an item to a specific ID
|
|
*
|
|
* @param string id ID to add the item to
|
|
* @param cTreeItem item Item to add
|
|
* @return void
|
|
* @access public
|
|
*/
|
|
function addItemToID( $id, &$item )
|
|
{
|
|
if ($this->_id == $id)
|
|
{
|
|
|
|
/* Update last item */
|
|
if ($lastitem = end($this->_subitems) !== false)
|
|
{
|
|
$this->_subitems[key($this->_subitems)]->_next = $item->_id;
|
|
}
|
|
|
|
$this->_subitems[count($this->_subitems)] = &$item;
|
|
$item->_parent = $this->_id;
|
|
$item->_previous = $lastitem->_id;
|
|
return true;
|
|
|
|
} else {
|
|
foreach (array_keys($this->_subitems) as $key)
|
|
{
|
|
$result = $this->_subitems[$key]->addItemToID($id, $item);
|
|
|
|
if ($result == true)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
|
|
} // end of member function addItemToID
|
|
|
|
/**
|
|
* moves an item to another object
|
|
*
|
|
* @param cTreeItem targetItem Item to move the subitem to
|
|
* @param mixed itemToMove cTreeItem-Object or id of object to move
|
|
* @return void
|
|
* @access public
|
|
*/
|
|
function moveItem( $targetItem, $itemToMove )
|
|
{
|
|
|
|
} // end of member function moveItem
|
|
|
|
/**
|
|
* deletes a subitem
|
|
*
|
|
* @param mixed item object or ID to delete
|
|
* @return deleted object
|
|
* @access public
|
|
*/
|
|
function deleteItem( $id )
|
|
{
|
|
foreach (array_keys($this->_subitems) as $key)
|
|
{
|
|
if ($this->_subitems[$key]->_id == $id)
|
|
{
|
|
/* Fetch next item, reset to current item */
|
|
$nextitem = next($this->_subitems);
|
|
$nkey = key($this->_subitems);
|
|
prev($this->_subitems);
|
|
|
|
$previtem = &prev($this->_subitems);
|
|
$pkey = key($this->_subitems);
|
|
next($this->_subitems);
|
|
|
|
|
|
if ($nextitem !== false)
|
|
{
|
|
if ($previtem !== false)
|
|
{
|
|
$this->_subitems[$nkey]->_previous = $this->_subitems[$pkey]->_id;
|
|
}
|
|
}
|
|
|
|
if ($previtem !== false)
|
|
{
|
|
if ($nextitem !== false)
|
|
{
|
|
$this->_subitems[$pkey]->_next = $this->_subitems[$nkey]->_id;
|
|
}
|
|
}
|
|
|
|
$itemcopy = $this->_subitems[$key];
|
|
unset($this->_subitems[$key]);
|
|
|
|
return ($itemcopy);
|
|
} else {
|
|
$this->_subitems[$key]->deleteItem($id);
|
|
}
|
|
}
|
|
} // end of member function deleteItem
|
|
|
|
/**
|
|
* Retrieves a specific item by its ID. Note that this
|
|
* function traverses all subitems to find the correct item.
|
|
*
|
|
* @param string id ID to retrieve
|
|
* @return cTreeItem
|
|
* @access public
|
|
*/
|
|
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;
|
|
} // end of member function getItemByID
|
|
|
|
/**
|
|
* sets a custom attribute for this TreeItem
|
|
*
|
|
* @param string attributeName
|
|
* @param array attributeValue The value(s) of the attribute
|
|
* @return void
|
|
* @access public
|
|
*/
|
|
function setAttribute( $attributeName, $attributeValue )
|
|
{
|
|
$this->_attributes[$attributeName] = $attributeValue;
|
|
} // end of member function setAttribute
|
|
|
|
/**
|
|
* sets a bunch of attributes
|
|
*
|
|
* @param string attributeName
|
|
* @param array attributeValue The value(s) of the attribute
|
|
* @return void
|
|
* @access public
|
|
*/
|
|
function setAttributes( $aAttributeArray )
|
|
{
|
|
$this->_attributes = array_merge($aAttributeArray, $this->_attributes);
|
|
} // end of member function setAttribute
|
|
|
|
/**
|
|
* returns an attribute
|
|
*
|
|
* @param string attributeName
|
|
* @return mixed
|
|
* @access public
|
|
*/
|
|
function getAttribute( $attributeName )
|
|
{
|
|
if (array_key_exists($attributeName, $this->_attributes))
|
|
{
|
|
return ($this->_attributes[$attributeName]);
|
|
} else {
|
|
return false;
|
|
}
|
|
} // end of member function getAttribute
|
|
|
|
/**
|
|
* deletes an attribute
|
|
*
|
|
* @param string attributeName
|
|
* @return void
|
|
* @access public
|
|
*/
|
|
function deleteAttribute( $attributeName )
|
|
{
|
|
if (array_key_exists($attributeName, $this->_attributes))
|
|
{
|
|
unset($this->_attributes[$attributeName]);
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
} // end of member function deleteAttribute
|
|
|
|
function hasAttribute ($attributeName, $bRecursive = false)
|
|
{
|
|
if (array_key_exists($attributeName, $this->_attributes))
|
|
{
|
|
return true;
|
|
} else {
|
|
if ($bRecursive == true)
|
|
{
|
|
if (count($this->_subitems) > 0)
|
|
{
|
|
foreach ($this->_subitems as $oSubitem)
|
|
{
|
|
$bFound = $oSubitem->hasAttribute($attributeName, true);
|
|
|
|
if ($bFound == true)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
/**
|
|
*
|
|
*
|
|
* @param mixed expand ID of item to expand or array of item ID's to expand
|
|
* @return void
|
|
* @access public
|
|
*/
|
|
function setExpanded( $id )
|
|
{
|
|
if (is_array($id))
|
|
{
|
|
if (in_array($this->_id, $id, true))
|
|
{
|
|
$this->_collapsed = false;
|
|
}
|
|
|
|
foreach (array_keys($this->_subitems) as $key)
|
|
{
|
|
$this->_subitems[$key]->setExpanded($id);
|
|
}
|
|
} else {
|
|
if ($this->_id === $id)
|
|
{
|
|
$this->_collapsed = false;
|
|
return true;
|
|
} else {
|
|
foreach (array_keys($this->_subitems) as $key)
|
|
{
|
|
$this->_subitems[$key]->setExpanded($id);
|
|
}
|
|
}
|
|
}
|
|
} // end of member function setExpanded
|
|
|
|
/**
|
|
*
|
|
*
|
|
* @param mixed collapse ID to collapse or an array with items to collapse
|
|
* @return void
|
|
* @access public
|
|
*/
|
|
function setCollapsed( $id )
|
|
{
|
|
if (is_array($id))
|
|
{
|
|
if (in_array($this->_id, $id, true))
|
|
{
|
|
$this->_collapsed = true;
|
|
}
|
|
|
|
foreach (array_keys($this->_subitems) as $key)
|
|
{
|
|
$this->_subitems[$key]->setCollapsed($id);
|
|
}
|
|
} else {
|
|
if ($this->_id === $id)
|
|
{
|
|
$this->_collapsed = true;
|
|
return true;
|
|
} else {
|
|
foreach (array_keys($this->_subitems) as $key)
|
|
{
|
|
$this->_subitems[$key]->setCollapsed($id);
|
|
}
|
|
}
|
|
}
|
|
} // end of member function setCollapsed
|
|
|
|
/**
|
|
*
|
|
*
|
|
* @param int leveloffset Level offset. Ignores all expand operations below the offset.
|
|
* @return void
|
|
* @access public
|
|
*/
|
|
function expandBelowLevel ($leveloffset)
|
|
{
|
|
if ($leveloffset > 0)
|
|
{
|
|
$leveloffset--;
|
|
} else {
|
|
$this->_collapsed = false;
|
|
}
|
|
|
|
foreach (array_keys($this->_subitems) as $key)
|
|
{
|
|
$this->_subitems[$key]->expandBelowLevel($leveloffset);
|
|
}
|
|
} // end of member function expandBelowLevel
|
|
|
|
/**
|
|
*
|
|
*
|
|
* @param int leveloffset Level offset. Ignores all expand operations below the offset.
|
|
* @return void
|
|
* @access public
|
|
*/
|
|
function collapseBelowLevel ($leveloffset)
|
|
{
|
|
if ($leveloffset > 0)
|
|
{
|
|
$leveloffset--;
|
|
} else {
|
|
$this->_collapsed = true;
|
|
}
|
|
|
|
foreach (array_keys($this->_subitems) as $key)
|
|
{
|
|
$this->_subitems[$key]->collapseBelowLevel($leveloffset);
|
|
}
|
|
} // end of member function expandBelowLevel
|
|
|
|
|
|
/**
|
|
*
|
|
*
|
|
* @param int leveloffset Level offset. Ignores all expand operations below the offset.
|
|
* @return void
|
|
* @access public
|
|
*/
|
|
function expandBelowID ($id, $found = false)
|
|
{
|
|
if ($found === true)
|
|
{
|
|
$this->_collapsed = false;
|
|
}
|
|
|
|
if ($this->_id == $id)
|
|
{
|
|
$found = true;
|
|
$this->_collapsed = false;
|
|
}
|
|
|
|
foreach (array_keys($this->_subitems) as $key)
|
|
{
|
|
$this->_subitems[$key]->expandBelowID($id, $found);
|
|
}
|
|
} // end of member function expandBelowLevel
|
|
|
|
/**
|
|
*
|
|
*
|
|
* @param int leveloffset Level offset. Ignores all expand operations below the offset.
|
|
* @return void
|
|
* @access public
|
|
*/
|
|
function collapseBelowID ($id, $found = false)
|
|
{
|
|
if ($found === true)
|
|
{
|
|
$this->_collapsed = true;
|
|
}
|
|
|
|
if ($this->_id == $id)
|
|
{
|
|
$found = true;
|
|
$this->_collapsed = true;
|
|
}
|
|
|
|
foreach (array_keys($this->_subitems) as $key)
|
|
{
|
|
$this->_subitems[$key]->collapseBelowID($id, $found);
|
|
}
|
|
} // end of member function expandBelowLevel
|
|
|
|
/**
|
|
* getCollapsedList
|
|
* Returns all items (as ID array) which are collapsed.
|
|
* @param array $list Contains the list with all collapsed items
|
|
*/
|
|
function getCollapsedList (&$list)
|
|
{
|
|
if (!is_array($list))
|
|
{
|
|
$list = array();
|
|
}
|
|
|
|
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 (!is_array($list))
|
|
{
|
|
$list = array();
|
|
}
|
|
|
|
if ($this->_collapsed == false && !in_array($this->_id, $list))
|
|
{
|
|
$list[] = $this->_id;
|
|
}
|
|
|
|
foreach (array_keys($this->_subitems) as $key)
|
|
{
|
|
$this->_subitems[$key]->getExpandedList($list);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* sets a payload object for later reference
|
|
*
|
|
* @param object payload The object to payload
|
|
* @return void
|
|
* @access public
|
|
*/
|
|
function setPayloadObject ($payload)
|
|
{
|
|
$this->payload = $payload;
|
|
} // end of member function setPayloadObject
|
|
|
|
/**
|
|
* unsets a payload object
|
|
*
|
|
* @return object
|
|
* @access public
|
|
*/
|
|
function unsetPayloadObject( )
|
|
{
|
|
|
|
} // end of member function unsetPayloadObject
|
|
|
|
|
|
/**
|
|
* traverse
|
|
* traverses the tree starting from this item, and returning
|
|
* all objects as $objects in a nested array.
|
|
* @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);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* flatTraverse
|
|
* traverses the tree starting from this item, and returning
|
|
* all objects as $objects in a flat array.
|
|
* @param object $objects all found objects
|
|
* @param integer $level Level to start on
|
|
*/
|
|
function flatTraverse ($level = 0)
|
|
{
|
|
$objects[] = &$this;
|
|
$this->_level = $level;
|
|
|
|
if ($this->_collapsed == false)
|
|
{
|
|
foreach (array_keys($this->_subitems) as $key)
|
|
{
|
|
$objects = array_merge($objects, $this->_subitems[$key]->flatTraverse($level + 1));
|
|
}
|
|
}
|
|
|
|
return $objects;
|
|
|
|
}
|
|
|
|
/**
|
|
* setName
|
|
* sets the Name for this item.
|
|
* @param string $name New name for this item
|
|
* @return none
|
|
*/
|
|
function setName ($name)
|
|
{
|
|
$this->_name = $name;
|
|
}
|
|
|
|
|
|
} // end of cTreeItem
|
|
?>
|