From: Leandro Lucarella Date: Fri, 10 Oct 2003 22:53:26 +0000 (+0000) Subject: Se agrega un DB_Pager mas bonito que el de PEAR. X-Git-Tag: svn_import~238 X-Git-Url: https://git.llucax.com/mecon/meconlib.git/commitdiff_plain/1c68d1cde4a65ad065aad845d5672dd601ae5815?ds=sidebyside;hp=0f5f0ce75b4bdb8a5998dea97c032c40a5dc1859 Se agrega un DB_Pager mas bonito que el de PEAR. --- diff --git a/lib/MECON/DB/Pager.php b/lib/MECON/DB/Pager.php new file mode 100644 index 0000000..db801af --- /dev/null +++ b/lib/MECON/DB/Pager.php @@ -0,0 +1,221 @@ + +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// +// $Id$ + +require_once 'PEAR.php'; +require_once 'DB.php'; + +/** +* This class handles all the stuff needed for displaying paginated results +* from a database query of Pear DB, in a very easy way. +* Documentation and examples of use, can be found in: +* http://vulcanonet.com/soft/pager/ (could be outdated) +* +* IMPORTANT! +* Since PEAR DB already support native row limit (more fast and avaible in +* all the drivers), there is no more need to use $pager->build() or +* the $pager->fetch*() methods. +* +* Usage example: +* +*< ?php +* require_once 'DB/Pager.php'; +* $db = DB::connect('your DSN string'); +* $from = 0; // The row to start to fetch from (you might want to get this +* // param from the $_GET array +* $limit = 10; // The number of results per page +* $maxpages = 10; // The number of pages for displaying in the pager (optional) +* $res = $db->limitQuery($sql, $from, $limit); +* $nrows = 0; // Alternative you could use $res->numRows() +* while ($row = $res->fetchrow()) { +* // XXX code for building the page here +* $nrows++; +* } +* $data = DB_Pager::getData($from, $limit, $nrows, $maxpages); +* // XXX code for building the pager here +* ? > +* +* @version 0.7 +* @author Tomas V.V.Cox +* @see http://vulcanonet.com/soft/pager/ +*/ + +class MECON_DB_Pager extends PEAR +{ + + /** + * Constructor + * + * Gets all the data needed to paginate results + * The object has this properties: + * + * 'current' => X, // current page you are + * 'numrows' => X, // total number of results + * 'next' => X, // row number where next page starts + * 'prev' => X, // row number where prev page starts + * 'remain' => X, // number of results remaning *in next page* + * 'numpages'=> X, // total number of pages + * 'from' => X, // the row to start fetching + * 'to' => X, // the row to stop fetching + * 'limit' => X, // how many results per page + * 'maxpages' => X, // how many pages to show (google style) + * 'firstpage' => X, // the row number of the first page + * 'lastpage' => X, // the row number where the last page starts + * 'pages' => array( // assoc with page "number => start row" + * 1 => X, + * 2 => X, + * 3 => X + * ) + * ); + + * @param object $res A DB_result object from Pear_DB + * @param int $from The row to start fetching + * @param int $limit How many results per page + * @param int $maxpages Maximum pages to display + * @param int $numrows Pager will automatically + * find this param if is not given. If your Pear_DB backend extension + * doesn't support numrows(), you can manually calculate it + * and supply later to the constructor + * @deprecated + */ + function MECON_DB_Pager (&$res, $from = 0, $limit = 10, $maxpages = 21, $numrows = null) + { + $this->res = $res; + $this->from = $from; + $this->limit = $limit; + $this->numrows = $numrows; + $this->maxpages = $maxpages; + $this->build(); + } + + /** + * Calculates all the data needed by Pager to work + * @return mixed PEAR_Error if error. + */ + function build() + { + // if there is no numrows given, calculate it + if ($this->numrows === null) { + $this->numrows = $this->res->numrows(); + if (DB::isError($this->numrows)) { + return $this->numrows; + } + } + // Si no hay resultados no se hace nada. + if (empty($this->numrows) or ($this->numrows < 0)) { + return; + } + $this->from = empty($this->from) ? 0 : $this->from; + + if ($this->limit <= 0) { + return PEAR::raiseError (null, 'wrong "limit" param', null, + null, null, 'DB_Error', true); + } + + // Total number of pages + $this->numpages = ceil($this->numrows/$this->limit); + + // first & last page + $this->firstpage = 1; + $this->lastpage = $this->numpages; + + // Build pages array + $this->pages = array(); + for ($i = 1; $i <= $this->numpages; $i++) { + $offset = $this->limit * ($i - 1); + $this->pages[$i] = $offset; + // $from must point to one page + if ($this->from == $offset) { + // The current page we are + $this->currentpage = $i; + } + } + if (!isset($this->currentpage)) { + return PEAR::raiseError (null, 'wrong "from" param', null, + null, null, 'DB_Error', true); + } + + // Limit number of pages (goole algoritm) + if ($this->maxpages) { + $radio = floor($this->maxpages/2); + $this->firstpage = $this->currentpage - $radio; + if (!($this->maxpages % 2)) { + $this->firstpage++; + } + if ($this->firstpage < 1) { + $this->firstpage = 1; + } + $this->lastpage = $this->currentpage + $radio; + if ($this->lastpage > $this->numpages) { + $this->lastpage = $this->numpages; + } + foreach (range($this->firstpage, $this->lastpage) as $page) { + $tmp[$page] = $this->pages[$page]; + } + $this->pages = $tmp; + } + + // Prev link + $this->prev = $this->from - $this->limit; + $this->prev = ($this->prev >= 0) ? $this->prev : null; + + // Next link + $this->next = $this->from + $this->limit; + $this->next = ($this->next < $this->numrows) ? $this->next : null; + + // Results remaining in next page & Last row to fetch + if ($this->currentpage == $this->numpages) { + $this->remain = 0; + $this->to = $this->numrows; + } else { + if ($this->currentpage == ($this->numpages - 1)) { + $this->remain = $this->numrows - ($this->limit * ($this->numpages - 1)); + } else { + $this->remain = $this->limit; + } + $this->to = $this->currentpage * $this->limit; + } + + // Current item (when fetching). + $this->current = $this->from - 1; + } + + function fetchRow($mode=DB_FETCHMODE_DEFAULT) + { + $this->current++; + if ($this->current >= $this->to) { + return null; + } + return $this->res->fetchRow($mode, $this->current); + } + + function fetchInto(&$arr, $mode=DB_FETCHMODE_DEFAULT) + { + $this->current++; + if ($this->current >= $this->to) { + return null; + } + return $this->res->fetchInto($arr, $mode, $this->current); + } +} +?>