iterator.php
5.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
<?php
/**
* @package FrameworkOnFramework
* @subpackage database
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*
* This file is adapted from the Joomla! Platform. It is used to iterate a database cursor returning FOFTable objects
* instead of plain stdClass objects
*/
// Protect from unauthorized access
defined('FOF_INCLUDED') or die;
/**
* Database iterator
*/
abstract class FOFDatabaseIterator implements Iterator
{
/**
* The database cursor.
*
* @var mixed
*/
protected $cursor;
/**
* The class of object to create.
*
* @var string
*/
protected $class;
/**
* The name of the column to use for the key of the database record.
*
* @var mixed
*/
private $_column;
/**
* The current database record.
*
* @var mixed
*/
private $_current;
/**
* The current database record as a FOFTable object.
*
* @var FOFTable
*/
private $_currentTable;
/**
* A numeric or string key for the current database record.
*
* @var scalar
*/
private $_key;
/**
* The number of fetched records.
*
* @var integer
*/
private $_fetched = 0;
/**
* A FOFTable object created using the class type $class, used by getTable
*
* @var FOFTable
*/
private $_tableObject = null;
/**
* Returns an iterator object for a specific database type
*
* @param string $dbName The database type, e.g. mysql, mysqli, sqlazure etc.
* @param mixed $cursor The database cursor
* @param string $column An option column to use as the iterator key
* @param string $class The table class of the returned objects
* @param array $config Configuration parameters to push to the table class
*
* @return FOFDatabaseIterator
*
* @throws InvalidArgumentException
*/
public static function &getIterator($dbName, $cursor, $column = null, $class, $config = array())
{
$className = 'FOFDatabaseIterator' . ucfirst($dbName);
$object = new $className($cursor, $column, $class, $config);
return $object;
}
/**
* Database iterator constructor.
*
* @param mixed $cursor The database cursor.
* @param string $column An option column to use as the iterator key.
* @param string $class The table class of the returned objects.
* @param array $config Configuration parameters to push to the table class
*
* @throws InvalidArgumentException
*/
public function __construct($cursor, $column = null, $class, $config = array())
{
// Figure out the type and prefix of the class by the class name
$parts = FOFInflector::explode($class);
if(count($parts) != 3)
{
throw new InvalidArgumentException('Invalid table name, expected a pattern like ComponentTableFoobar got '.$class);
}
$this->_tableObject = FOFTable::getInstance($parts[2], ucfirst($parts[0]) . ucfirst($parts[1]))->getClone();
$this->cursor = $cursor;
$this->class = 'stdClass';
$this->_column = $column;
$this->_fetched = 0;
$this->next();
}
/**
* Database iterator destructor.
*/
public function __destruct()
{
if ($this->cursor)
{
$this->freeResult($this->cursor);
}
}
/**
* The current element in the iterator.
*
* @return object
*
* @see Iterator::current()
*/
public function current()
{
return $this->_currentTable;
}
/**
* The key of the current element in the iterator.
*
* @return scalar
*
* @see Iterator::key()
*/
public function key()
{
return $this->_key;
}
/**
* Moves forward to the next result from the SQL query.
*
* @return void
*
* @see Iterator::next()
*/
public function next()
{
// Set the default key as being the number of fetched object
$this->_key = $this->_fetched;
// Try to get an object
$this->_current = $this->fetchObject();
// If an object has been found
if ($this->_current)
{
$this->_currentTable = $this->getTable();
// Set the key as being the indexed column (if it exists)
if (isset($this->_current->{$this->_column}))
{
$this->_key = $this->_current->{$this->_column};
}
// Update the number of fetched object
$this->_fetched++;
}
}
/**
* Rewinds the iterator.
*
* This iterator cannot be rewound.
*
* @return void
*
* @see Iterator::rewind()
*/
public function rewind()
{
}
/**
* Checks if the current position of the iterator is valid.
*
* @return boolean
*
* @see Iterator::valid()
*/
public function valid()
{
return (boolean) $this->_current;
}
/**
* Method to fetch a row from the result set cursor as an object.
*
* @return mixed Either the next row from the result set or false if there are no more rows.
*/
abstract protected function fetchObject();
/**
* Method to free up the memory used for the result set.
*
* @return void
*/
abstract protected function freeResult();
/**
* Returns the data in $this->_current as a FOFTable instance
*
* @return FOFTable
*
* @throws OutOfBoundsException
*/
protected function getTable()
{
if (!$this->valid())
{
throw new OutOfBoundsException('Cannot get item past iterator\'s bounds', 500);
}
$this->_tableObject->bind($this->_current);
return $this->_tableObject;
}
}