Subversion Repositories Applications.papyrus

Rev

Rev 1372 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1173 jp_milcent 1
<?php
2
//
3
//  Pear DB Pager - Retrieve and return information of databases
4
//                  result sets
5
//
6
//  Copyright (C) 2001  Tomas Von Veschler Cox <cox@idecnet.com>
7
//
8
//  This library is free software; you can redistribute it and/or
9
//  modify it under the terms of the GNU Lesser General Public
10
//  License as published by the Free Software Foundation; either
11
//  version 2.1 of the License, or (at your option) any later version.
12
//
13
//  This library is distributed in the hope that it will be useful,
14
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
15
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
//  Lesser General Public License for more details.
17
//
18
//  You should have received a copy of the GNU Lesser General Public
19
//  License along with this library; if not, write to the Free Software
20
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
21
//
22
//
23
// $Id: Pager.php,v 1.1 2006-12-14 15:04:28 jp_milcent Exp $
24
 
25
require_once 'PEAR.php';
26
require_once 'DB.php';
27
 
28
/**
29
* This class handles all the stuff needed for displaying paginated results
30
* from a database query of Pear DB, in a very easy way.
31
* Documentation and examples of use, can be found in:
32
* http://vulcanonet.com/soft/pager/ (could be outdated)
33
*
34
* IMPORTANT!
35
* Since PEAR DB already support native row limit (more fast and avaible in
36
* all the drivers), there is no more need to use $pager->build() or
37
* the $pager->fetch*() methods.
38
*
39
* Usage example:
40
*
41
*< ?php
42
* require_once 'DB/Pager.php';
43
* $db = DB::connect('your DSN string');
44
* $from = 0;   // The row to start to fetch from (you might want to get this
45
*              // param from the $_GET array
46
* $limit = 10; // The number of results per page
47
* $maxpages = 10; // The number of pages for displaying in the pager (optional)
48
* $res = $db->limitQuery($sql, $from, $limit);
49
* $nrows = 0; // Alternative you could use $res->numRows()
50
* while ($row = $res->fetchrow()) {
51
*    // XXX code for building the page here
52
*     $nrows++;
53
* }
54
* $data = DB_Pager::getData($from, $limit, $nrows, $maxpages);
55
* // XXX code for building the pager here
56
* ? >
57
*
58
* @version 0.7
59
* @author Tomas V.V.Cox <cox@idecnet.com>
60
* @see http://vulcanonet.com/soft/pager/
61
*/
62
 
