1 <?php
2 /**
3 * @package Joomla.Platform
4 * @subpackage Database
5 *
6 * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved.
7 * @license GNU General Public License version 2 or later; see LICENSE
8 */
9
10 defined('JPATH_PLATFORM') or die;
11
12 /**
13 * Joomla Platform Database Driver Class
14 *
15 * @since 12.1
16 */
17 abstract class JDatabaseIterator implements Countable, Iterator
18 {
19 /**
20 * The database cursor.
21 *
22 * @var mixed
23 * @since 12.1
24 */
25 protected $cursor;
26
27 /**
28 * The class of object to create.
29 *
30 * @var string
31 * @since 12.1
32 */
33 protected $class;
34
35 /**
36 * The name of the column to use for the key of the database record.
37 *
38 * @var mixed
39 * @since 12.1
40 */
41 private $_column;
42
43 /**
44 * The current database record.
45 *
46 * @var mixed
47 * @since 12.1
48 */
49 private $_current;
50
51 /**
52 * A numeric or string key for the current database record.
53 *
54 * @var scalar
55 * @since 12.1
56 */
57 private $_key;
58
59 /**
60 * The number of fetched records.
61 *
62 * @var integer
63 * @since 12.1
64 */
65 private $_fetched = 0;
66
67 /**
68 * Database iterator constructor.
69 *
70 * @param mixed $cursor The database cursor.
71 * @param string $column An option column to use as the iterator key.
72 * @param string $class The class of object that is returned.
73 *
74 * @throws InvalidArgumentException
75 */
76 public function __construct($cursor, $column = null, $class = 'stdClass')
77 {
78 if (!class_exists($class))
79 {
80 throw new InvalidArgumentException(sprintf('new %s(*%s*, cursor)', get_class($this), gettype($class)));
81 }
82
83 $this->cursor = $cursor;
84 $this->class = $class;
85 $this->_column = $column;
86 $this->_fetched = 0;
87 $this->next();
88 }
89
90 /**
91 * Database iterator destructor.
92 *
93 * @since 12.1
94 */
95 public function __destruct()
96 {
97 if ($this->cursor)
98 {
99 $this->freeResult($this->cursor);
100 }
101 }
102
103 /**
104 * The current element in the iterator.
105 *
106 * @return object
107 *
108 * @see Iterator::current()
109 * @since 12.1
110 */
111 public function current()
112 {
113 return $this->_current;
114 }
115
116 /**
117 * The key of the current element in the iterator.
118 *
119 * @return scalar
120 *
121 * @see Iterator::key()
122 * @since 12.1
123 */
124 public function key()
125 {
126 return $this->_key;
127 }
128
129 /**
130 * Moves forward to the next result from the SQL query.
131 *
132 * @return void
133 *
134 * @see Iterator::next()
135 * @since 12.1
136 */
137 public function next()
138 {
139 // Set the default key as being the number of fetched object
140 $this->_key = $this->_fetched;
141
142 // Try to get an object
143 $this->_current = $this->fetchObject();
144
145 // If an object has been found
146 if ($this->_current)
147 {
148 // Set the key as being the indexed column (if it exists)
149 if (isset($this->_current->{$this->_column}))
150 {
151 $this->_key = $this->_current->{$this->_column};
152 }
153
154 // Update the number of fetched object
155 $this->_fetched++;
156 }
157 }
158
159 /**
160 * Rewinds the iterator.
161 *
162 * This iterator cannot be rewound.
163 *
164 * @return void
165 *
166 * @see Iterator::rewind()
167 * @since 12.1
168 */
169 public function rewind()
170 {
171 }
172
173 /**
174 * Checks if the current position of the iterator is valid.
175 *
176 * @return boolean
177 *
178 * @see Iterator::valid()
179 * @since 12.1
180 */
181 public function valid()
182 {
183 return (boolean) $this->_current;
184 }
185
186 /**
187 * Method to fetch a row from the result set cursor as an object.
188 *
189 * @return mixed Either the next row from the result set or false if there are no more rows.
190 *
191 * @since 12.1
192 */
193 abstract protected function fetchObject();
194
195 /**
196 * Method to free up the memory used for the result set.
197 *
198 * @return void
199 *
200 * @since 12.1
201 */
202 abstract protected function freeResult();
203 }
204