From 0d9e0f11721117aa500f4aec3b9b237188fadad3 Mon Sep 17 00:00:00 2001 From: Francisco Facioni Date: Tue, 22 May 2012 10:23:51 -0300 Subject: [PATCH] Added knp paginator support Bug fix: no Feature addition: yes Backwards compatibility break: no Encapsulated Pagerfanta dependency for pagination and added support for knp pagination component --- Finder/PaginatedFinderInterface.php | 10 +++ Finder/RawFinder.php | 5 +- Finder/TransformedFinder.php | 5 +- Paginator/AbstractPaginatorAdapter.php | 54 --------------- Paginator/FantaPaginatorAdapter.php | 46 +++++++++++++ Paginator/PaginatorAdapterInterface.php | 27 ++++++++ Paginator/PartialResultsInterface.php | 32 +++++++++ Paginator/RawPaginatorAdapter.php | 65 ++++++++++++++++--- Paginator/RawPartialResults.php | 52 +++++++++++++++ Paginator/TransformedPaginatorAdapter.php | 15 ++--- Paginator/TransformedPartialResults.php | 34 ++++++++++ Resources/config/config.xml | 4 ++ .../PaginateElasticaQuerySubscriber.php | 33 ++++++++++ 13 files changed, 307 insertions(+), 75 deletions(-) delete mode 100644 Paginator/AbstractPaginatorAdapter.php create mode 100644 Paginator/FantaPaginatorAdapter.php create mode 100644 Paginator/PaginatorAdapterInterface.php create mode 100644 Paginator/PartialResultsInterface.php create mode 100644 Paginator/RawPartialResults.php create mode 100644 Paginator/TransformedPartialResults.php create mode 100644 Subscriber/PaginateElasticaQuerySubscriber.php diff --git a/Finder/PaginatedFinderInterface.php b/Finder/PaginatedFinderInterface.php index 52f0615..a764f9d 100644 --- a/Finder/PaginatedFinderInterface.php +++ b/Finder/PaginatedFinderInterface.php @@ -2,7 +2,9 @@ namespace FOQ\ElasticaBundle\Finder; +use FOQ\ElasticaBundle\Paginator\PaginatorAdapterInterface; use Pagerfanta\Pagerfanta; +use Elastica_Query; interface PaginatedFinderInterface { @@ -13,4 +15,12 @@ interface PaginatedFinderInterface * @return Pagerfanta paginated results */ function findPaginated($query); + + /** + * Creates a paginator adapter for this query + * + * @param Elastica_Query $query + * @return PaginatorAdapterInterface + */ + function createPaginatorAdapter(Elastica_Query $query); } diff --git a/Finder/RawFinder.php b/Finder/RawFinder.php index 639e199..10bac12 100644 --- a/Finder/RawFinder.php +++ b/Finder/RawFinder.php @@ -3,6 +3,7 @@ namespace FOQ\ElasticaBundle\Finder; use FOQ\ElasticaBundle\Paginator\RawPaginatorAdapter; +use FOQ\ElasticaBundle\Paginator\FantaPaginatorAdapter; use Pagerfanta\Pagerfanta; use Elastica_Searchable; use Elastica_Query; @@ -42,7 +43,7 @@ class RawFinder implements FinderInterface, PaginatedFinderInterface $queryObject = Elastica_Query::create($query); $paginatorAdapter = $this->createPaginatorAdapter($queryObject); - return new Pagerfanta($paginatorAdapter); + return new Pagerfanta(new FantaPaginatorAdapter($paginatorAdapter)); } /** @@ -51,7 +52,7 @@ class RawFinder implements FinderInterface, PaginatedFinderInterface * @param Elastica_Query $query * @return RawPaginatorAdapter */ - protected function createPaginatorAdapter(Elastica_Query $query) + public function createPaginatorAdapter(Elastica_Query $query) { return new RawPaginatorAdapter($this->searchable, $query); } diff --git a/Finder/TransformedFinder.php b/Finder/TransformedFinder.php index 00317f8..77bffad 100644 --- a/Finder/TransformedFinder.php +++ b/Finder/TransformedFinder.php @@ -6,6 +6,7 @@ use FOQ\ElasticaBundle\Finder\FinderInterface; use FOQ\ElasticaBundle\Finder\PaginatedFinderInterface; use FOQ\ElasticaBundle\Transformer\ElasticaToModelTransformerInterface; use FOQ\ElasticaBundle\Paginator\TransformedPaginatorAdapter; +use FOQ\ElasticaBundle\Paginator\FantaPaginatorAdapter; use Pagerfanta\Pagerfanta; use Elastica_Searchable; use Elastica_Query; @@ -67,7 +68,7 @@ class TransformedFinder implements FinderInterface, PaginatedFinderInterface $queryObject = Elastica_Query::create($query); $paginatorAdapter = $this->createPaginatorAdapter($queryObject); - return new Pagerfanta($paginatorAdapter); + return new Pagerfanta(new FantaPaginatorAdapter($paginatorAdapter)); } /** @@ -76,7 +77,7 @@ class TransformedFinder implements FinderInterface, PaginatedFinderInterface * @param Elastica_Query $query * @return TransformedPaginatorAdapter */ - protected function createPaginatorAdapter(Elastica_Query $query) + public function createPaginatorAdapter(Elastica_Query $query) { return new TransformedPaginatorAdapter($this->searchable, $query, $this->transformer); } diff --git a/Paginator/AbstractPaginatorAdapter.php b/Paginator/AbstractPaginatorAdapter.php deleted file mode 100644 index 94ed1ff..0000000 --- a/Paginator/AbstractPaginatorAdapter.php +++ /dev/null @@ -1,54 +0,0 @@ -searchable = $searchable; - $this->query = $query; - } - - protected function getElasticaResults($offset, $itemCountPerPage) - { - $query = clone $this->query; - $query->setFrom($offset); - $query->setLimit($itemCountPerPage); - - return $this->searchable->search($query)->getResults(); - } - - /** - * @see Pagerfanta\Adapter\AdapterInterface::getNbResults - */ - public function getNbResults() - { - return $this->searchable->count($this->query); - } -} diff --git a/Paginator/FantaPaginatorAdapter.php b/Paginator/FantaPaginatorAdapter.php new file mode 100644 index 0000000..18d47ad --- /dev/null +++ b/Paginator/FantaPaginatorAdapter.php @@ -0,0 +1,46 @@ +adapter = $adapter; + } + + /** + * Returns the number of results. + * + * @return integer The number of results. + * + * @api + */ + public function getNbResults() + { + return $this->adapter->getTotalHits(); + } + + /** + * Returns an slice of the results. + * + * @param integer $offset The offset. + * @param integer $length The length. + * + * @return array|\Traversable The slice. + * + * @api + */ + public function getSlice($offset, $length) + { + return $this->adapter->getResults($offset,$length)->toArray(); + } +} diff --git a/Paginator/PaginatorAdapterInterface.php b/Paginator/PaginatorAdapterInterface.php new file mode 100644 index 0000000..363fcd3 --- /dev/null +++ b/Paginator/PaginatorAdapterInterface.php @@ -0,0 +1,27 @@ +getElasticaResults($offset, $length); + private $searchable = null; - return array_map(function($result) { return $result->getSource(); }, $results); + /** + * @var Elastica_Query the query to search + */ + private $query = null; + + /** + * @see PaginatorAdapterInterface::__construct + * + * @param Elastica_SearchableInterface the object to search in + * @param Elastica_Query the query to search + */ + public function __construct(Elastica_Searchable $searchable, Elastica_Query $query) + { + $this->searchable = $searchable; + $this->query = $query; + } + + /** + * Returns the paginated results. + * + * @return Elastica_ResultSet + */ + protected function getElasticaResults($offset, $itemCountPerPage) + { + $query = clone $this->query; + $query->setFrom($offset); + $query->setLimit($itemCountPerPage); + + return $this->searchable->search($query); + } + + /** + * Returns the paginated results. + * + * @return FOQ\ElasticaBundle\Paginator\PartialResultInterface + */ + public function getResults($offset, $itemCountPerPage) + { + return new RawPartialResults($this->getElasticaResults($offset,$itemCountPerPage)); + } + + /** + * Returns the number of results. + * + * @return integer The number of results. + */ + public function getTotalHits() + { + return $this->searchable->count($this->query); } } diff --git a/Paginator/RawPartialResults.php b/Paginator/RawPartialResults.php new file mode 100644 index 0000000..b1136b9 --- /dev/null +++ b/Paginator/RawPartialResults.php @@ -0,0 +1,52 @@ +resultSet = $resultSet; + } + + /** + * {@inheritDoc} + */ + public function toArray() + { + return array_map(function($result) { + return $result->getSource(); + }, $this->resultSet->getResults()); + } + + /** + * {@inheritDoc} + */ + public function getTotalHits() + { + return $this->resultSet->getTotalHits(); + } + + /** + * {@inheritDoc} + */ + public function getFacets() + { + if ($this->resultSet->hasFacets()) { + return $this->resultSet->getFacets(); + } + + return null; + } +} \ No newline at end of file diff --git a/Paginator/TransformedPaginatorAdapter.php b/Paginator/TransformedPaginatorAdapter.php index 1276301..ac38248 100644 --- a/Paginator/TransformedPaginatorAdapter.php +++ b/Paginator/TransformedPaginatorAdapter.php @@ -3,17 +3,16 @@ namespace FOQ\ElasticaBundle\Paginator; use FOQ\ElasticaBundle\Transformer\ElasticaToModelTransformerInterface; +use FOQ\ElasticaBundle\Paginator\TransformedPartialResults; use Elastica_Searchable; use Elastica_Query; /** - * Implements the Pagerfanta\Adapter\AdapterInterface Interface for use with Zend\Paginator\Paginator - * * Allows pagination of Elastica_Query */ -class TransformedPaginatorAdapter extends AbstractPaginatorAdapter +class TransformedPaginatorAdapter extends RawPaginatorAdapter { - protected $transformer; + private $transformer; /** * @param Elastica_SearchableInterface the object to search in @@ -28,12 +27,10 @@ class TransformedPaginatorAdapter extends AbstractPaginatorAdapter } /** - * @see Pagerfanta\Adapter\AdapterInterface::getSlice + * {@inheritDoc} */ - public function getSlice($offset, $length) + public function getResults($offset, $length) { - $results = $this->getElasticaResults($offset, $length); - - return $this->transformer->transform($results); + return new TransformedPartialResults($this->getElasticaResults($offset,$length),$this->transformer); } } diff --git a/Paginator/TransformedPartialResults.php b/Paginator/TransformedPartialResults.php new file mode 100644 index 0000000..b4a5070 --- /dev/null +++ b/Paginator/TransformedPartialResults.php @@ -0,0 +1,34 @@ +transformer = $transformer; + } + + /** + * {@inheritDoc} + */ + public function toArray() + { + return $this->transformer->transform($this->resultSet->getResults()); + } +} \ No newline at end of file diff --git a/Resources/config/config.xml b/Resources/config/config.xml index 8a0974e..95e2bb8 100644 --- a/Resources/config/config.xml +++ b/Resources/config/config.xml @@ -68,6 +68,10 @@ + + + + diff --git a/Subscriber/PaginateElasticaQuerySubscriber.php b/Subscriber/PaginateElasticaQuerySubscriber.php new file mode 100644 index 0000000..2f043ef --- /dev/null +++ b/Subscriber/PaginateElasticaQuerySubscriber.php @@ -0,0 +1,33 @@ +target instanceof PaginatorAdapterInterface) { + $results = $event->target->getResults($event->getOffset(), $event->getLimit()); + + $event->count = $results->getTotalHits(); + $event->items = $results->toArray(); + $facets = $results->getFacets(); + if (null != $facets) { + $event->setCustomPaginationParameter('facets', $facets); + } + + $event->stopPropagation(); + } + } + + public static function getSubscribedEvents() + { + return array( + 'knp_pager.items' => array('items', 1) + ); + } +} \ No newline at end of file