| <?php |
| /** |
| * File containing the ezcTreeNode class. |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0 |
| * @version //autogentag// |
| * @filesource |
| * @package Tree |
| */ |
| |
| /** |
| * ezcTreeNode represents a node in a tree. |
| * |
| * The methods that operate on nodes (fetchChildren, fetchPath, ..., |
| * isSiblingOf) are all marshalled to calls on the tree (that is stored in the |
| * $tree private variable) itself. |
| * |
| * Example: |
| * <code> |
| * <?php |
| * // Creates a new node with ID 'O' and as data 'Oxygen' |
| * $node = new ezcTreeNode( $this->tree, 'O', 'Oxygen' ); |
| * |
| * // Adds a node as child element to another already create node in a tree |
| * $parentNode->addChild( $node ); |
| * ?> |
| * </code> |
| * |
| * To use your own implementation of tree nodes, you can override the class |
| * that is used by the tree by setting the nodeClassName property of the |
| * ezcTree class. The class must inherit from this class though. |
| * |
| * @property-read string $id The ID that uniquely identifies a node |
| * @property-read ezcTree $tree The tree object that this node belongs to |
| * @property mixed $data The data belonging to a node |
| * @property bool $dataFetched Whether the data for this node has been |
| * fetched. Should *only* be modified by |
| * data store implementations. |
| * @property bool $dataStored Whether the data for this node has been |
| * stored. Should *only* be modified by |
| * data store implementations. |
| * |
| * @package Tree |
| * @version //autogentag// |
| * @mainclass |
| */ |
| class ezcTreeNode implements ezcTreeVisitable |
| { |
| /** |
| * Holds the properties of this class. |
| * |
| * @var array(string=>mixed) |
| */ |
| private $properties = array(); |
| |
| /** |
| * Constructs a new ezcTreeNode object with ID $nodeId on tree $tree. |
| * |
| * If a third argument is specified it is used as data for the new node. |
| * |
| * @param ezcTree $tree |
| * @param string $nodeId |
| * @param mixed $data |
| */ |
| public function __construct( ezcTree $tree, $nodeId ) |
| { |
| $this->properties['id'] = (string) $nodeId; |
| $this->properties['tree'] = $tree; |
| |
| if ( func_num_args() === 2 ) |
| { |
| $this->properties['data'] = null; |
| $this->properties['dataFetched'] = false; |
| $this->properties['dataStored'] = true; |
| } |
| else |
| { |
| $this->properties['data'] = func_get_arg( 2 ); |
| $this->properties['dataFetched'] = true; |
| $this->properties['dataStored'] = false; |
| } |
| } |
| |
| /** |
| * Returns the value of the property $name. |
| * |
| * @throws ezcBasePropertyNotFoundException if the property does not exist. |
| * @param string $name |
| * @return mixed |
| * @ignore |
| */ |
| public function __get( $name ) |
| { |
| switch ( $name ) |
| { |
| case 'data': |
| if ( $this->properties['dataFetched'] === false ) |
| { |
| // fetch the data on the fly |
| $this->tree->store->fetchDataForNode( $this ); |
| } |
| // break intentionally missing |
| case 'id': |
| case 'dataFetched': |
| case 'dataStored': |
| case 'tree': |
| return $this->properties[$name]; |
| |
| } |
| throw new ezcBasePropertyNotFoundException( $name ); |
| } |
| |
| /** |
| * Sets the property $name to $value. |
| * |
| * @throws ezcBasePropertyNotFoundException if the property does not exist. |
| * @throws ezcBasePropertyPermissionException if a read-only property is |
| * tried to be modified. |
| * @throws ezcBaseValueException if trying to assign a wrong value to |
| * the property |
| * @param string $name |
| * @param mixed $value |
| * @ignore |
| */ |
| public function __set( $name, $value ) |
| { |
| switch ( $name ) |
| { |
| case 'id': |
| case 'tree': |
| throw new ezcBasePropertyPermissionException( $name, ezcBasePropertyPermissionException::READ ); |
| |
| case 'data': |
| if ( !$this->properties['dataFetched'] ) |
| { |
| $this->tree->store->fetchDataForNode( $this ); |
| $this->properties['dataFetched'] = true; |
| } |
| |
| $this->properties[$name] = $value; |
| $this->properties['dataStored'] = false; |
| $this->tree->store->storeDataForNode( $this ); |
| return; |
| |
| case 'dataFetched': |
| case 'dataStored': |
| if ( !is_bool( $value ) ) |
| { |
| throw new ezcBaseValueException( $name, $value, 'boolean' ); |
| } |
| $this->properties[$name] = $value; |
| break; |
| |
| default: |
| throw new ezcBasePropertyNotFoundException( $name ); |
| } |
| } |
| |
| /** |
| * Returns true if the property $name is set, otherwise false. |
| * |
| * @param string $name |
| * @return bool |
| * @ignore |
| */ |
| public function __isset( $name ) |
| { |
| switch ( $name ) |
| { |
| case 'id': |
| case 'tree': |
| case 'data': |
| case 'dataFetched': |
| case 'dataStored': |
| return isset( $this->properties[$name] ); |
| |
| default: |
| return false; |
| } |
| } |
| |
| /** |
| * Inject data. |
| * |
| * Used to set the data from a data loader. Should not be used for |
| * interfacing with the tree node, since the node will not be flagged as |
| * modified by this method. |
| * |
| * @access private |
| * @param string $data |
| * @return void |
| */ |
| public function injectData( $data ) |
| { |
| $this->properties['data'] = $data; |
| } |
| |
| /** |
| * Implements the accept method for visiting. |
| * |
| * @param ezcTreeVisitor $visitor |
| */ |
| public function accept( ezcTreeVisitor $visitor ) |
| { |
| $visitor->visit( $this ); |
| foreach ( $this->fetchChildren()->nodes as $childNode ) |
| { |
| $childNode->accept( $visitor ); |
| } |
| } |
| |
| /** |
| * Adds the node $node as child of the current node to the tree. |
| * |
| * @param ezcTreeNode $node |
| */ |
| public function addChild( ezcTreeNode $node ) |
| { |
| $this->tree->addChild( $this->id, $node ); |
| } |
| |
| /** |
| * Returns all the children of this node. |
| * |
| * @return ezcTreeNodeList |
| */ |
| public function fetchChildren() |
| { |
| return $this->tree->fetchChildren( $this->id ); |
| } |
| |
| /** |
| * Returns all the nodes in the path from the root node to this node. |
| * |
| * @return ezcTreeNodeList |
| */ |
| public function fetchPath() |
| { |
| return $this->tree->fetchPath( $this->id ); |
| } |
| |
| /** |
| * Returns the parent node of this node. |
| * |
| * @return ezcTreeNode |
| */ |
| public function fetchParent() |
| { |
| return $this->tree->fetchParent( $this->id ); |
| } |
| |
| /** |
| * Returns this node and all its children, sorted according to the |
| * {@link http://en.wikipedia.org/wiki/Depth-first_search Depth-first sorting} |
| * algorithm. |
| * |
| * @return ezcTreeNodeList |
| */ |
| public function fetchSubtreeDepthFirst() |
| { |
| return $this->tree->fetchSubtreeDepthFirst( $this->id ); |
| } |
| |
| /** |
| * Alias for fetchSubtreeDepthFirst(). |
| * |
| * @see fetchSubtreeDepthFirst |
| * @return ezcTreeNodeList |
| */ |
| public function fetchSubtree() |
| { |
| return $this->fetchSubtreeDepthFirst(); |
| } |
| |
| /** |
| * Returns this node and all its children, sorted accoring to the |
| * {@link http://en.wikipedia.org/wiki/Breadth-first_search Breadth-first sorting} |
| * algorithm. |
| * |
| * @return ezcTreeNodeList |
| */ |
| public function fetchSubtreeBreadthFirst() |
| { |
| return $this->tree->fetchSubtreeBreadthFirst( $this->id ); |
| } |
| |
| /** |
| * Returns the number of direct children of this node. |
| * |
| * @return int |
| */ |
| public function getChildCount() |
| { |
| return $this->tree->getChildCount( $this->id ); |
| } |
| |
| /** |
| * Returns the number of children of this node, recursively iterating over |
| * the children. |
| * |
| * @return int |
| */ |
| public function getChildCountRecursive() |
| { |
| return $this->tree->getChildCountRecursive( $this->id ); |
| } |
| |
| /** |
| * Returns the distance from the root node to this node. |
| * |
| * @return int |
| */ |
| public function getPathLength() |
| { |
| return $this->tree->getPathlength( $this->id ); |
| } |
| |
| /** |
| * Returns whether this node has children. |
| * |
| * @return bool |
| */ |
| public function hasChildNodes() |
| { |
| return $this->tree->hasChildNodes( $this->id ); |
| } |
| |
| /** |
| * Returns whether this node is a direct child of the $parentNode node. |
| * |
| * @param ezcTreeNode $parentNode |
| * |
| * @return bool |
| */ |
| public function isChildOf( ezcTreeNode $parentNode ) |
| { |
| return $this->tree->isChildOf( $this->id, $parentNode->id ); |
| } |
| |
| /** |
| * Returns whether this node is a direct or indirect child of the |
| * $parentNode node. |
| * |
| * @param ezcTreeNode $parentNode |
| * |
| * @return bool |
| */ |
| public function isDescendantOf( ezcTreeNode $parentNode ) |
| { |
| return $this->tree->isDescendantOf( $this->id, $parentNode->id ); |
| } |
| |
| /** |
| * Returns whether this node, and the $child2Node node are are siblings |
| * (ie, they share the same parent). |
| * |
| * @param ezcTreeNode $child2Node |
| * |
| * @return bool |
| */ |
| public function isSiblingOf( ezcTreeNode $child2Node ) |
| { |
| return $this->tree->isSiblingOf( $this->id, $child2Node->id ); |
| } |
| |
| /** |
| * Returns the text representation of a node (its ID). |
| * |
| * @return string |
| * @ignore |
| */ |
| public function __toString() |
| { |
| return $this->id; |
| } |
| } |
| ?> |