Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge remote-tracking branch 'borisguery/doctrine-selectable-collecti…

…ons' into doctrine_selectable
  • Loading branch information...
commit adc4653139109daf2efda1abfa557f51226a0b42 2 parents 43feb3d + 12ef2a0
@pablodip pablodip authored
View
21 README.md
@@ -178,6 +178,27 @@ $user = $em->find("Pagerfanta\Tests\Adapter\DoctrineORM\User", 1);
$adapter = new DoctrineCollectionAdapter($user->getGroups());
```
+### DoctrineSelectableAdapter
+
+To paginate a `Doctrine\Common\Collection\Selectable` interface you can use the `DoctrineSelectableAdapter`. It uses the matching() method on the Selectable interface for pagination. This is especially usefull when using the Doctrine Criteria object to filter a PersistentCollection:
+
+```php
+<?php
+
+use Pagerfanta\Adapter\DoctrineSelectableAdapter;
+use Doctrine\Common\Collections\Criteria;
+
+$user = $em->find("Pagerfanta\Tests\Adapter\DoctrineORM\User", 1);
+$comments = $user->getComments();
+$criteria = Criteria::create()->andWhere(Criteria::expr()->in('id', array(1,2,3));
+
+$adapter = new DoctrineSelectableAdapter($comments, $criteria);
+```
+
+Note that you should never use this adapter with a PersistentCollection which is not set to use the EXTRA_LAZY fetch mode.
+
+*Be carefull when using the `count()` method, currently Doctrine2 needs to fetch all the records to count the number of elements.*
+
### PropelAdapter
To paginate a propel query:
View
73 src/Pagerfanta/Adapter/DoctrineSelectableAdapter.php
@@ -0,0 +1,73 @@
+<?php
+
+/*
+ * This file is part of the Pagerfanta package.
+ *
+ * (c) Pablo Díez <pablodip@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Pagerfanta\Adapter;
+
+use Doctrine\Common\Collections\Criteria;
+use Doctrine\Common\Collections\Selectable;
+
+/**
+ * DoctrineSelectableAdapter.
+ *
+ * @author Boris Guéry <guery.b@gmail.com>
+ *
+ * @api
+ */
+class DoctrineSelectableAdapter implements AdapterInterface
+{
+ /**
+ * @var Selectable
+ */
+ private $selectable;
+
+ /**
+ * @var Criteria
+ */
+ private $criteria;
+
+ /**
+ * Constructor.
+ *
+ * @param Selectable $selectable An implementation of the Selectable interface.
+ * @param Criteria $criteria A Doctrine criteria.
+ *
+ * @api
+ */
+ public function __construct(Selectable $selectable, Criteria $criteria = null)
+ {
+ $this->selectable = $selectable;
+ $this->criteria = ($criteria) ?: new Criteria();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getNbResults()
+ {
+ $criteria = clone $this->criteria;
+ $criteria->setFirstResult(null);
+ $criteria->setMaxResults(null);
+
+ return $this->selectable->matching($criteria)->count();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getSlice($offset, $length)
+ {
+ $criteria = clone $this->criteria;
+ $criteria->setFirstResult($offset);
+ $criteria->setMaxResults($length);
+
+ return $this->selectable->matching($this->criteria);
+ }
+}
View
92 tests/Pagerfanta/Tests/Adapter/DoctrineSelectableTest.php
@@ -0,0 +1,92 @@
+<?php
+
+namespace Pagerfanta\Tests\Adapter;
+
+use Pagerfanta\Adapter\DoctrineSelectableAdapter;
+use Doctrine\Common\Collections\Selectable;
+use Doctrine\Common\Collections\Collection;
+
+class DoctrineSelectableTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @var Collection
+ */
+ protected $collection;
+
+ /**
+ * @var Selectable
+ */
+ protected $selectable;
+
+ /**
+ * @var DoctrineSelectableAdapter
+ */
+ protected $adapter;
+
+ protected function setUp()
+ {
+ if (version_compare(\Doctrine\ORM\Version::VERSION, '2.3', '<')) {
+ $this->markTestSkipped('This test can only be run using Doctrine >= 2.3');
+ }
+
+ $this->selectable = $this
+ ->getMockBuilder('Doctrine\Common\Collections\Selectable')
+ ->disableOriginalConstructor()
+ ->getMock()
+ ;
+
+ $this->collection = $this
+ ->getMockBuilder('Doctrine\Common\Collections\Collection')
+ ->disableOriginalConstructor()
+ ->getMock()
+ ;
+
+ $this->collection
+ ->expects($this->any())
+ ->method('count')
+ ->will($this->returnValue(10))
+ ;
+
+ $this->adapter = new DoctrineSelectableAdapter($this->selectable);
+ }
+
+ public function testGetNbResults()
+ {
+ $this->selectable
+ ->expects($this->once())
+ ->method('matching')
+ ->will($this->returnValue($this->collection))
+ ;
+
+ $this->assertSame(10, $this->adapter->getNbResults());
+ }
+
+ /**
+ * @dataProvider getResultsProvider
+ */
+ public function testGetResults($offset, $limit)
+ {
+
+ $this->selectable
+ ->expects($this->once())
+ ->method('matching')
+ ->will(
+ $this->returnValue($data = array(
+ new \DateTime(),
+ new \DateTime(),
+ )
+ )
+ )
+ ;
+
+ $this->assertSame($data, $this->adapter->getSlice($offset, $limit));
+ }
+
+ public function getResultsProvider()
+ {
+ return array(
+ array(2, 10),
+ array(3, 2),
+ );
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.