/[drupal]/contributions/modules/custom_pagers/custom_pagers.module
ViewVC logotype

Contents of /contributions/modules/custom_pagers/custom_pagers.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.6 - (show annotations) (download) (as text)
Tue Jun 17 21:20:32 2008 UTC (17 months, 1 week ago) by eaton
Branch: MAIN
CVS Tags: DRUPAL-6--1-10-BETA1, HEAD
Branch point for: DRUPAL-6--1, DRUPAL-6--2
Changes since 1.5: +4 -2 lines
File MIME type: text/x-php
Choked when loading lists with no entries. Whoops.
1 <?php
2 // $Id: custom_pagers.module,v 1.3.2.11 2008/01/04 22:39:07 eaton Exp $
3
4 /**
5 * Implementation of hook_menu().
6 */
7 function custom_pagers_menu() {
8 $items = array();
9
10 $access = user_access('administer custom pagers');
11 $items['admin/build/custom_pagers'] = array(
12 'title' => 'Custom pagers',
13 'description' => 'Add custom pagers for content types.',
14 'page callback' => 'custom_pagers_page',
15 'access arguments' => array('administer custom pagers'),
16 'file' => 'custom_pagers.admin.inc',
17 );
18
19 $items['admin/build/custom_pagers/add'] = array(
20 'path' => 'admin/build/custom_pagers/add',
21 'title' => 'Add custom pager',
22 'type' => MENU_CALLBACK,
23 'page callback' => 'drupal_get_form',
24 'page arguments' => array('custom_pagers_form'),
25 'access arguments' => array('administer custom pagers'),
26 'file' => 'custom_pagers.admin.inc',
27 );
28
29 $items['admin/build/custom_pagers/edit'] = array(
30 'title' => 'Edit custom pager',
31 'type' => MENU_CALLBACK,
32 'page callback' => 'drupal_get_form',
33 'page arguments' => array('custom_pagers_form', 4),
34 'access arguments' => array('administer custom pagers'),
35 'file' => 'custom_pagers.admin.inc',
36 );
37
38 return $items;
39 }
40
41 function custom_pagers_perm() {
42 return array('administer custom pagers', 'use php in custom pagers');
43 }
44
45 function custom_pagers_theme() {
46 return array(
47 'custom_pager' => array(
48 'arguments' => array(
49 'nav_array' => NULL,
50 'node' => NULL,
51 'pager' => NULL,
52 'position' => 'bottom',
53 ),
54 'template' => 'custom-pager',
55 ),
56 );
57 }
58
59 function custom_pagers_nodeapi(&$node, $op, $teaser, $page) {
60 switch ($op) {
61 case 'view':
62 // We want to make sure we don't try to output when print.module is active.
63 // It's a bit of special casing but it doesn't do much harm.
64 if ($teaser == false && empty($node->printing)) {
65 $pagers = _custom_pagers_load_all_pagers();
66 foreach ($pagers as $pager) {
67 if ($pager->position != 'block' && _custom_pagers_visibility($pager, $node)) {
68 $nav_array = custom_pager_build_nav($pager, $node);
69 if ($nav_array['current_index'] != -1) {
70 switch ($pager->position) {
71 case 'top':
72 $node->content['custom_pager_top'][$pager->pid] = array('#value' => theme('custom_pager', $nav_array, $node, $pager, 'top'));
73 break;
74 case 'bottom':
75 $node->content['custom_pager_bottom'][$pager->pid] = array('#value' => theme('custom_pager', $nav_array, $node, $pager, 'bottom'));
76 break;
77 case 'both':
78 $node->content['custom_pager_top'][$pager->pid] = array('#value' => theme('custom_pager', $nav_array, $node, $pager, 'top'));
79 $node->content['custom_pager_bottom'][$pager->pid] = array('#value' => theme('custom_pager', $nav_array, $node, $pager, 'bottom'));
80 break;
81 }
82 }
83 }
84 }
85 if (isset($node->content['custom_pager_top'])) {
86 $node->content['custom_pager_top']['#weight'] = -100;
87 }
88 if (isset($node->content['custom_pager_bottom'])) {
89 $node->content['custom_pager_bottom']['#weight'] = 100;
90 }
91 }
92 break;
93 case 'update':
94 case 'insert':
95 case 'delete':
96 // If a user makes any changes to a node, we want to make sure that
97 // their pager cache is cleared. It's ugly, but it should prevent some
98 // of the nastier cache-went-stale issues.
99 unset($_SESSION['custom_pagers']);
100 break;
101 }
102 }
103
104 /**
105 * Implementation of hook_block().
106 *
107 * Generates a block with a pager for the current node.
108 */
109 function custom_pagers_block($op = 'list', $delta = 0) {
110 if ($op == 'list') {
111 $pagers = _custom_pagers_load_all_pagers();
112 foreach ($pagers as $pager) {
113 if ($pager->position == 'block') {
114 $blocks[$pager->pid]['info'] = $pager->title;
115 }
116 }
117 return $blocks;
118 }
119 else if ($op == 'view' && arg(0) == 'node' && $node = menu_get_object()) {
120 $pagers = _custom_pagers_load_all_pagers();
121 if ($pager = $pagers[$delta]) {
122 if ($pager->position == 'block' && _custom_pagers_visibility($pager, $node)) {
123 $nav_array = custom_pager_build_nav($pager, $node);
124 if ($nav_array['current_index'] != -1) {
125 if (module_exists('token')) {
126 $block['subject'] = token_replace($pager->title, 'node', $node);
127 }
128 else {
129 $block['subject'] = $pager->title;
130 }
131 $block['content'] = theme('custom_pager', $nav_array, $node, $pager, 'block');
132 return $block;
133 }
134 }
135 }
136 }
137 }
138
139 function _custom_pagers_load_pager($pid) {
140 $sql = 'SELECT * FROM {custom_pager} WHERE pid = %d';
141 $result = db_query($sql, $pid);
142 $pager = db_fetch_object($result);
143 return $pager;
144 }
145
146 function _custom_pagers_load_all_pagers($refresh = FALSE) {
147 static $pagers;
148 if ($refresh || !isset($pagers)) {
149 $sql = 'SELECT * FROM {custom_pager}';
150 $result = db_query($sql);
151
152 $pagers = array();
153 while($pager = db_fetch_object($result)) {
154 $pagers[$pager->pid] = $pager;
155 }
156 }
157 return $pagers;
158 }
159
160 function _custom_pagers_save_pager($pager = NULL) {
161 if (isset($pager->pid)) {
162 drupal_write_record('custom_pager', $pager, array('pid'));
163 }
164 else {
165 drupal_write_record('custom_pager', $pager);
166 }
167 cache_clear_all('custom_pagers_', 'cache', TRUE);
168 }
169
170 function _custom_pagers_delete_pager($pid) {
171 $sql = 'DELETE FROM {custom_pager} WHERE pid = %d';
172 db_query($sql, $pid);
173 }
174
175 function _custom_pagers_visibility($pager, $node) {
176 $visible = FALSE;
177 if (!empty($pager->visibility_php)) {
178 // Use PHP code to generate the list.
179 ob_start();
180 $result = eval(trim($pager->visibility_php));
181 $visible = ($result == TRUE);
182 ob_end_clean();
183 } elseif (!empty($pager->node_type)) {
184 $visible = (strpos($pager->node_type, $node->type) !== FALSE);
185 }
186 return $visible;
187 }
188
189 function custom_pager_build_nav($pager, $node) {
190 static $pager_cache;
191 $list = array();
192
193 // First we check the static function cache for this pager.
194 // If it's already been built for this page-load, we'll use it.
195 if (isset($pager_cache[$pager->pid])) {
196 $list = explode(',', $pager_cache[$pager->pid]);
197 }
198
199 // If it doesn't give us a list, and the pager is set to cache its
200 // data, we'll try to load from the current user's session. We do it
201 // that way rather than via cache_set() because of the potential for
202 // node_access violations. Each user's node list *could* be different.
203 if (empty($list) && $pager->cache_list) {
204 if ($cache = $_SESSION['custom_pagers'][$pager->pid]) {
205 // We should probably set the pager cache lifetime to a configurable
206 // value. If any nodes drop through the cracks, users won't see the
207 // pager when they visit them. Five minutes should keep the pager from
208 // thrashing. In the future, we'll want to develop a better strategy
209 // for this.
210 if ($cache['timestamp'] < (time() - 300)) {
211 unset($_SESSION['custom_pagers'][$pager->pid]);
212 }
213 else {
214 $list = explode(',', $_SESSION['custom_pagers'][$pager->pid]['data']);
215 }
216 }
217 }
218
219 // If $list is still empty, neither caching strategy produced a list.
220 // Let's build it from scratch!
221 if (empty($list)) {
222 // If the pager uses PHP, execute the PHP and run with the list.
223 // Otherwise, use a view to get a list of node ids.
224 if (!empty($pager->list_php)) {
225 // Use PHP code to generate the list.
226 ob_start();
227 $result = eval(trim($pager->list_php));
228 if (is_array($result)) {
229 $list = $result;
230 }
231 ob_end_clean();
232 }
233 elseif (module_exists('views') && $view = views_get_view($pager->view)) {
234 // Get arguments for the view.
235 if (isset($pager->args)) {
236 $args = explode("\n", $pager->args);
237 if (module_exists('token')) {
238 $args = token_replace($args, 'node', $node);
239 }
240 $view->set_arguments($args);
241 }
242
243 // Make sure the query is not cached
244 $view->is_cacheable = FALSE;
245 $view->execute();
246
247 if (isset($view->result)) {
248 foreach($view->result as $result) {
249 $list[] = $result->nid;
250 }
251 }
252 }
253
254 if ($pager->reverse_list) {
255 $list = array_reverse($list);
256 }
257 }
258
259 // If we get to this point, we want to cache what we've made.
260 if ($pager->cache_list) {
261 $_SESSION['custom_pagers'][$pager->pid]['data'] = implode(',', $list);
262 $_SESSION['custom_pagers'][$pager->pid]['timestamp'] = time();
263 }
264 $pager_cache[$pager->pid] = $list;
265
266 return pager_entries_by_val($node->nid, $list);
267 }
268
269 // Helper functions to pull proper entries from a list of nids.
270
271 function pager_entries_by_val($value, $list) {
272 $list = array_values($list);
273 foreach ($list as $k => $v) {
274 if ($v == $value) {
275 $key = $k;
276 }
277 }
278 if (!isset($key)) {
279 $key = -1;
280 }
281 return pager_entries_by_key($key, $list);
282 }
283
284 function pager_entries_by_key($key, $list, $increment = 1) {
285 $list = array_values($list);
286 $nav = array(
287 'first' => $list[0],
288 'prev' => $list[max($key - $increment, 0)],
289 'next' => $list[min($key + $increment, (count($list) - 1))],
290 'last' => $list[count($list) - 1],
291 'full_list' => $list
292 );
293
294 foreach($nav as $k => $v) {
295 if ($nav[$k] == $list[$key]) {
296 $nav[$k] = NULL;
297 }
298 }
299
300 $nav['current_index'] = $key;
301 return $nav;
302 }
303
304 function custom_pagers_preprocess_custom_pager(&$vars) {
305 drupal_add_css(drupal_get_path('module', 'custom_pagers') .'/custom_pagers.css');
306 $node = $vars['node'];
307 $pager = $vars['pager'];
308 $nav = $vars['nav_array'];
309
310 $vars['previous'] = !empty($nav['prev']) ? l(t('‹ previous'), 'node/'. $nav['prev']) : '';
311 $vars['key'] = t('@count of @count_total', array('@count' => ($nav['current_index'] + 1), '@count_total' => count($nav['full_list'])));
312 $vars['next'] = !empty($nav['next']) ? l(t('next ›'), 'node/'. $nav['next']) : '';
313
314 $vars['suggestions'][] = "custom-pager-{$vars['position']}";
315 $vars['suggestions'][] = "custom-pager-$node->type";
316 $vars['suggestions'][] = "custom-pager-$node->type-{$vars['position']}";
317 $vars['suggestions'][] = "custom-pager-$pager->pid";
318 $vars['suggestions'][] = "custom-pager-$pager->pid-{$vars['position']}";
319 }

  ViewVC Help
Powered by ViewVC 1.1.2