Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
// CVS: $Id: Pager_Wrapper.php,v 1.23 2006/12/12 17:25:50 quipo Exp $
3
//
4
// Pager_Wrapper
5
// -------------
6
//
7
// Ready-to-use wrappers for paging the result of a query,
8
// when fetching the whole resultset is NOT an option.
9
// This is a performance- and memory-savvy method
10
// to use PEAR::Pager with a database.
11
// With this approach, the network load can be
12
// consistently smaller than with PEAR::DB_Pager.
13
//
14
// The following wrappers are provided: one for each PEAR
15
// db abstraction layer (DB, MDB and MDB2), one for
16
// PEAR::DB_DataObject, and one for the PHP Eclipse library
17
//
18
//
19
// SAMPLE USAGE
20
// ------------
21
//
22
// $query = 'SELECT this, that FROM mytable';
23
// require_once 'Pager_Wrapper.php'; //this file
24
// $pagerOptions = array(
25
//     'mode'    => 'Sliding',
26
//     'delta'   => 2,
27
//     'perPage' => 15,
28
// );
29
// $paged_data = Pager_Wrapper_MDB2($db, $query, $pagerOptions);
30
// //$paged_data['data'];  //paged data
31
// //$paged_data['links']; //xhtml links for page navigation
32
// //$paged_data['page_numbers']; //array('current', 'total');
33
//
34
 
35
/**
36
 * Helper method - Rewrite the query into a "SELECT COUNT(*)" query.
37
 * @param string $sql query
38
 * @return string rewritten query OR false if the query can't be rewritten
39
 * @access private
40
 */
41
function rewriteCountQuery($sql)
42
{
43
    if (preg_match('/^\s*SELECT\s+\bDISTINCT\b/is', $sql) ||
44
        preg_match('/\s+GROUP\s+BY\s+/is', $sql) ||
45
        preg_match('/\s+UNION\s+/is', $sql)) {
46
        return false;
47
    }
48
    $open_parenthesis = '(?:\()';
49
    $close_parenthesis = '(?:\))';
50
    $subquery_in_select = $open_parenthesis.'.*\bFROM\b.*'.$close_parenthesis;
51
    $pattern = '/(?:.*'.$subquery_in_select.'.*)\bFROM\b\s+/Uims';
52
    if (preg_match($pattern, $sql)) {
53
        return false;
54
    }
55
    $subquery_with_limit_order = $open_parenthesis.'.*\b(LIMIT|ORDER)\b.*'.$close_parenthesis;
56
    $pattern = '/.*\bFROM\b.*(?:.*'.$subquery_with_limit_order.'.*).*/Uims';
57
    if (preg_match($pattern, $sql)) {
58
        return false;
59
    }
60
    $queryCount = preg_replace('/(?:.*)\bFROM\b\s+/Uims', 'SELECT COUNT(*) FROM ', $sql, 1);
61
    list($queryCount, ) = preg_split('/\s+ORDER\s+BY\s+/is', $queryCount);
62
    list($queryCount, ) = preg_split('/\bLIMIT\b/is', $queryCount);
63
    return trim($queryCount);
64
}
65
 
66
/**
67
 * @param object PEAR::DB instance
68
 * @param string db query
69
 * @param array  PEAR::Pager options
70
 * @param boolean Disable pagination (get all results)
71
 * @param integer fetch mode constant
72
 * @param mixed  parameters for query placeholders
73
 *        If you use placeholders for table names or column names, please
74
 *        count the # of items returned by the query and pass it as an option:
75
 *        $pager_options['totalItems'] = count_records('some query');
76
 * @return array with links and paged data
77
 */
78
function Pager_Wrapper_DB(&$db, $query, $pager_options = array(), $disabled = false, $fetchMode = DB_FETCHMODE_ASSOC, $dbparams = null)
79
{
80
   if (!array_key_exists('totalItems', $pager_options)) {
81
        //  be smart and try to guess the total number of records
82
        if ($countQuery = rewriteCountQuery($query)) {
83
            $totalItems = $db->getOne($countQuery, $dbparams);
84
            if (PEAR::isError($totalItems)) {
85
                return $totalItems;
86
            }
87
        } else {
88
            $res =& $db->query($query, $dbparams);
89
            if (PEAR::isError($res)) {
90
                return $res;
91
            }
92
            $totalItems = (int)$res->numRows();
93
            $res->free();
94
        }
95
        $pager_options['totalItems'] = $totalItems;
96
    }
97
    require_once 'Pager/Pager.php';
98
    $pager = Pager::factory($pager_options);
99
 
100
    $page = array();
101
    $page['totalItems'] = $pager_options['totalItems'];
102
    $page['links'] = $pager->links;
103
    $page['page_numbers'] = array(
104
        'current' => $pager->getCurrentPageID(),
105
        'total'   => $pager->numPages()
106
    );
107
    list($page['from'], $page['to']) = $pager->getOffsetByPageId();
108
 
109
    $res = ($disabled)
110
        ? $db->limitQuery($query, 0, $totalItems, $dbparams)
111
        : $db->limitQuery($query, $page['from']-1, $pager_options['perPage'], $dbparams);
112
 
113
    if (PEAR::isError($res)) {
114
        return $res;
115
    }
116
    $page['data'] = array();
117
    while ($res->fetchInto($row, $fetchMode)) {
118
       $page['data'][] = $row;
119
    }
120
    if ($disabled) {
121
        $page['links'] = '';
122
        $page['page_numbers'] = array(
123
            'current' => 1,
124
            'total'   => 1
125
        );
126
    }
127
    return $page;
128
}
129
 
