
Klasa prostego drzewka:
<?php class Tree implements IteratorAggregate { protected $oElement; public function __construct($sName = NULL) { if($sName != NULL) { $this->$sName = new Tree; } } /** * Dodajemy nowy wezel do istniejacego * @acces public * @param string $sName nazwa naszego wezla * @param object $oItem obiekt ktory chcemy podlaczyc do naszego drzewa * @return void */ public function addChild($sName, $oItem) { $this->$sName = new Tree; $this->aNode[$sName]->oElement = &$oItem; } /** * Sprawdzamy czy dany wezel ma wezly potomne * @acces public * @return bool */ public function checkChildren() { } /** * Pobieramy obiekt przywiazany do danego wezla * @acces public * @return object */ public function &getObject() { $oObject = &$this->oElement; } /** * Pobieramy wezly * @acces public * @return object */ public function getNodes() { return $this->aNode; } // php 5 RoX public function __get($p) { return $this->aNode[$p]; else return false; } public function __set($p,$val) { $this->aNode[$p] = $val; } public function getIterator() { return new RecursiveIteratorIterator(new TreeIterator($this)); } } ?>
Iterator dla tego drzewka:
<?php class TreeIterator implements RecursiveIterator { private $oTree = NULL; private $iKey = 0; private $oCurrentNode; public function __construct($oMenu) { $this->oTree = &$oMenu; foreach(new ArrayObject($this->oTree->getNodes()) as $property => $value) { $this->aItems[] = $property; } } /** * Ustawiamy obecny wezel * @acces private * @param int $iKey klucz danego wezla * @return void */ private function setCurrent($iKey) { $sNodeName = $this->aItems[$iKey]; $this->oCurrentNode = $this->oTree->$sNodeName; } //Metody Interfejsu { $this->iKey = 0; $this->setCurrent($this->iKey); } public function valid() { } { $this->iKey++; $this->setCurrent($this->iKey); } { return $this->iKey; } { $this->setCurrent($this->iKey); return $this->oCurrentNode->getObject(); //Zwracamy do petli obiekt podlaczony do tej galezi } public function hasChildren() { return $this->oCurrentNode->checkChildren(); } public function getChildren() { return new TreeIterator($this->oCurrentNode); } } ?>
Testowe obiekty które wrzucam do drzewa:
<?php abstract class MenuElement { private $fullName; public function __construct($sName) { $this->fullName = $sName; } public function getName() { return $this->fullName; } } class MenuFolder extends MenuElement { } class MenuLink extends MenuElement { private $sAction; { parent::__construct($sName); $this->setParams($aParams); $this->setAction($sAction); } public function setParams($aParams) { $this->aParams = &$aParams; } public function setAction($sActionName) { $this->sAction = $sActionName; } private function paramsToString() { $string = ''; foreach ($this->aParams as $key => $val) { $string .= '&'.$key.'='.$val; } return $string; } public function getUrl() { return '?action='.$this->sAction.$this->paramsToString(); } } ?>
I test:
<?php include('menu.php'); include('TreeIterator.php'); $menu = new Tree(); $menu->addChild( 'artykuly' , new MenuFolder('Nasze Artykuły') ); $menu->artykuly->addChild( 'pralki' , new MenuFolder( 'Zobacz pralki') ); $menu->artykuly->pralki->addChild('automatyczne' , new MenuLink( 'Zobacz automatyczne','showNews',array('id' => 5) )); $menu->addChild( 'onas' , new MenuFolder('O nas') ); $menu->addChild( 'firma' , new MenuFolder('Nasza firma, adres i kontakt') ); $menu->addChild( 'news' , new MenuFolder('Aktualnosci na stronie') ); $menu->news->addChild( 'dzisiaj' , new MenuLink( 'Dzisiejsze newsy','showNews',array('id' => 5) ) ); $menu->news->addChild('wszystkie' , new MenuFolder('Wszystkie newsy')); $menu->news->wszystkie->addChild('jakis', new MenuLink( 'News ze srody','showNews',array('id' => 5) )); $menu->addChild('test',new MenuFolder('Testowy folder')); foreach($menu as $key => $val ) { //echo $value; //echo '<br>'; } ?>
A zwraca:
Kod
MenuLink Object
(
[sAction:private] => showNews
[aParams:private] => Array
(
[id] => 5
)
[fullName:private] => Zobacz automatyczne
)
MenuFolder Object
(
[fullName:private] => O nas
)
MenuFolder Object
(
[fullName:private] => Nasza firma, adres i kontakt
)
MenuLink Object
(
[sAction:private] => showNews
[aParams:private] => Array
(
[id] => 5
)
[fullName:private] => Dzisiejsze newsy
)
MenuLink Object
(
[sAction:private] => showNews
[aParams:private] => Array
(
[id] => 19
)
[fullName:private] => Wczorajsze newsy
)
MenuLink Object
(
[sAction:private] => showNews
[aParams:private] => Array
(
[id] => 5
)
[fullName:private] => News ze srody
)
MenuFolder Object
(
[fullName:private] => Testowy folder
)
(
[sAction:private] => showNews
[aParams:private] => Array
(
[id] => 5
)
[fullName:private] => Zobacz automatyczne
)
MenuFolder Object
(
[fullName:private] => O nas
)
MenuFolder Object
(
[fullName:private] => Nasza firma, adres i kontakt
)
MenuLink Object
(
[sAction:private] => showNews
[aParams:private] => Array
(
[id] => 5
)
[fullName:private] => Dzisiejsze newsy
)
MenuLink Object
(
[sAction:private] => showNews
[aParams:private] => Array
(
[id] => 19
)
[fullName:private] => Wczorajsze newsy
)
MenuLink Object
(
[sAction:private] => showNews
[aParams:private] => Array
(
[id] => 5
)
[fullName:private] => News ze srody
)
MenuFolder Object
(
[fullName:private] => Testowy folder
)
Czyli zawsze ostatni element galezi pomijajac elementy wyzszego rzędu


I problem rozwiązany

<?php RIT_LEAVES_ONLY // (the default) only returns leaves in current and skips all parents (elements that have children). ?>
A jeśli zmienimy na:
<?php RIT_SELF_FIRST //first returns the parent and then their children. ?>
Otrzymamy efekt, który chciałem
