forked from sonata-project/SonataAdminBundle
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request sonata-project#2656 from pulzarraider/simplepager
Added SimplePager from SonataDoctrinePhpcrAdminBundle
- Loading branch information
Showing
37 changed files
with
583 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Sonata package. | ||
* | ||
* (c) Thomas Rabaix <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Sonata\AdminBundle\Datagrid; | ||
|
||
use Doctrine\ORM\QueryBuilder; | ||
use Doctrine\Common\Collections\ArrayCollection; | ||
|
||
/** | ||
* Simple pager | ||
* | ||
* @author Lukas Kahwe Smith <[email protected]> | ||
* @author Sjoerd Peters <[email protected]> | ||
*/ | ||
class SimplePager extends Pager | ||
{ | ||
/** | ||
* @var boolean | ||
*/ | ||
protected $haveToPaginate; | ||
|
||
/** | ||
* How many pages to look forward to create links to next pages. | ||
* | ||
* @var int | ||
*/ | ||
protected $threshold; | ||
|
||
/** | ||
* @var int | ||
*/ | ||
protected $thresholdCount; | ||
|
||
/** | ||
* The threshold parameter can be used to determine how far ahead the pager | ||
* should fetch results. | ||
* | ||
* If set to 1 which is the minimal value the pager will generate a link to the next page | ||
* If set to 2 the pager will generate links to the next two pages | ||
* If set to 3 the pager will generate links to the next three pages | ||
* etc. | ||
* | ||
* @param integer $maxPerPage Number of records to display per page | ||
* @param int $threshold | ||
*/ | ||
public function __construct($maxPerPage = 10, $threshold = 1) | ||
{ | ||
parent::__construct($maxPerPage); | ||
$this->setThreshold($threshold); | ||
} | ||
|
||
/** | ||
* Returns the exact count when there is only one page or when the current | ||
* equals the last page. | ||
* | ||
* In all other cases an estimate of the total count is returned. | ||
* | ||
* @return integer | ||
*/ | ||
public function getNbResults() | ||
{ | ||
$n = ceil(($this->getLastPage() -1) * $this->getMaxPerPage()); | ||
if ($this->getLastPage() == $this->getPage()) { | ||
return $n + $this->thresholdCount; | ||
} | ||
|
||
return $n; | ||
} | ||
|
||
/** | ||
* Get all the results for the pager instance | ||
* | ||
* @param mixed $hydrationMode A hydration mode identifier | ||
* | ||
* @return array | ||
*/ | ||
public function getResults($hydrationMode = null) | ||
{ | ||
if ($this->results) { | ||
return $this->results; | ||
} | ||
|
||
$this->results = $this->getQuery()->execute(array(), $hydrationMode); | ||
$this->thresholdCount = count($this->results); | ||
if (count($this->results) > $this->getMaxPerPage()) { | ||
$this->haveToPaginate = true; | ||
|
||
if ($this->results instanceof ArrayCollection) { | ||
$this->results = new ArrayCollection($this->results->slice(0, $this->getMaxPerPage())); | ||
} else { | ||
$this->results = new ArrayCollection(array_slice($this->results, 0, $this->getMaxPerPage())); | ||
} | ||
|
||
} else { | ||
$this->haveToPaginate = false; | ||
} | ||
|
||
return $this->results; | ||
} | ||
|
||
/** | ||
* {@inheritDoc} | ||
*/ | ||
public function haveToPaginate() | ||
{ | ||
return $this->haveToPaginate || $this->getPage() > 1; | ||
} | ||
|
||
/** | ||
* {@inheritDoc} | ||
*/ | ||
protected function resetIterator() | ||
{ | ||
parent::resetIterator(); | ||
$this->haveToPaginate = false; | ||
} | ||
|
||
/** | ||
* {@inheritDoc} | ||
* | ||
* @throws \RuntimeException the QueryBuilder is uninitialized. | ||
*/ | ||
public function init() | ||
{ | ||
if (!$this->getQuery()) { | ||
throw new \RuntimeException('Uninitialized QueryBuilder'); | ||
} | ||
$this->resetIterator(); | ||
|
||
if (0 == $this->getPage() || 0 == $this->getMaxPerPage()) { | ||
$this->setLastPage(0); | ||
$this->getQuery()->setFirstResult(0); | ||
$this->getQuery()->setMaxResults(0); | ||
} else { | ||
$offset = ($this->getPage() - 1) * $this->getMaxPerPage(); | ||
$this->getQuery()->setFirstResult($offset); | ||
|
||
$maxOffset = $this->getThreshold() > 0 | ||
? $this->getMaxPerPage() * $this->threshold + 1 : $this->getMaxPerPage() + 1; | ||
|
||
$this->getQuery()->setMaxResults($maxOffset); | ||
$this->initializeIterator(); | ||
|
||
$t = (int) ceil($this->thresholdCount / $this->getMaxPerPage()) + $this->getPage() - 1; | ||
$this->setLastPage($t); | ||
} | ||
} | ||
|
||
/** | ||
* Set how many pages to look forward to create links to next pages. | ||
* | ||
* @param int $threshold | ||
*/ | ||
public function setThreshold($threshold) | ||
{ | ||
$this->threshold = (int) $threshold; | ||
} | ||
|
||
/** | ||
* @return int | ||
*/ | ||
public function getThreshold() | ||
{ | ||
return $this->threshold; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
52 changes: 52 additions & 0 deletions
52
Resources/doc/cookbook/recipe_improve_performance_large_datasets.rst
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
Improve performance of large datasets | ||
===================================== | ||
|
||
If your database table contains thousands of records, the database queries generated | ||
by SonataAdmin may become very slow. Here are tips how to improve the performance of your admin. | ||
|
||
|
||
Change default Pager to SimplePager | ||
------------------------------------- | ||
|
||
Default `Pager` is counting all rows in the table, so user can easily navigate | ||
to any page in the Datagrid. But counting thousands or milions of records | ||
can be slow operation. If you don't need to know the number of all records, | ||
you can use `SimplePager` instead. It doesn't count all rows, but gives user only | ||
information if there is next page or not. | ||
|
||
To use SimplePager in your admin just define `pager_type` inside the service definition: | ||
|
||
.. configuration-block:: | ||
|
||
.. code-block:: xml | ||
<!-- Acme/DemoBundle/Resources/config/admin.xml --> | ||
<container xmlns="http://symfony.com/schema/dic/services" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://symfony.com/schema/dic/services/services-1.0.xsd"> | ||
<services> | ||
<service id="sonata.admin.post" class="Acme\DemoBundle\Admin\PostAdmin"> | ||
<tag name="sonata.admin" manager_type="orm" group="Content" label="Post" pager_type="simple" /> | ||
<argument /> | ||
<argument>Acme\DemoBundle\Entity\Post</argument> | ||
<argument /> | ||
</service> | ||
</services> | ||
</container> | ||
.. code-block:: yaml | ||
# Acme/DemoBundle/Resources/config/admin.yml | ||
services: | ||
sonata.admin.post: | ||
class: Acme\DemoBundle\Admin\PostAdmin | ||
tags: | ||
- { name: sonata.admin, manager_type: orm, group: "Content", label: "Post", pager_type: "simple" } | ||
arguments: | ||
- ~ | ||
- Acme\DemoBundle\Entity\Post | ||
- ~ | ||
.. note:: The `pager_results` template is automatically changed to `SonataAdminBundle:Pager:simple_pager_results.html.twig` if it's not already overloaded. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.