130
/**
131
 * @param object PEAR::MDB instance
132
 * @param string db query
133
 * @param array  PEAR::Pager options
134
 * @param boolean Disable pagination (get all results)
135
 * @param integer fetch mode constant
136
 * @return array with links and paged data
137
 */
138
function Pager_Wrapper_MDB(&$db, $query, $pager_options = array(), $disabled = false, $fetchMode = MDB_FETCHMODE_ASSOC)
139
{
140
    if (!array_key_exists('totalItems', $pager_options)) {
141
        //be smart and try to guess the total number of records
142
        if ($countQuery = rewriteCountQuery($query)) {
143
            $totalItems = $db->queryOne($countQuery);
144
            if (PEAR::isError($totalItems)) {
145
                return $totalItems;
146
            }
147
        } else {
148
            $res = $db->query($query);
149
            if (PEAR::isError($res)) {
150
                return $res;
151
            }
152
            $totalItems = (int)$db->numRows($res);
153
            $db->freeResult($res);
154
        }
155
        $pager_options['totalItems'] = $totalItems;
156
    }
157
    require_once 'Pager/Pager.php';
158
    $pager = Pager::factory($pager_options);
159
 
160
    $page = array();
161
    $page['totalItems'] = $pager_options['totalItems'];
162
    $page['links'] = $pager->links;
163
    $page['page_numbers'] = array(
164
        'current' => $pager->getCurrentPageID(),
165
        'total'   => $pager->numPages()
166
    );
167
    list($page['from'], $page['to']) = $pager->getOffsetByPageId();
168
 
169
    $res = ($disabled)
170
        ? $db->limitQuery($query, null, 0, $totalItems)
171
        : $db->limitQuery($query, null, $page['from']-1, $pager_options['perPage']);
172
 
173
    if (PEAR::isError($res)) {
174
        return $res;
175
    }
176
    $page['data'] = array();
177
    while ($row = $db->fetchInto($res, $fetchMode)) {
178
        $page['data'][] = $row;
179
    }
180
    if ($disabled) {
181
        $page['links'] = '';
182
        $page['page_numbers'] = array(
183
            'current' => 1,
184
            'total'   => 1
185
        );
186
    }
187
    return $page;
188
}
189
 
190
/**
191
 * @param object PEAR::MDB2 instance
192
 * @param string db query
193
 * @param array  PEAR::Pager options
194
 * @param boolean Disable pagination (get all results)
195
 * @param integer fetch mode constant
196
 * @return array with links and paged data
197
 */
198
function Pager_Wrapper_MDB2(&$db, $query, $pager_options = array(), $disabled = false, $fetchMode = MDB2_FETCHMODE_ASSOC)
199
{
200
    if (!array_key_exists('totalItems', $pager_options)) {
201
        //be smart and try to guess the total number of records
202
        if ($countQuery = rewriteCountQuery($query)) {
203
            $totalItems = $db->queryOne($countQuery);
204
            if (PEAR::isError($totalItems)) {
205
                return $totalItems;
206
            }
207
        } else {
208
            //GROUP BY => fetch the whole resultset and count the rows returned
209
            $res =& $db->queryCol($query);
210
            if (PEAR::isError($res)) {
211
                return $res;
212
            }
213
            $totalItems = count($res);
214
        }
215
        $pager_options['totalItems'] = $totalItems;
216
    }
217
    require_once 'Pager/Pager.php';
218
    $pager = Pager::factory($pager_options);
219
 
220
    $page = array();
221
    $page['links'] = $pager->links;
222
    $page['totalItems'] = $pager_options['totalItems'];
223
    $page['page_numbers'] = array(
224
        'current' => $pager->getCurrentPageID(),
225
        'total'   => $pager->numPages()
226
    );
227
    list($page['from'], $page['to']) = $pager->getOffsetByPageId();
228
    $page['limit'] = $page['to'] - $page['from'] +1;
229
    if (!$disabled) {
230
        $db->setLimit($pager_options['perPage'], $page['from']-1);
231
    }
232
    $page['data'] = $db->queryAll($query, null, $fetchMode);
233
    if (PEAR::isError($page['data'])) {
234
        return $page['data'];
235
    }
236
    if ($disabled) {
237
        $page['links'] = '';
238
        $page['page_numbers'] = array(
239
            'current' => 1,
240
            'total'   => 1
241
        );
242
    }
243
    return $page;
244
}
245
 
