diff --git a/lib/Cake/ORM/ResultSet.php b/lib/Cake/ORM/ResultSet.php index 182c4be3ceb..0c9b48734c6 100644 --- a/lib/Cake/ORM/ResultSet.php +++ b/lib/Cake/ORM/ResultSet.php @@ -18,6 +18,7 @@ use Cake\Database\Type; use \Iterator; +use \JsonSerializable; use \Serializable; /** @@ -27,7 +28,7 @@ * queries required for eager loading external associations. * */ -class ResultSet implements Iterator, Serializable { +class ResultSet implements Iterator, Serializable, JsonSerializable { /** * Original query from where results where generated @@ -200,20 +201,21 @@ protected function _calculateAssociationMap() { * @return void */ protected function _fetchResult() { - $advance = ($this->_lastIndex < $this->_index); - if (!$advance) { - return; - } if (isset($this->_results[$this->_index])) { $this->_current = $this->_results[$this->_index]; + $this->_lastIndex = $this->_index; + return; + } + if (!$this->_statement) { + $this->_current = false; return; } $row = $this->_statement->fetch('assoc'); if ($row !== false) { $row = $this->_groupResult($row); + $this->_results[] = $row; } $this->_current = $row; - $this->_results[] = $row; $this->_lastIndex = $this->_index; } @@ -290,26 +292,37 @@ protected function _castValues($table, $values) { /** * Serialize a resultset. * - * Part of Serializable Interface + * Part of Serializable interface. * * @return string Serialized object */ public function serialize() { - iterator_to_array($this); + $this->toArray(); return serialize($this->_results); } /** * Unserialize a resultset. * - * Part of Serializable Interface + * Part of Serializable interface. * * @param string Serialized object * @return ResultSet The hydrated result set. */ public function unserialize($serialized) { $this->_results = unserialize($serialized); - return $this; + } + +/** + * Convert a result set into JSON. + * + * Part of JsonSerializable interface. + * + * @return array The data to convert to JSON + */ + public function jsonSerialize() { + $this->toArray(); + return $this->_results; } } diff --git a/lib/Cake/Test/TestCase/ORM/ResultSetTest.php b/lib/Cake/Test/TestCase/ORM/ResultSetTest.php index 23dd93e2aa3..3b5b146c75c 100644 --- a/lib/Cake/Test/TestCase/ORM/ResultSetTest.php +++ b/lib/Cake/Test/TestCase/ORM/ResultSetTest.php @@ -34,6 +34,12 @@ public function setUp() { parent::setUp(); $this->connection = ConnectionManager::getDataSource('test'); $this->table = new Table(['table' => 'articles', 'connection' => $this->connection]); + + $this->fixtureData = [ + ['id' => 1, 'author_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body', 'published' => 'Y'], + ['id' => 2, 'author_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body', 'published' => 'Y'], + ['id' => 3, 'author_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body', 'published' => 'Y'] + ]; } /** @@ -83,15 +89,23 @@ public function testIteratorAfterSerialization() { $query = $this->table->find('all'); $results = unserialize(serialize($query->execute())); - $expected = [ - ['id' => 1, 'author_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body', 'published' => 'Y'], - ['id' => 2, 'author_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body', 'published' => 'Y'], - ['id' => 3, 'author_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body', 'published' => 'Y'] - ]; // Use a loop to test Iterator implementation foreach ($results as $i => $row) { - $this->assertEquals($expected[$i], $row, "Row $i does not match"); + $this->assertEquals($this->fixtureData[$i], $row, "Row $i does not match"); } } +/** + * Test converting resultsets into json + * + * @return void + */ + public function testJsonSerialize() { + $query = $this->table->find('all'); + $results = $query->execute(); + + $expected = json_encode($this->fixtureData); + $this->assertEquals(json_encode($results), $expected); + } + }