]> git.llucax.com Git - mecon/meconlib.git/commitdiff
Se agrega un DB_Pager mas bonito que el de PEAR.
authorLeandro Lucarella <llucax@gmail.com>
Fri, 10 Oct 2003 22:53:26 +0000 (22:53 +0000)
committerLeandro Lucarella <llucax@gmail.com>
Fri, 10 Oct 2003 22:53:26 +0000 (22:53 +0000)
lib/MECON/DB/Pager.php [new file with mode: 0644]

diff --git a/lib/MECON/DB/Pager.php b/lib/MECON/DB/Pager.php
new file mode 100644 (file)
index 0000000..db801af
--- /dev/null
@@ -0,0 +1,221 @@
+<?php
+//
+//  Pear DB Pager - Retrieve and return information of databases
+//                  result sets
+//
+//  Copyright (C) 2001  Tomas Von Veschler Cox <cox@idecnet.com>
+//
+//  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 <cox@idecnet.com>
+* @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);
+    }
+}
+?>