246
/**
247
 * @param object PEAR::DataObject instance
248
 * @param array  PEAR::Pager options
249
 * @param boolean Disable pagination (get all results)
250
 * @return array with links and paged data
251
 * @author Massimiliano Arione <garak@studenti.it>
252
 */
253
function Pager_Wrapper_DBDO(&$db, $pager_options = array(), $disabled = false)
254
{
255
    if (!array_key_exists('totalItems', $pager_options)) {
256
        $totalItems = $db->count();
257
        $pager_options['totalItems'] = $totalItems;
258
    }
259
    require_once 'Pager/Pager.php';
260
    $pager = Pager::factory($pager_options);
261
 
262
    $page = array();
263
    $page['links'] = $pager->links;
264
    $page['totalItems'] = $pager_options['totalItems'];
265
    $page['page_numbers'] = array(
266
        'current' => $pager->getCurrentPageID(),
267
        'total'   => $pager->numPages()
268
    );
269
    list($page['from'], $page['to']) = $pager->getOffsetByPageId();
270
    $page['limit'] = $page['to'] - $page['from'] + 1;
271
    if (!$disabled) {
272
        $db->limit($page['from'] - 1, $pager_options['perPage']);
273
    }
274
    $db->find();
275
    while ($db->fetch()) {
276
        $db->getLinks();
277
        $page['data'][] = $db->toArray('%s', true);
278
    }
279
    return $page;
280
}
281
 
282
/**
283
 * @param object PHP Eclipse instance
284
 * @param string db query
285
 * @param array  PEAR::Pager options
286
 * @param boolean Disable pagination (get all results)
287
 * @return array with links and paged data
288
 * @author Matte Edens <matte@arubanetworks.com>
289
 * @see http://sourceforge.net/projects/eclipselib/
290
 */
291
function Pager_Wrapper_Eclipse(&$db, $query, $pager_options = array(), $disabled = false)
292
{
293
    if (!$disabled) {
294
        require_once(ECLIPSE_ROOT . 'PagedQuery.php');
295
        $query =& new PagedQuery($db->query($query), $pager_options['perPage']);
296
        $totalrows = $query->getRowCount();
297
        $numpages  = $query->getPageCount();
298
        $whichpage = isset($_GET[$pager_options['urlVar']]) ? (int)$_GET[$pager_options['urlVar']] - 1 : 0;
299
        if ($whichpage >= $numpages) {
300
            $whichpage = $numpages - 1;
301
        }
302
        $result = $query->getPage($whichpage);
303
    } else {
304
        $result    = $db->query($query);
305
        $totalrows = $result->getRowCount();
306
        $numpages  = 1;
307
    }
308
    if (!$result->isSuccess()) {
309
        return PEAR::raiseError($result->getErrorMessage());
310
    }
311
    if (!array_key_exists('totalItems', $pager_options)) {
312
        $pager_options['totalItems'] = $totalrows;
313
    }
314
 
315
    $page = array();
316
    require_once(ECLIPSE_ROOT . 'QueryIterator.php');
317
    for ($it =& new QueryIterator($result); $it->isValid(); $it->next()) {
318
        $page['data'][] =& $it->getCurrent();
319
    }
320
    require_once 'Pager/Pager.php';
321
    $pager = Pager::factory($pager_options);
322
 
323
    $page['links']        = $pager->links;
324
    $page['totalItems']   = $pager_options['totalItems'];
325
    $page['page_numbers'] = array(
326
        'current' => $pager->getCurrentPageID(),
327
        'total'   => $numpages
328
    );
329
	$page['perPageSelectBox'] = $pager->getperpageselectbox();
330
    list($page['from'], $page['to']) = $pager->getOffsetByPageId();
331
    $page['limit'] = $page['to'] - $page['from'] +1;
332
    if ($disabled) {
333
        $page['links'] = '';
334
        $page['page_numbers'] = array(
335
            'current' => 1,
336
            'total'   => 1
337
        );
338
    }
339
    return $page;
340
}
341
?>