# Source for file PreOrderIterator.php

Documentation is available at PreOrderIterator.php

1. <?php
2. /*
3. * $Id: PreOrderIterator.php 1080 2007-02-10 18:17:08Z romanb $
4. *
5. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
6. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
7. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
8. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
9. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
10. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
11. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
12. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
13. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
14. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
15. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16. *
17. * This software consists of voluntary contributions made by many individuals
18. * and is licensed under the LGPL. For more information, see
19. * <http://www.phpdoctrine.com>.
20. */
21. /**
22. * Doctrine_Node_NestedSet_PreOrderIterator
23. *
24. * @package Doctrine
25. * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
26. * @category Object Relational Mapping
27. * @link www.phpdoctrine.com
28. * @since 1.0
29. * @version $Revision: 1080 $
30. * @author Joe Simms <joe.simms@websites4.com>
31. */
32. class Doctrine_Node_NestedSet_PreOrderIterator implements Iterator
33. {
34. /**
35. * @var Doctrine_Collection $collection
36. */
37. protected $collection;
38. /**
39. * @var array $keys
40. */
41. protected $keys;
42. /**
43. * @var mixed $key
44. */
45. protected $key;
46. /**
47. * @var integer $index
48. */
49. protected $index;
50. /**
51. * @var integer $index
52. */
53. protected $prevIndex;
54. /**
55. * @var integer $index
56. */
57. protected $traverseLevel;
58. /**
59. * @var integer $count
60. */
61. protected $count;
63. public function __construct($record, $opts)
64. {
65. $componentName = $record->getTable()->getComponentName();
67. $q = $record->getTable()->createQuery();
69. $params = array($record->get('lft'), $record->get('rgt'));
70. if (isset($opts['include_record']) && $opts['include_record']) {
71. $query = $q->where("$componentName.lft >= ? AND $componentName.rgt <= ?", $params)->orderBy("$componentName.lft asc");
72. } else {
73. $query = $q->where("$componentName.lft > ? AND $componentName.rgt < ?", $params)->orderBy("$componentName.lft asc");
74. }
76. $query = $record->getTable()->getTree()->returnQueryWithRootId($query, $record->getNode()->getRootValue());
78. $this->maxLevel = isset($opts['depth']) ? ($opts['depth'] + $record->getNode()->getLevel()) : 0;
79. $this->options = $opts;
80. $this->collection = isset($opts['collection']) ? $opts['collection'] : $query->execute();
81. $this->keys = $this->collection->getKeys();
82. $this->count = $this->collection->count();
83. $this->index = -1;
84. $this->level = $record->getNode()->getLevel();
85. $this->prevLeft = $record->getNode()->getLeftValue();
87. // clear the table identity cache
88. $record->getTable()->clear();
89. }
91. /**
92. * rewinds the iterator
93. *
94. * @return void
95. */
96. public function rewind()
97. {
98. $this->index = -1;
99. $this->key = null;
100. }
102. /**
103. * returns the current key
104. *
105. * @return integer
106. */
107. public function key()
108. {
109. return $this->key;
110. }
112. /**
113. * returns the current record
114. *
115. * @return Doctrine_Record
116. */
117. public function current()
118. {
119. $record = $this->collection->get($this->key);
120. $record->getNode()->setLevel($this->level);
121. return $record;
122. }
124. /**
125. * advances the internal pointer
126. *
127. * @return void
128. */
129. public function next()
130. {
131. while ($current = $this->advanceIndex()) {
132. if ($this->maxLevel && ($this->level > $this->maxLevel)) {
133. continue;
134. }
136. return $current;
137. }
139. return false;
140. }
142. /**
143. * @return boolean whether or not the iteration will continue
144. */
145. public function valid()
146. {
147. return ($this->index < $this->count);
148. }
150. public function count()
151. {
152. return $this->count;
153. }
155. private function updateLevel()
156. {
157. if (!(isset($this->options['include_record']) && $this->options['include_record'] && $this->index == 0)) {
158. $left = $this->collection->get($this->key)->getNode()->getLeftValue();
159. $this->level += $this->prevLeft - $left + 2;
160. $this->prevLeft = $left;
161. }
162. }
164. private function advanceIndex()
165. {
166. $this->index++;
167. $i = $this->index;
168. if (isset($this->keys[$i])) {
169. $this->key = $this->keys[$i];
170. $this->updateLevel();
171. return $this->current();
172. }
174. return false;
175. }
176. }