--- nfo/php/libs/net.php.pear/Tree/Memory.php 2003/05/13 09:38:58 1.2 +++ nfo/php/libs/net.php.pear/Tree/Memory.php 2004/07/07 02:49:19 1.3 @@ -16,11 +16,10 @@ // | Authors: Wolfram Kriesing | // +----------------------------------------------------------------------+ // -// Id: Memory.php,v 1.17 2003/01/18 15:38:04 cain Exp -// $Id: Memory.php,v 1.2 2003/05/13 09:38:58 joko Exp $ +// $Id: Memory.php,v 1.3 2004/07/07 02:49:19 joko Exp $ -require_once('Tree/Common.php'); -require_once('Tree/Error.php'); +require_once 'Tree/Common.php'; +require_once 'Tree/Error.php'; /** * this class can be used to step through a tree using ['parent'], ['child'], etc. @@ -146,6 +145,13 @@ var $_getNodeCurParent; /** + * the maximum depth of the tree + * @access private + * @var int the maximum depth of the tree + */ + var $_treeDepth = 0; + + /** * set up this object * * @version 2001/06/27 @@ -185,9 +191,16 @@ * @param array $options additional options you can set * @return boolean true on success */ - function setDataSource( $dsn , $options=array() ) + function switchDataSource( $type , $dsn='' , $options=array() ) { - $this->Tree( $dsn , $options ); + $data = $this->getNode(); + //$this->Tree( $dsn , $options ); + $this->Tree_Memory( $type , $GLOBALS['dummy'] , $options ); + + // this method prepares data retreived using getNode to be used + // in this type of tree + $this->dataSourceClass->setData($data); + $this->setup(); } /** @@ -213,9 +226,10 @@ * @version 2002/01/19 * @access public * @author Wolfram Kriesing + * @param array the result of a query which retreives (all) the tree data from a source * @return true or Tree_Error */ - function setup() + function setup($data=null) { if( $this->debug ) { @@ -223,7 +237,7 @@ $startTime = $startTime[1]+$startTime[0]; } - if(PEAR::isError($res = $this->dataSourceClass->setup()) ) + if(PEAR::isError($res = $this->dataSourceClass->setup($data)) ) return $res; if( $this->debug ) @@ -238,7 +252,7 @@ } /** - * retreive all the navigation data from the db and call build to build the + * retreive all the navigation data from the db and build the * tree in the array data and structure * * @version 2001/11/20 @@ -312,7 +326,7 @@ // most if checks in this foreach are for the following reason, if not stated otherwise: // dont make an data[''] or data[0] since this was not read from the DB, because id is autoincrement and starts at 1 // and also in an xml tree there can not be an element , i hope :-) - if( isset($value['parentId']) ) // see comment above + if( $value['parentId'] ) // see comment above { $this->data[$key]['parent'] = &$this->data[ $value['parentId'] ]; // the parent has an extra array which contains a reference to all it's children, set it here @@ -384,10 +398,11 @@ { // see comments in 'move' and 'remove' - if( method_exists($this->dataSourceClass,'add') ) + if (method_exists($this->dataSourceClass,'add')) { return $this->dataSourceClass->add( $newValues , $parentId , $prevId ); - else + } else { return $this->_throwError( 'method not implemented yet.' , __LINE__ ); + } } // end of function @@ -404,10 +419,8 @@ { // if removing recursively is not allowed, which means every child should be removed // then check if this element has a child and return "sorry baby cant remove :-) " - if( $this->removeRecursively != true ) - { - if( isset( $this->data[$id]['child'] ) ) - { + if ($this->removeRecursively != true) { + if (isset( $this->data[$id]['child'] )) { // TODO raise PEAR warning return $this->_throwError("Element with id=$id has children, cant be removed. Set 'setRemoveRecursively' to true to allow this.",__LINE__); } @@ -417,10 +430,11 @@ // if the prevId is in use we need to update the prevId of the element after the one that // is removed too, to have the prevId of the one that is removed!!! - if( method_exists($this->dataSourceClass,'add') ) + if (method_exists($this->dataSourceClass,'remove')) { return $this->dataSourceClass->remove( $id ); - else + } else { return $this->_throwError( 'method not implemented yet.' , __LINE__ ); + } } /** @@ -528,7 +542,7 @@ // and it has to change the prevId of the element that will be after it // so we may be simply call some method like 'update' too? - if( method_exists($this->dataSourceClass,'add') ) + if( method_exists($this->dataSourceClass,'move') ) return $this->dataSourceClass->move( $idToMove , $newParentId , $prevId ); else return $this->_throwError( 'method not implemented yet.' , __LINE__ ); @@ -545,10 +559,11 @@ */ function update( $id , $data ) { - if( method_exists($this->dataSourceClass,'add') ) + if (method_exists($this->dataSourceClass,'update')) { return $this->dataSourceClass->update($id,$data); - else + } else { return $this->_throwError( 'method not implemented yet.' , __LINE__ ); + } } // end of function @@ -586,16 +601,19 @@ // set the level, since we are walking through the structure here anyway we // can do this here, instead of up in the setup method :-) // always set the level to one higher than the parent's level, easy ha? - if( isset($this->data[$parentId]['parent']['level']) ) // this applies only to the root element(s) + if (isset($this->data[$parentId]['parent']['level'])) { // this applies only to the root element(s) $this->data[$parentId]['level'] = $this->data[$parentId]['parent']['level']+1; - else + + if ($this->data[$parentId]['level']>$this->_treeDepth) { + $this->_treeDepth = $this->data[$parentId]['level']; + } + } else { $this->data[$parentId]['level'] = 0; // set first level number to 0 + } - if( isset($this->children[$parentId]) && sizeof($this->children[$parentId]) ) - { + if (isset($this->children[$parentId]) && sizeof($this->children[$parentId])) { // go thru all the folders - foreach( $this->children[$parentId] as $child ) - { + foreach ($this->children[$parentId] as $child) { // build the structure under this folder, // use the current folder as the new parent and call build recursively // to build all the children @@ -626,21 +644,16 @@ function walk( $walkFunction , $id=0 , $returnType='string') { $useNode = $this->structure; // by default all of structure is used - if( $id == 0 ) - { + if ($id == 0) { $keys = array_keys($this->structure); $id = $keys[0]; - } - else - { + } else { $path = $this->getPath($id); // get the path, to be able to go to the element in this->structure array_pop($path); // pop off the last element, since it is the one requested $curNode = $this->structure; // start at the root of structure - foreach( $path as $node ) - { + foreach ($path as $node) { $curNode = $curNode[$node['id']]; // go as deep into structure as path defines } - $useNode = array(); // empty it first, so we dont have the other stuff in there from before $useNode[$id] = $curNode[$id]; // copy only the branch of the tree that the parameter $id requested } @@ -666,19 +679,16 @@ */ function _walk( $walkFunction , &$curLevel , $returnType ) { - if( sizeof($curLevel) ) - { - foreach( $curLevel as $key=>$value ) - { + if (sizeof($curLevel)) { + foreach ($curLevel as $key=>$value) { $ret = call_user_func( $walkFunction , $this->data[$key] ); - - switch( $returnType ) - { + switch ($returnType) { case 'array': $this->walkReturn[] = $ret; break; case 'ifArray': // this only adds the element if the $ret is an array and contains data - if( is_array($ret) ) + if (is_array($ret)) { $this->walkReturn[] = $ret; + } break; default: $this->walkReturn.= $ret; break; @@ -1136,12 +1146,9 @@ */ function &getNode( $startId=0 , $depth=0 ) { - if( $startId == 0) - { + if ($startId == 0) { $level = 0; - } - else - { + } else { $level = $this->getLevel($startId); } @@ -1149,10 +1156,12 @@ //!!! $this->_getNodeCurParent = $this->data['parent']['id']; // if the tree is empty dont walk through it - if( !sizeof($this->data) ) + if (!sizeof($this->data)) { return; + } - return $this->walk( array(&$this,'_getNode') , $startId , 'ifArray' ); + $ret = $this->walk( array(&$this,'_getNode') , $startId , 'ifArray' ); + return $ret; } // end of function /** @@ -1170,10 +1179,10 @@ */ function &_getNode( &$node ) { - if( $this->_getNodeMaxLevel ) - { - if( $this->getLevel($node['id']) < $this->_getNodeMaxLevel ) + if ($this->_getNodeMaxLevel) { + if ($this->getLevel($node['id']) < $this->_getNodeMaxLevel) { return $node; + } return; } return $node; @@ -1206,22 +1215,20 @@ * @return boolean true if the node has children */ function getChildren( $ids , $levels=1 ) - { -//FIXXME $levels to be implemented + { +//FIXXME $levels to be implemented $ret = array(); - if( is_array($ids) ) - { - foreach( $ids as $aId ) - { - if( $this->hasChildren( $aId ) ) + if (is_array($ids)) { + foreach ($ids as $aId) { + if ($this->hasChildren( $aId )) { $ret[$aId] = $this->data[$aId]['children']; + } } - } - else - { - if( $this->hasChildren( $ids ) ) + } else { + if ($this->hasChildren( $ids )) { $ret = $this->data[$ids]['children']; + } } return $ret; } // end of function @@ -1260,38 +1267,34 @@ // if $node is an array, we assume it is a collection of elements if( !is_array($node) ) - $node = $this->getNode($node); // if $node==0 then the entire tree is retreived - - foreach( $node as $aNode ) - { - print 'Element :'; - foreach( $aNode as $key=>$aElement ) - { - print "$key"; - - if( in_array( $key , $dontDump ) ) - { - if( !isset($aElement['id']) && is_array($aElement) ) - { - print "['ids']="; - $ids = array(); - foreach( $aElement as $aSubElement ) - $ids[] = $aSubElement['id']; - print implode(', ',$ids); - } - else - - print "['id']=".$aElement['id']; - } - else - { - print '='; - print_r($aElement); + $nodes = $this->getNode($node); // if $node==0 then the entire tree is retreived + + if (sizeof($node)) { + print ''; + $keys = array(); + foreach ($this->getRoot() as $key=>$x) { + if (!is_array($x)) { + print ""; + $keys[] = $key; } - print " ... "; } - print "
\n"; - } + print ""; + + foreach ($nodes as $aNode) { + print '"; + foreach ($keys as $aKey) { + if (!is_array($key)) { + $val = $aNode[$aKey] ? $aNode[$aKey] : ' '; + print ""; + } + } + print ""; + } + print "
name$key
'; + $prefix = ''; + for($i=0;$i<$aNode['level'];$i++) $prefix .= '- '; + print "$prefix {$aNode['name']}$val
"; + } } // end of function @@ -1316,7 +1319,7 @@ */ function copy( $srcId , $destId ) { - if( method_exists($this->dataSourceClass,'add') ) + if( method_exists($this->dataSourceClass,'copy') ) return $this->dataSourceClass->copy( $srcId , $destId ); else return $this->_throwError( 'method not implemented yet.' , __LINE__ );