63
class DB_Pager extends PEAR
64
{
65
 
66
    /**
67
    * Constructor
68
    *
69
    * @param object $res  A DB_result object from Pear_DB
70
    * @param int    $from  The row to start fetching
71
    * @param int    $limit  How many results per page
72
    * @param int    $numrows Pager will automatically
73
    *    find this param if is not given. If your Pear_DB backend extension
74
    *    doesn't support numrows(), you can manually calculate it
75
    *    and supply later to the constructor
76
    * @deprecated
77
    */
78
    function DB_Pager (&$res, $from, $limit, $numrows = null)
79
    {
80
        $this->res = $res;
81
        $this->from = $from;
82
        $this->limit = $limit;
83
        $this->numrows = $numrows;
84
    }
85
 
86
    /**
87
    * Calculates all the data needed by Pager to work
88
    *
89
    * @return mixed An assoc array with all the data (see getData)
90
    *    or DB_Error on error
91
    * @see DB_Pager::getData
92
    * @deprecated
93
    */
94
    function build()
95
    {
96
        // if there is no numrows given, calculate it
97
        if ($this->numrows === null) {
98
            $this->numrows = $this->res->numrows();
99
            if (DB::isError($this->numrows)) {
100
                return $this->numrows;
101
            }
102
        }
103
        $data = $this->getData($this->from, $this->limit, $this->numrows);
104
        if (DB::isError($data)) {
105
            return $data;
106
        }
107
        $this->current = $this->from - 1;
108
        $this->top = $data['to'];
109
        return $data;
110
    }
111
 
112
    /**
113
    * @deprecated
114
    */
115
    function fetchRow($mode=DB_FETCHMODE_DEFAULT)
116
    {
117
        $this->current++;
118
        if ($this->current >= $this->top) {
119
            return null;
120
        }
121
        return $this->res->fetchRow($mode, $this->current);
122
    }
123
 
124
    /**
125
    * @deprecated
126
    */
127
    function fetchInto(&$arr, $mode=DB_FETCHMODE_DEFAULT)
128
    {
129
        $this->current++;
130
        if ($this->current >= $this->top) {
131
            return null;
132
        }
133
        return $this->res->fetchInto($arr, $mode, $this->current);
134
    }
135
 
136
    /*
137
    * Gets all the data needed to paginate results
138
    * This is an associative array with the following
139
    * values filled in:
140
    *
141
    * array(
142
    *    'current' => X,    // current page you are
143
    *    'numrows' => X,    // total number of results
144
    *    'next'    => X,    // row number where next page starts
145
    *    'prev'    => X,    // row number where prev page starts
146
    *    'remain'  => X,    // number of results remaning *in next page*
147
    *    'numpages'=> X,    // total number of pages
148
    *    'from'    => X,    // the row to start fetching
149
    *    'to'      => X,    // the row to stop fetching
150
    *    'limit'   => X,    // how many results per page
151
    *    'maxpages'   => X, // how many pages to show (google style)
152
    *    'firstpage'  => X, // the row number of the first page
153
    *    'lastpage'   => X, // the row number where the last page starts
154
    *    'pages'   => array(    // assoc with page "number => start row"
155
    *                1 => X,
156
    *                2 => X,
157
    *                3 => X
158
    *                )
159
    *    );
160
    * @param int $from    The row to start fetching
161
    * @param int $limit   How many results per page
162
    * @param int $numrows Number of results from query
163
    *
164
    * @return array associative array with data or DB_error on error
165
    *
166
    */
167
    function &getData($from, $limit, $numrows, $maxpages = false)
168
    {
169
        if (empty($numrows) || ($numrows < 0)) {
170
            return null;
171
        }
172
        $from = (empty($from)) ? 0 : $from;
173
 
174
        if ($limit <= 0) {
175
            return PEAR::raiseError (null, 'wrong "limit" param', null,
176
                                     null, null, 'DB_Error', true);
177
        }
178
 
179
        // Total number of pages
180
        $pages = ceil($numrows/$limit);
181
        $data['numpages'] = $pages;
182
 
183
        // first & last page
184
        $data['firstpage'] = 1;
185
        $data['lastpage']  = $pages;
186
 
187
        // Build pages array
188
        $data['pages'] = array();
189
        for ($i=1; $i <= $pages; $i++) {
190
            $offset = $limit * ($i-1);
191
            $data['pages'][$i] = $offset;
192
            // $from must point to one page
193
            if ($from == $offset) {
194
                // The current page we are
195
                $data['current'] = $i;
196
            }
197
        }
198
        if (!isset($data['current'])) {
199
            return PEAR::raiseError (null, 'wrong "from" param', null,
200
                                     null, null, 'DB_Error', true);
201
        }
202
 
203
        // Limit number of pages (goole algoritm)
204
        if ($maxpages) {
205
            $radio = floor($maxpages/2);
206
            $minpage = $data['current'] - $radio;
207
            if ($minpage < 1) {
208
                $minpage = 1;
209
            }
210
            $maxpage = $data['current'] + $radio - 1;
211
            if ($maxpage > $data['numpages']) {
212
                $maxpage = $data['numpages'];
213
            }
214
            foreach (range($minpage, $maxpage) as $page) {
215
                $tmp[$page] = $data['pages'][$page];
216
            }
217
            $data['pages'] = $tmp;
218
            $data['maxpages'] = $maxpages;
219
        } else {
220
            $data['maxpages'] = null;
221
        }
222
 
223
        // Prev link
224
        $prev = $from - $limit;
225
        $data['prev'] = ($prev >= 0) ? $prev : null;
226
 
227
        // Next link
228
        $next = $from + $limit;
229
        $data['next'] = ($next < $numrows) ? $next : null;
230
 
231
        // Results remaining in next page & Last row to fetch
232
        if ($data['current'] == $pages) {
233
            $data['remain'] = 0;
234
            $data['to'] = $numrows;
235
        } else {
236
            if ($data['current'] == ($pages - 1)) {
237
                $data['remain'] = $numrows - ($limit*($pages-1));
238
            } else {
239
                $data['remain'] = $limit;
240
            }
241
            $data['to'] = $data['current'] * $limit;
242
        }
243
        $data['numrows'] = $numrows;
244
        $data['from']    = $from + 1;
245
        $data['limit']   = $limit;
246
 
247
        return $data;
248
    }
249
}
250
?>