1<?php 2 3/** @file recursivecachingiterator.inc 4 * @ingroup SPL 5 * @brief class RecursiveCachingIterator 6 * @author Marcus Boerger 7 * @date 2003 - 2009 8 * 9 * SPL - Standard PHP Library 10 */ 11 12/** 13 * @brief Cached recursive iteration over another Iterator 14 * @author Marcus Boerger 15 * @version 1.2 16 * @since PHP 5.1 17 * 18 * @see CachingIterator 19 */ 20class RecursiveCachingIterator extends CachingIterator implements RecursiveIterator 21{ 22 private $hasChildren; 23 private $getChildren; 24 25 /** Construct from another iterator 26 * 27 * @param it Iterator to cache 28 * @param flags Bitmask: 29 * - CALL_TOSTRING (whether to call __toString() for every element) 30 * - CATCH_GET_CHILD (whether to catch exceptions when trying to get childs) 31 */ 32 function __construct(RecursiveIterator $it, $flags = self::CALL_TOSTRING) 33 { 34 parent::__construct($it, $flags); 35 } 36 37 /** Rewind Iterator 38 */ 39 function rewind(); 40 { 41 $this->hasChildren = false; 42 $this->getChildren = NULL; 43 parent::rewind(); 44 } 45 46 /** Forward to next element if necessary then an Iterator for the Children 47 * will be created. 48 */ 49 function next() 50 { 51 if ($this->hasChildren = $this->it->hasChildren()) 52 { 53 try 54 { 55 $child = $this->it->getChildren(); 56 if (!$this->ref) 57 { 58 $this->ref = new ReflectionClass($this); 59 } 60 $this->getChildren = $ref->newInstance($child, $this->flags); 61 } 62 catch(Exception $e) 63 { 64 if (!$this->flags & self::CATCH_GET_CHILD) 65 { 66 throw $e; 67 } 68 $this->hasChildren = false; 69 $this->getChildren = NULL; 70 } 71 } else 72 { 73 $this->getChildren = NULL; 74 } 75 parent::next(); 76 } 77 78 private $ref; 79 80 /** @return whether the current element has children 81 * @note The check whether the Iterator for the children can be created was 82 * already executed. Hence when flag CATCH_GET_CHILD was given in 83 * constructor this function returns false so that getChildren does 84 * not try to access those children. 85 */ 86 function hasChildren() 87 { 88 return $this->hasChildren; 89 } 90 91 /** @return An Iterator for the children 92 */ 93 function getChildren() 94 { 95 return $this->getChildren; 96 } 97} 98 99?> 100