Voila la demande : faire en sorte que toutes les pages de la pagination affichent toujours le même nombre de résultats. S’il manque des données, alors il faut allez chercher des données archivés, expirés, outdatés … Un exemple sera plus parlant : parmi vos données, vous avez 4 annonces en cours de validité et une dizaine expirés. Avec une pagination réglée à 3 vous aurez deux pages de pagination : 1 qui présente 3 annonces valides puis 1 autre qui offre 1 annonce valide et 2 expirés.
Pour traiter ce problème, j’ai surclassé sfDoctrinePager en sfDoctrineFulfilledPager pour prendre en compte un autre paramètre qui est la requête complémentaire : celle qu’il faudra exécuter pour compléter les résultat.
Et pour la faire luxe, je l’ai rendu compatible avec sa parente. De sorte que si l’on n’entre pas ce paramètre supplémentaire, le résultat sera le même qu’avec sfDoctrinePager. Un point d’amélioration : éviter les cas où la même données pourrait être ressortir dans les deux requêtes.
C’est une demande client que j’ai bien aimé.
Voici ce que cela donne dans sfDoctrineFulfilledPager.class.php :
<?php /** * sfDoctrine (completed with extra data) pager class. * * @author vibby <vincent.beauvivre@gmail.com--> * @version 0 */ class sfDoctrineFulfilledPager extends sfDoctrinePager { protected $queryComplement = null; public function init() { $this->resetIterator(); $totalCount = $this->getCountQuery()->count(); if ($this->getQueryComplement()) $totalCount = $totalCount + $this->getCountComplement(); $this->setNbResults($totalCount); $query = $this->getQuery(); $query ->offset(0) ->limit(0) ; if ($this->getQueryComplement()) { $queryComplement = $this->getQueryComplement(); $queryComplement ->offset(0) ->limit(0) ; } if (0 == $this->getPage() || 0 == $this->getMaxPerPage() || 0 == $this->getNbResults()) { $this->setLastPage(0); } else { $offset = ($this->getPage() - 1) * $this->getMaxPerPage(); $this->setLastPage(ceil($this->getNbResults() / $this->getMaxPerPage())); $query ->offset($offset) ->limit($this->getMaxPerPage()) ; if ($this->getQueryComplement() && $this->getPage() == $this->getLastPage()) { $queryComplement ->limit($this->getQueryComplementLimit()) ; } } } protected function retrieveObject($offset) { if ($offset <= $this->countQuery) { $queryForRetrieve = clone $this->getQuery(); } else { $queryForRetrieve = clone $this->getQueryComplement(); $offset = $offset - $this->countQuery; } $queryForRetrieve ->offset($offset - 1) ->limit(1) ; $results = $queryForRetrieve->execute(); return $results[0]; } public function getQueryComplementLimit() { $val = ($this->getMaxPerPage() - ($this->getCountQuery()->count() % $this->getMaxPerPage())); return $val; } public function getCountComplement() { $query = clone $this->getQueryComplement(); $query ->offset(0) ->limit($this->getQueryComplementLimit()) ->count() ; return min($query->count(),$this->getQueryComplementLimit());; } public function setQueryComplement($query) { $this->queryComplement = $query; } public function getQueryComplement() { return $this->queryComplement->limit($this->getQueryComplementLimit()); } public function getResults($hydrationMode = null) { $objects = $this->getQuery()->execute(array(), $hydrationMode); if ($this->getQueryComplement() && $this->getPage() == $this->getLastPage()) { $objects->merge($this->getQueryComplement()->execute(array(), $hydrationMode)); } return $objects; } }
Et voici le code a ajouter dans le controlleur :
$this->pager = new sfDoctrineFulfilledPager( 'JobeetJob', sfConfig::get('app_jobs_per_page') ); $this->pager->setQuery(Doctrine::getTable('JobeetJob')->getActiveJobsQuery()); $this->pager->setQueryComplement(Doctrine::getTable('JobeetJob')->getUnactiveJobQuery()); $this->pager->setPage($request->getParameter('page', 1)); $this->pager->init();
Je vous laisse le soin de faire votre propre « getUnactiveJobQuery »
Attention : cette classe n’a pas été testée dans tous les sens, il n’est donc pas exclu que certains cas limites ne fonctionnent pas.
besoin de verifier:)
Vérifier … quoi ?