Skip to content

Commit cd1278d

Browse files
committed
Add support for JsonSerializable.
Fix issues with deserializing ResultSets, where a `false` would be appended to the stored results.
1 parent 66e9970 commit cd1278d

File tree

2 files changed

+43
-16
lines changed

2 files changed

+43
-16
lines changed

lib/Cake/ORM/ResultSet.php

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
use Cake\Database\Type;
2020
use \Iterator;
21+
use \JsonSerializable;
2122
use \Serializable;
2223

2324
/**
@@ -27,7 +28,7 @@
2728
* queries required for eager loading external associations.
2829
*
2930
*/
30-
class ResultSet implements Iterator, Serializable {
31+
class ResultSet implements Iterator, Serializable, JsonSerializable {
3132

3233
/**
3334
* Original query from where results where generated
@@ -200,20 +201,21 @@ protected function _calculateAssociationMap() {
200201
* @return void
201202
*/
202203
protected function _fetchResult() {
203-
$advance = ($this->_lastIndex < $this->_index);
204-
if (!$advance) {
205-
return;
206-
}
207204
if (isset($this->_results[$this->_index])) {
208205
$this->_current = $this->_results[$this->_index];
206+
$this->_lastIndex = $this->_index;
207+
return;
208+
}
209+
if (!$this->_statement) {
210+
$this->_current = false;
209211
return;
210212
}
211213
$row = $this->_statement->fetch('assoc');
212214
if ($row !== false) {
213215
$row = $this->_groupResult($row);
216+
$this->_results[] = $row;
214217
}
215218
$this->_current = $row;
216-
$this->_results[] = $row;
217219
$this->_lastIndex = $this->_index;
218220
}
219221

@@ -290,26 +292,37 @@ protected function _castValues($table, $values) {
290292
/**
291293
* Serialize a resultset.
292294
*
293-
* Part of Serializable Interface
295+
* Part of Serializable interface.
294296
*
295297
* @return string Serialized object
296298
*/
297299
public function serialize() {
298-
iterator_to_array($this);
300+
$this->toArray();
299301
return serialize($this->_results);
300302
}
301303

302304
/**
303305
* Unserialize a resultset.
304306
*
305-
* Part of Serializable Interface
307+
* Part of Serializable interface.
306308
*
307309
* @param string Serialized object
308310
* @return ResultSet The hydrated result set.
309311
*/
310312
public function unserialize($serialized) {
311313
$this->_results = unserialize($serialized);
312-
return $this;
314+
}
315+
316+
/**
317+
* Convert a result set into JSON.
318+
*
319+
* Part of JsonSerializable interface.
320+
*
321+
* @return array The data to convert to JSON
322+
*/
323+
public function jsonSerialize() {
324+
$this->toArray();
325+
return $this->_results;
313326
}
314327

315328
}

lib/Cake/Test/TestCase/ORM/ResultSetTest.php

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ public function setUp() {
3434
parent::setUp();
3535
$this->connection = ConnectionManager::getDataSource('test');
3636
$this->table = new Table(['table' => 'articles', 'connection' => $this->connection]);
37+
38+
$this->fixtureData = [
39+
['id' => 1, 'author_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body', 'published' => 'Y'],
40+
['id' => 2, 'author_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body', 'published' => 'Y'],
41+
['id' => 3, 'author_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body', 'published' => 'Y']
42+
];
3743
}
3844

3945
/**
@@ -83,15 +89,23 @@ public function testIteratorAfterSerialization() {
8389
$query = $this->table->find('all');
8490
$results = unserialize(serialize($query->execute()));
8591

86-
$expected = [
87-
['id' => 1, 'author_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body', 'published' => 'Y'],
88-
['id' => 2, 'author_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body', 'published' => 'Y'],
89-
['id' => 3, 'author_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body', 'published' => 'Y']
90-
];
9192
// Use a loop to test Iterator implementation
9293
foreach ($results as $i => $row) {
93-
$this->assertEquals($expected[$i], $row, "Row $i does not match");
94+
$this->assertEquals($this->fixtureData[$i], $row, "Row $i does not match");
9495
}
9596
}
9697

98+
/**
99+
* Test converting resultsets into json
100+
*
101+
* @return void
102+
*/
103+
public function testJsonSerialize() {
104+
$query = $this->table->find('all');
105+
$results = $query->execute();
106+
107+
$expected = json_encode($this->fixtureData);
108+
$this->assertEquals(json_encode($results), $expected);
109+
}
110+
97111
}

0 commit comments

Comments
 (0)