[symfony][propel][mysql] symfony 1.2 の sfPropelPager で MySQL 行カウント SQL_CALC_FOUND_ROWS を使う
http://ossipedia.ipa.go.jp/capacity/EV0603280115/
<?php $c = new Criteria(); $c->addDescendingOrderByColumn(ArticlePeer::CREATED_AT); $pager = new myPropelPager('Article', 10); $pager->setCriteria($c); $pager->setPage($page); //$pager->init(); // COUNT $pager->initFoundRows(); // SQL_CALC_FOUND_ROWS
<?php class myPropelPager extends sfPropelPager { protected $results; public function initFoundRows() { $hasMaxRecordLimit = ($this->getMaxRecordLimit() !== false); $maxRecordLimit = $this->getMaxRecordLimit(); $c1 = $this->getCriteria(); if ($c1 instanceof myCriteria) { $c = $c1; } else { $c = new myCriteria(); $c->fromCriteria($c1); } $c->addSelectModifier(myCriteria::SQL_CALC_FOUND_ROWS)-> setOffset(0)-> setLimit(0); $offset = ($this->getPage() - 1) * $this->getMaxPerPage(); $c->setOffset($offset); if ($hasMaxRecordLimit) { $maxRecordLimit = $maxRecordLimit - $offset; if ($maxRecordLimit > $this->getMaxPerPage()) { $c->setLimit($this->getMaxPerPage()); } else { $c->setLimit($maxRecordLimit); } } else { $c->setLimit($this->getMaxPerPage()); } $this->setCriteria($c); $this->results = parent::getResults(); $con = Propel::getConnection(constant($this->getClassPeer() . '::DATABASE_NAME'), Propel::CONNECTION_READ); $stmt = $con->query('SELECT FOUND_ROWS()'); $count = $stmt->fetchColumn(); $this->setNbResults($hasMaxRecordLimit ? min($count, $maxRecordLimit) : $count); if (($this->getPage() == 0 || $this->getMaxPerPage() == 0)) { $this->setLastPage(0); } else { $this->setLastPage(ceil($this->getNbResults() / $this->getMaxPerPage())); } } public function getResults() { if ($this->results === null) { $this->results = parent::getResults(); } return $this->results; } } class myCriteria extends Criteria { const SQL_CALC_FOUND_ROWS = 'SQL_CALC_FOUND_ROWS'; protected $_selectModifiers = array(); public function addSelectModifier($modifier) { $this->_selectModifiers[] = $modifier; } public function getSelectModifiers() { return array_merge(parent::getSelectModifiers(), $this->_selectModifiers); } public function clear() { $this->_selectModifiers = array(); parent::clear(); } public function fromCriteria(Criteria $c) { array_map(array($this, 'addSelectColumn'), $c->getSelectColumns()); array_map(array($this, 'addGroupByColumn'), $c->getGroupByColumns()); array_map(array($this, 'add'), $c->getMap()); foreach ($c->getAsColumns() as $name => $clause) { $this->addAsColumn($name, $clause); } foreach ($c->getJoins() as $join) { $this->addJoin($join->getLeftColumns(), $join->getRightColumns(), $join->getJoinType()); } foreach ($c->getSelectModifiers() as $selectModifier) { switch ($selectModifier) { case Criteria::DISTINCT: $this->setDistinct(); break; case Criteria::ALL: $this->setAll(); break; } } foreach ($c->getOrderByColumns() as $column) { list($name, $order) = explode(' ', $column); switch ($order) { case Criteria::ASC: $this->addAscendingOrderByColumn($name); break; case Criteria::DESC: $this->addDescendingOrderByColumn($name); break; } } if ($having = $c->getHaving()) { $this->addHaving($having); } // TODO addAlias $this->setUseTransaction($c->isUseTransaction()); $this->setDbName($c->getDbName()); $this-> setIgnoreCase($c->isIgnoreCase())-> setSingleRecord($c->isSingleRecord())-> setOffset($c->getOffset())-> setLimit($c->getLimit()); return $this; } }