custom_pagers.module in Custom Pagers 6
Same filename and directory in other branches
Allows administrators to define context-sensitive previous/next pagers for any node type.
File
custom_pagers.moduleView source
<?php
/**
* @file
* Allows administrators to define context-sensitive previous/next pagers for any node type.
*/
/**
* Implementation of hook_menu().
*/
function custom_pagers_menu() {
$items = array();
$access = user_access('administer custom pagers');
$items['admin/build/custom_pagers'] = array(
'title' => 'Custom pagers',
'description' => 'Add custom pagers for content types.',
'page callback' => 'custom_pagers_page',
'access arguments' => array(
'administer custom pagers',
),
'file' => 'custom_pagers.admin.inc',
);
$items['admin/build/custom_pagers/add'] = array(
'path' => 'admin/build/custom_pagers/add',
'title' => 'Add custom pager',
'type' => MENU_CALLBACK,
'page callback' => 'drupal_get_form',
'page arguments' => array(
'custom_pagers_form',
),
'access arguments' => array(
'administer custom pagers',
),
'file' => 'custom_pagers.admin.inc',
);
$items['admin/build/custom_pagers/edit'] = array(
'title' => 'Edit custom pager',
'type' => MENU_CALLBACK,
'page callback' => 'drupal_get_form',
'page arguments' => array(
'custom_pagers_form',
4,
),
'access arguments' => array(
'administer custom pagers',
),
'file' => 'custom_pagers.admin.inc',
);
return $items;
}
function custom_pagers_perm() {
return array(
'administer custom pagers',
'use php in custom pagers',
);
}
function custom_pagers_theme() {
return array(
'custom_pager' => array(
'arguments' => array(
'nav_array' => NULL,
'node' => NULL,
'pager' => NULL,
'position' => 'bottom',
),
'template' => 'custom-pager',
),
);
}
function custom_pagers_nodeapi(&$node, $op, $teaser, $page) {
switch ($op) {
case 'view':
// We want to make sure we don't try to output when print.module is active.
// It's a bit of special casing but it doesn't do much harm.
if ($teaser == FALSE && empty($node->printing)) {
$node->custom_pagers = _custom_pagers_load_all_pagers();
foreach ($node->custom_pagers as $pager) {
if ($pager->position != 'block' && _custom_pagers_visibility($pager, $node)) {
$nav_array = custom_pager_build_nav($pager, $node);
if ($nav_array['current_index'] != -1) {
switch ($pager->position) {
case 'top':
$node->content['custom_pager_top'][$pager->pid] = array(
'#value' => theme('custom_pager', $nav_array, $node, $pager, 'top'),
);
break;
case 'bottom':
$node->content['custom_pager_bottom'][$pager->pid] = array(
'#value' => theme('custom_pager', $nav_array, $node, $pager, 'bottom'),
);
break;
case 'both':
$node->content['custom_pager_top'][$pager->pid] = array(
'#value' => theme('custom_pager', $nav_array, $node, $pager, 'top'),
);
$node->content['custom_pager_bottom'][$pager->pid] = array(
'#value' => theme('custom_pager', $nav_array, $node, $pager, 'bottom'),
);
break;
}
}
}
}
if (isset($node->content['custom_pager_top'])) {
$node->content['custom_pager_top']['#weight'] = -100;
}
if (isset($node->content['custom_pager_bottom'])) {
$node->content['custom_pager_bottom']['#weight'] = 100;
}
}
break;
}
}
/**
* Implementation of hook_block().
*
* Generates a block with a pager for the current node.
*/
function custom_pagers_block($op = 'list', $delta = 0) {
if ($op == 'list') {
$pagers = _custom_pagers_load_all_pagers();
foreach ($pagers as $pager) {
if ($pager->position == 'block') {
$blocks[$pager->pid]['info'] = $pager->title;
}
}
return $blocks;
}
else {
if ($op == 'view' && arg(0) == 'node' && ($node = menu_get_object())) {
$pagers = _custom_pagers_load_all_pagers();
if ($pager = $pagers[$delta]) {
if ($pager->position == 'block' && _custom_pagers_visibility($pager, $node)) {
$nav_array = custom_pager_build_nav($pager, $node);
if ($nav_array['current_index'] != -1) {
if (module_exists('token')) {
$block['subject'] = token_replace($pager->title, 'node', $node);
}
else {
$block['subject'] = $pager->title;
}
$block['content'] = theme('custom_pager', $nav_array, $node, $pager, 'block');
return $block;
}
}
}
}
}
}
function _custom_pagers_load_pager($pid) {
$sql = 'SELECT * FROM {custom_pager} WHERE pid = %d';
$result = db_query($sql, $pid);
$pager = db_fetch_object($result);
return $pager;
}
function _custom_pagers_load_all_pagers($refresh = FALSE) {
static $pagers;
if ($refresh || !isset($pagers)) {
$sql = 'SELECT * FROM {custom_pager}';
$result = db_query($sql);
$pagers = array();
while ($pager = db_fetch_object($result)) {
$pagers[$pager->pid] = $pager;
}
}
return $pagers;
}
function _custom_pagers_save_pager($pager = NULL) {
if (isset($pager->pid)) {
drupal_write_record('custom_pager', $pager, array(
'pid',
));
}
else {
drupal_write_record('custom_pager', $pager);
}
cache_clear_all('custom_pagers_', 'cache', TRUE);
}
function _custom_pagers_delete_pager($pid) {
$sql = 'DELETE FROM {custom_pager} WHERE pid = %d';
db_query($sql, $pid);
}
function _custom_pagers_visibility($pager, $node) {
$visible = FALSE;
if (!empty($pager->visibility_php)) {
// Use PHP code to generate the list.
ob_start();
$result = eval(trim($pager->visibility_php));
$visible = $result == TRUE;
ob_end_clean();
}
elseif (!empty($pager->node_type)) {
$visible = strpos($pager->node_type, $node->type) !== FALSE;
}
return $visible;
}
function custom_pager_build_nav($pager, $node) {
static $pager_cache;
$list = array();
// Let's build it from scratch!
if (empty($list)) {
// If the pager uses PHP, execute the PHP and run with the list.
// Otherwise, use a view to get a list of node ids.
if (!empty($pager->list_php)) {
// Use PHP code to generate the list.
ob_start();
$result = eval(trim($pager->list_php));
if (is_array($result)) {
$list = $result;
}
ob_end_clean();
}
elseif ($results = custom_pagers_get_list_from_view($pager, $node)) {
$list = $results;
}
if ($pager->reverse_list) {
$list = array_reverse($list);
}
}
return pager_entries_by_val($node->nid, $list);
}
// Helper functions to pull proper entries from a list of nids.
function pager_entries_by_val($value, $list) {
$list = array_values($list);
foreach ($list as $k => $v) {
if ($v == $value) {
$key = $k;
}
}
if (!isset($key)) {
$key = -1;
}
return pager_entries_by_key($key, $list);
}
function pager_entries_by_key($key, $list, $increment = 1) {
$list = array_values($list);
$nav = array(
'first' => $list[0],
'prev' => $list[max($key - $increment, 0)],
'next' => $list[min($key + $increment, count($list) - 1)],
'last' => $list[count($list) - 1],
'full_list' => $list,
);
foreach ($nav as $k => $v) {
if ($nav[$k] == $list[$key]) {
$nav[$k] = NULL;
}
}
$nav['current_index'] = $key;
return $nav;
}
function custom_pagers_get_list_from_view($pager, $node) {
if ($view = views_get_view($pager->view)) {
$display = $view
->add_display('custom_pagers_simple');
$view
->set_display($display);
$view->display_handler
->set_option('style_plugin', 'custom_pagers_php_array');
$view->display_handler
->set_option('items_per_page', 0);
// Get arguments for the view.
if (!empty($pager->args)) {
$args = array_map('trim', explode("\n", $pager->args));
if (module_exists('token')) {
$args = token_replace($args, 'node', $node);
}
}
else {
$args = array();
}
// Remove the number-of-items-per-page restriction, as it will mess up
// our counts.
$view->pager['items_per_page'] = 0;
// Get the results.
$result = $view
->execute_display($display, $args);
}
else {
$result = FALSE;
}
return $result;
}
function template_preprocess_custom_pager(&$vars) {
drupal_add_css(drupal_get_path('module', 'custom_pagers') . '/custom_pagers.css');
$node = $vars['node'];
$pager = $vars['pager'];
$nav = $vars['nav_array'];
$vars['previous'] = !empty($nav['prev']) ? l('‹ ' . t('previous'), 'node/' . $nav['prev']) : '';
$vars['key'] = t('@count of @count_total', array(
'@count' => $nav['current_index'] + 1,
'@count_total' => count($nav['full_list']),
));
$vars['next'] = !empty($nav['next']) ? l(t('next') . ' ›', 'node/' . $nav['next']) : '';
$vars['template_files'][] = "custom-pager-{$vars['position']}";
$vars['template_files'][] = "custom-pager-{$node->type}";
$vars['template_files'][] = "custom-pager-{$node->type}-{$vars['position']}";
$vars['template_files'][] = "custom-pager-{$pager->pid}";
$vars['template_files'][] = "custom-pager-{$pager->pid}-{$vars['position']}";
}
/**
* Implementation of hook_views_api().
*/
function custom_pagers_views_api() {
return array(
'api' => 2,
'path' => drupal_get_path('module', 'custom_pagers') . '/views',
);
}