00001 <?php 00002 00022 class RecursiveIteratorIterator implements OuterIterator 00023 { 00025 const LEAVES_ONLY = 0; 00027 const SELF_FIRST = 1; 00029 const CHILD_FIRST = 2; 00030 00033 const CATCH_GET_CHILD = 0x00000002; 00034 00035 private $ait = array(); 00036 private $count = 0; 00037 private $mode = self::LEAVES_ONLY; 00038 private $flags = 0; 00039 00053 function __construct(RecursiveIterator $it, $mode = self::LEAVES_ONLY, $flags = 0) 00054 { 00055 $this->ait[0] = $it; 00056 $this->mode = $mode; 00057 $this->flags = $flags; 00058 } 00059 00062 function rewind() 00063 { 00064 while ($this->count) { 00065 unset($this->ait[$this->count--]); 00066 $this->endChildren(); 00067 } 00068 $this->ait[0]->rewind(); 00069 $this->ait[0]->recursed = false; 00070 callNextElement(true); 00071 } 00072 00075 function valid() 00076 { 00077 $count = $this->count; 00078 while ($count) { 00079 $it = $this->ait[$count]; 00080 if ($it->valid()) { 00081 return true; 00082 } 00083 $count--; 00084 $this->endChildren(); 00085 } 00086 return false; 00087 } 00088 00091 function key() 00092 { 00093 $it = $this->ait[$this->count]; 00094 return $it->key(); 00095 } 00096 00099 function current() 00100 { 00101 $it = $this->ait[$this->count]; 00102 return $it->current(); 00103 } 00104 00107 function next() 00108 { 00109 while ($this->count) { 00110 $it = $this->ait[$this->count]; 00111 if ($it->valid()) { 00112 if (!$it->recursed && callHasChildren()) { 00113 $it->recursed = true; 00114 try 00115 { 00116 $sub = callGetChildren(); 00117 } 00118 catch (Exception $e) 00119 { 00120 if (!($this->flags & self::CATCH_GET_CHILD)) 00121 { 00122 throw $e; 00123 } 00124 $it->next(); 00125 continue; 00126 } 00127 $sub->recursed = false; 00128 $sub->rewind(); 00129 if ($sub->valid()) { 00130 $this->ait[++$this->count] = $sub; 00131 if (!$sub instanceof RecursiveIterator) { 00132 throw new Exception(get_class($sub).'::getChildren() must return an object that implements RecursiveIterator'); 00133 } 00134 $this->beginChildren(); 00135 return; 00136 } 00137 unset($sub); 00138 } 00139 $it->next(); 00140 $it->recursed = false; 00141 if ($it->valid()) { 00142 return; 00143 } 00144 $it->recursed = false; 00145 } 00146 if ($this->count) { 00147 unset($this->ait[$this->count--]); 00148 $it = $this->ait[$this->count]; 00149 $this->endChildren(); 00150 callNextElement(false); 00151 } 00152 } 00153 callNextElement(true); 00154 } 00155 00159 function getSubIterator($level = NULL) 00160 { 00161 if (is_null($level)) { 00162 $level = $this->count; 00163 } 00164 return @$this->ait[$level]; 00165 } 00166 00170 function getInnerIterator() 00171 { 00172 return $this->it; 00173 } 00174 00177 function getDepth() 00178 { 00179 return $this->level; 00180 } 00181 00185 function callHasChildren() 00186 { 00187 return $this->ait[$this->count]->hasChildren(); 00188 } 00189 00193 function callGetChildren() 00194 { 00195 return $this->ait[$this->count]->getChildren(); 00196 } 00197 00201 function beginChildren() 00202 { 00203 } 00204 00209 function endChildren() 00210 { 00211 } 00212 00213 private function callNextElement($after_move) 00214 { 00215 if ($this->valid()) 00216 { 00217 if ($after_move) 00218 { 00219 if (($this->mode == self::SELF_FIRST && $this->callHasChildren()) 00220 || $this->mode == self::LEAVES_ONLY) 00221 $this->nextElement(); 00222 } 00223 else 00224 { 00225 $this->nextElement(); 00226 } 00227 } 00228 } 00229 00232 function nextElement() 00233 { 00234 } 00235 } 00236 00237 ?>
1.5.2