Dans la continuité, voici comment gérer la pagination à partir de plusieurs requêtes DQL :
A créer dans un fichier sfMultiDoctrinePager.class.php, et à placer qque part dans votre lib
<?php /** * dualTableDoctrinePager * a pager for combining the results of multiple tables * * @author vibby */ class sfMultiDoctrinePager extends sfDoctrinePager { protected $queries = null; public function setQueries($queries) { $pagerQueries = array(); foreach($queries as $key => $query) { $pagerQueries[$key]['query'] = $query; $pagerQueries[$key]['active'] = true; } $this->queries = $pagerQueries; } public function getCountQueries() { $queries = array(); foreach($this->queries as $key => $query) { $queries[$key]['query'] = clone $query['query']; $queries[$key]['query'] ->offset(0) ->limit(0); } return $queries; } public function init() { $this->results = null; $countQueries = $this->getCountQueries(); $count = 0; $counts = array(); // remebering counts for each table foreach($countQueries as $countQuery) { $currentCount = $countQuery['query']->count(); $counts[] = $currentCount; $count += $currentCount; } $this->setNbResults($count); // reseting queries foreach($this->queries as &$query) { $query['query'] ->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())); //For every query $iQuery = -1; $totalCount = 0; foreach($this->queries as $key => &$query) { $iQuery ++; //Is this query a part of the wanted ? echo $counts[$iQuery].' + '.$totalCount.' <= '.$offset.'<br />'; echo $totalCount.' > '.$offset.' + '.$this->getMaxPerPage().'<br />'; if ( ($counts[$iQuery] + $totalCount <= $offset) || ($totalCount >= ($offset + $this->getMaxPerPage())) ) { $query['active'] = false; } else { echo ($offset - $totalCount + 1).' et limite : '.($offset + $this->getMaxPerPage() - $totalCount); $query['active'] = true; $query['query'] ->offset(max(0,$offset - $totalCount)) ->limit($offset + $this->getMaxPerPage() - $totalCount); } $totalCount += $counts[$iQuery]; } } } public function getResults($hydrationMode = null) { $results = array(); foreach($this->queries as $key => $query) { if($query['active']) { $results[] = $query['query']->execute(array(), $hydrationMode); } else { $results[] = array(); } } return $results; } }
Et cela s’appelle comme cela depuis le controller :
$queries[] = Doctrine::getTable('myTable')->anyQueryCreation(); $queries[] = Doctrine::getTable('myOtherTable')->anyQueryCreation(); $queries[] = Doctrine::getTable('myYetAnotherTable')->anyQueryCreation(); $this->pager= new sfMultiDoctrinePager( 'consuleadsAccount', sfConfig::get('app_directory_count_default') ); $this->pager->setQueries($queries); // $this->pager->setQueries($queries2); $this->pager->setPage($request->getParameter('page',1)); // $this->pager->setQueries($queries2); $this->pager->init();
Enjoy