SPL-StandardPHPLibrary
recursiveiteratoriterator.inc
Go to the documentation of this file.
1 <?php
2 
23 {
25  const LEAVES_ONLY = 0;
27  const SELF_FIRST = 1;
29  const CHILD_FIRST = 2;
30 
33  const CATCH_GET_CHILD = 0x00000002;
34 
35  private $ait = array();
36  private $count = 0;
37  private $mode = self::LEAVES_ONLY;
38  private $flags = 0;
39 
53  function __construct(RecursiveIterator $it, $mode = self::LEAVES_ONLY, $flags = 0)
54  {
55  $this->ait[0] = $it;
56  $this->mode = $mode;
57  $this->flags = $flags;
58  }
59 
62  function rewind()
63  {
64  while ($this->count) {
65  unset($this->ait[$this->count--]);
66  $this->endChildren();
67  }
68  $this->ait[0]->rewind();
69  $this->ait[0]->recursed = false;
70  callNextElement(true);
71  }
72 
75  function valid()
76  {
78  while ($count) {
79  $it = $this->ait[$count];
80  if ($it->valid()) {
81  return true;
82  }
83  $count--;
84  $this->endChildren();
85  }
86  return false;
87  }
88 
91  function key()
92  {
93  $it = $this->ait[$this->count];
94  return $it->key();
95  }
96 
99  function current()
100  {
101  $it = $this->ait[$this->count];
102  return $it->current();
103  }
104 
107  function next()
108  {
109  while ($this->count) {
110  $it = $this->ait[$this->count];
111  if ($it->valid()) {
112  if (!$it->recursed && callHasChildren()) {
113  $it->recursed = true;
114  try
115  {
116  $sub = callGetChildren();
117  }
118  catch (Exception $e)
119  {
120  if (!($this->flags & self::CATCH_GET_CHILD))
121  {
122  throw $e;
123  }
124  $it->next();
125  continue;
126  }
127  $sub->recursed = false;
128  $sub->rewind();
129  if ($sub->valid()) {
130  $this->ait[++$this->count] = $sub;
131  if (!$sub instanceof RecursiveIterator) {
132  throw new Exception(get_class($sub).'::getChildren() must return an object that implements RecursiveIterator');
133  }
134  $this->beginChildren();
135  return;
136  }
137  unset($sub);
138  }
139  $it->next();
140  $it->recursed = false;
141  if ($it->valid()) {
142  return;
143  }
144  $it->recursed = false;
145  }
146  if ($this->count) {
147  unset($this->ait[$this->count--]);
148  $it = $this->ait[$this->count];
149  $this->endChildren();
150  callNextElement(false);
151  }
152  }
153  callNextElement(true);
154  }
155 
159  function getSubIterator($level = NULL)
160  {
161  if (is_null($level)) {
162  $level = $this->count;
163  }
164  return @$this->ait[$level];
165  }
166 
170  function getInnerIterator()
171  {
172  return $this->it;
173  }
174 
177  function getDepth()
178  {
179  return $this->level;
180  }
181 
185  function callHasChildren()
186  {
187  return $this->ait[$this->count]->hasChildren();
188  }
189 
193  function callGetChildren()
194  {
195  return $this->ait[$this->count]->getChildren();
196  }
197 
201  function beginChildren()
202  {
203  }
204 
209  function endChildren()
210  {
211  }
212 
213  private function callNextElement($after_move)
214  {
215  if ($this->valid())
216  {
217  if ($after_move)
218  {
219  if (($this->mode == self::SELF_FIRST && $this->callHasChildren())
220  || $this->mode == self::LEAVES_ONLY)
221  $this->nextElement();
222  }
223  else
224  {
225  $this->nextElement();
226  }
227  }
228  }
229 
232  function nextElement()
233  {
234  }
235 }
236 
237 ?>
Iterates through recursive iterators.
Interface to access the current inner iteraor of iterator wrappers.
const CATCH_GET_CHILD
Flag: Catches exceptions during getChildren() calls and simply jumps to the next element.
const LEAVES_ONLY
Mode: Only show leaves.
nextElement()
Called when the next element is available.
$it
Definition: class_tree.php:105
Interface for recursive iteration with RecursiveIteratorIterator.
__construct(RecursiveIterator $it, $mode=self::LEAVES_ONLY, $flags=0)
Construct from RecursiveIterator.
beginChildren()
Called right after calling getChildren() and its rewind().
Basic Exception class.
Definition: spl.php:258
endChildren()
Called after current child iterator is invalid and right before it gets destructed.
const CHILD_FIRST
Mode: Show all children prior to their parent.
next()
Forward to next element.
rewind()
Rewind to top iterator as set in constructor.
const SELF_FIRST
Mode: Show parents prior to their children.