diff --git a/src/Adapter/AdapterInterface.php b/src/Adapter/AdapterInterface.php index 513517e..ac01f56 100644 --- a/src/Adapter/AdapterInterface.php +++ b/src/Adapter/AdapterInterface.php @@ -24,4 +24,11 @@ interface AdapterInterface extends Countable * @return array */ public function getItems($offset, $itemCountPerPage); + + /** + * Returns the internal cache id + * + * @return string + */ + public function getCacheInternalId(); } diff --git a/src/Adapter/ArrayAdapter.php b/src/Adapter/ArrayAdapter.php index 3044820..8e01fc1 100644 --- a/src/Adapter/ArrayAdapter.php +++ b/src/Adapter/ArrayAdapter.php @@ -57,4 +57,14 @@ public function count() { return $this->count; } + + /** + * Returns the internal cache id + * + * @return string + */ + public function getCacheInternalId() + { + return json_encode($this); + } } diff --git a/src/Adapter/Callback.php b/src/Adapter/Callback.php index 523a1b4..51fd3e4 100644 --- a/src/Adapter/Callback.php +++ b/src/Adapter/Callback.php @@ -62,4 +62,14 @@ public function count() { return call_user_func($this->countCallback); } + + /** + * Returns the internal cache id + * + * @return string + */ + public function getCacheInternalId() + { + return json_encode($this); + } } diff --git a/src/Adapter/DbSelect.php b/src/Adapter/DbSelect.php index ff2db0e..154867d 100644 --- a/src/Adapter/DbSelect.php +++ b/src/Adapter/DbSelect.php @@ -151,4 +151,12 @@ protected function getSelectCount() return $countSelect; } + + /** + * @return string + */ + public function getCacheInternalId() + { + return hash('sha512', $this->select->getSqlString()); + } } diff --git a/src/Adapter/Iterator.php b/src/Adapter/Iterator.php index d01f7f2..abf1102 100644 --- a/src/Adapter/Iterator.php +++ b/src/Adapter/Iterator.php @@ -68,4 +68,14 @@ public function count() { return $this->count; } + + /** + * Returns the internal cache id + * + * @return string + */ + public function getCacheInternalId() + { + return json_encode($this); + } } diff --git a/src/Adapter/NullFill.php b/src/Adapter/NullFill.php index b343d27..1de5d33 100644 --- a/src/Adapter/NullFill.php +++ b/src/Adapter/NullFill.php @@ -56,4 +56,14 @@ public function count() { return $this->count; } + + /** + * Returns the internal cache id + * + * @return string + */ + public function getCacheInternalId() + { + return json_encode($this); + } } diff --git a/src/Paginator.php b/src/Paginator.php index da85902..5bb959f 100644 --- a/src/Paginator.php +++ b/src/Paginator.php @@ -865,7 +865,7 @@ protected function _getCacheInternalId() // @codingStandardsIgnoreEnd return md5( get_class($this->getAdapter()) - . json_encode($this->getAdapter()) + . $this->getAdapter()->getCacheInternalId() . $this->getItemCountPerPage() ); } diff --git a/test/PaginatorTest.php b/test/PaginatorTest.php index 006b4de..bb712d2 100644 --- a/test/PaginatorTest.php +++ b/test/PaginatorTest.php @@ -9,7 +9,6 @@ namespace ZendTest\Paginator; -use ArrayIterator; use ArrayObject; use PHPUnit\Framework\TestCase; use ReflectionMethod; @@ -945,6 +944,101 @@ public function testAcceptsComplexAdapters() $this->assertInstanceOf('ArrayObject', $paginator->getCurrentItems()); } + /** + * This piece of code tests the failure in determine different cache_id for different queries when using the + * generic TestAdapter. All the results will hit the same cache_id when simulating DbSelectAdapter object. + */ + public function testDbSelectAdapterLikeFailure() + { + $paginator = new Paginator\Paginator( + new TestAsset\TestAdapter(function () { + // Simulate some "real" params + return [ + 'driver' => [ + 'name' => 'mysql', + 'uptime' => new \DateTime('Y-m-d H:i:s'), + ], + 'sql' => 'Select * FROM table1 where ID = 1' + ]; + }) + ); + + $reflectionGetCacheInternalId = new ReflectionMethod($paginator, '_getCacheInternalId'); + $reflectionGetCacheInternalId->setAccessible(true); + $firstOutputGetCacheInternalId = $reflectionGetCacheInternalId->invoke($paginator); + + sleep(1); + + $paginator = new Paginator\Paginator( + new TestAsset\TestAdapter(function () { + return [ + // Simulate some "real" params + 'driver' => [ + 'name' => 'mysql', + 'uptime' => new \DateTime('Y-m-d H:i:s'), + ], + 'sql' => 'Select * FROM table2 where ID = 2' + ]; + }) + ); + $reflectionGetCacheInternalId = new ReflectionMethod($paginator, '_getCacheInternalId'); + $reflectionGetCacheInternalId->setAccessible(true); + $secondOutputGetCacheInternalId = $reflectionGetCacheInternalId->invoke($paginator); + + $this->assertEquals($firstOutputGetCacheInternalId, $secondOutputGetCacheInternalId); + + $this->assertInstanceOf('ArrayObject', $paginator->getCurrentItems()); + } + + /** + * This piece of code tests the success in determine different cache_id + * for different queries when using DbSelectAdapter object. + */ + public function testDbSelectAdapterLikeSuccess() + { + $select = new Sql\Select('table1'); + $select->where('id = 1'); + $select->where('nick = \'test\''); + $paginator = new Paginator\Paginator( + new TestAsset\TestDbSelectAdapter( + $select, + new DbAdapter\Adapter( + new DbAdapter\Driver\Pdo\Pdo( + new DbAdapter\Driver\Pdo\Connection([]) + ) + ) + ) + ); + + $reflectionGetCacheInternalId = new ReflectionMethod($paginator, '_getCacheInternalId'); + $reflectionGetCacheInternalId->setAccessible(true); + $firstOutputGetCacheInternalId = $reflectionGetCacheInternalId->invoke($paginator); + $this->assertCount(10, $paginator->getCurrentItems()); + $this->assertInstanceOf('ArrayObject', $paginator->getCurrentItems()); + + $select = new Sql\Select('table2'); + $select->where('id = 2'); + $select->where('nick = \'test\''); + $paginator = new Paginator\Paginator( + new TestAsset\TestDbSelectAdapter( + $select, + new DbAdapter\Adapter( + new DbAdapter\Driver\Pdo\Pdo( + new DbAdapter\Driver\Pdo\Connection([]) + ) + ) + ) + ); + $reflectionGetCacheInternalId = new ReflectionMethod($paginator, '_getCacheInternalId'); + $reflectionGetCacheInternalId->setAccessible(true); + $secondOutputGetCacheInternalId = $reflectionGetCacheInternalId->invoke($paginator); + + $this->assertInstanceOf('ArrayObject', $paginator->getCurrentItems()); + $this->assertCount(10, $paginator->getCurrentItems()); + + $this->assertNotEquals($firstOutputGetCacheInternalId, $secondOutputGetCacheInternalId); + } + /** * @group 6808 * @group 6809 diff --git a/test/TestAsset/TestAdapter.php b/test/TestAsset/TestAdapter.php index 95065e3..68bb39d 100644 --- a/test/TestAsset/TestAdapter.php +++ b/test/TestAsset/TestAdapter.php @@ -30,4 +30,14 @@ public function getItems($pageNumber, $itemCountPerPage) { return new \ArrayObject(range(1, 10)); } + + /** + * Returns the internal cache id + * + * @return string + */ + public function getCacheInternalId() + { + return json_encode($this); + } } diff --git a/test/TestAsset/TestDbSelectAdapter.php b/test/TestAsset/TestDbSelectAdapter.php new file mode 100644 index 0000000..b82a9bd --- /dev/null +++ b/test/TestAsset/TestDbSelectAdapter.php @@ -0,0 +1,23 @@ +