book_helper.module in Book helper 6
Same filename and directory in other branches
Improves Drupal's core book module's functionality.
File
book_helper.moduleView source
<?php
/**
* @file
* Improves Drupal's core book module's functionality.
*/
/**
* Implementation of hook_help().
*/
function book_helper_help($path, $arg) {
switch ($path) {
case 'node/%/delete':
book_helper_display_delete_book_page_warning($arg[1]);
break;
}
}
/**
* Implementation of hook_perm().
*/
function book_helper_perm() {
return array(
'administer own book outlines',
);
}
/**
* Implementation of hook_menu().
*/
function book_helper_menu() {
// Adds an order tab to book's main node.
$items['node/%node/order'] = array(
'title' => 'Order',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'book_helper_admin_edit',
1,
),
'access callback' => '_book_helper_access',
'access arguments' => array(
1,
),
'type' => MENU_LOCAL_TASK,
'weight' => 2,
'file' => 'book_helper.admin.inc',
);
return $items;
}
/**
* Implementation of hook_menu_alter(). Overrides the books outline page.
*
* @see book.module
*/
function book_helper_menu_alter(&$items) {
// Hijack the book.module's 'edit order and titles' page. (admin/content/book/%node)
// This allows us to add the hide/show checkbox to order book form.
$items['admin/content/book/%node']['page arguments'] = array(
'book_helper_admin_edit',
3,
);
$items['admin/content/book/%node']['file'] = 'book_helper.admin.inc';
$items['admin/content/book/%node']['file path'] = drupal_get_path('module', 'book_helper');
// Remove outline tab.
if (variable_get('book_helper_remove_outline', '0') == '1') {
unset($items['node/%node/outline']);
}
}
/**
* Implementation of hook_menu_link_alter().
*/
function book_helper_menu_link_alter(&$item, $menu) {
// Book module does not support hidden pages so we need to manually
// preserve it when a book page is updated outside of the book helper
// module's node/%/order page.
if (isset($item['module']) && $item['module'] == 'book' && isset($item['mlid']) && !isset($item['hidden'])) {
$item['hidden'] = db_result(db_query('SELECT hidden FROM {menu_links} WHERE mlid=%d', $item['mlid']));
}
}
/**
* Menu callback access; Determine if the order book tab is accessible.
*/
function _book_helper_access($node) {
global $user;
$is_node_book = isset($node->book['bid']) && $node->book['bid'] == $node->nid;
if (!$is_node_book) {
return FALSE;
}
// Allow users to administer their own books using 'administer own book outlines'
if (user_access('administer own book outlines') && $node->uid === $user->uid) {
return TRUE;
}
return _book_outline_access($node);
}
/**
* Implementation of hook_nodeapi().
*/
function book_helper_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
switch ($op) {
case 'view':
// Remove book navigation.
if (variable_get('book_helper_remove_book_navigation', 0) == 1) {
unset($node->content['book_navigation']);
}
break;
case 'load':
// Track customized link title and whether it is sync (equal) to the node's title.
$link_title = db_result(db_query('SELECT link_title FROM {book} b INNER JOIN {menu_links} ml ON b.mlid = ml.mlid WHERE b.nid = %d', $node->nid));
if ($link_title) {
$node_title = function_exists('node_parent_title_remove') ? node_parent_title_remove($node->title) : $node->title;
$info['book_helper']['link_title_custom'] = $link_title;
$info['book_helper']['link_title_sync'] = $link_title == $node_title ? TRUE : FALSE;
return $info;
}
break;
case 'insert':
case 'update':
// Get link title sync and custom from the book.module's array().
if (isset($node->book['book_helper_link_title_sync'])) {
$node->book_helper['link_title_sync'] = $node->book['book_helper_link_title_sync'];
}
if (isset($node->book['book_helper_link_title_custom'])) {
$node->book_helper['link_title_custom'] = $node->book['book_helper_link_title_custom'];
}
// Update the book page's menu link title if it has been customized.
if (!empty($node->book['bid']) && empty($node->book_helper['link_title_sync']) && $node->book_helper['link_title_custom'] != $node->book['link_title']) {
db_query("UPDATE {menu_links} SET link_title='%s' WHERE mlid = %d", $node->book_helper['link_title_custom'], $node->book['mlid']);
}
break;
default:
break;
}
}
/**
* Implementation of hook_block().
*/
function book_helper_block($op = 'list', $delta = 0, $edit = array()) {
switch ($op) {
case 'list':
$blocks['book-helper-inline-navigation'] = array(
'info' => t('Book (inline) navigation'),
);
return $blocks;
case 'view':
$node = menu_get_object();
if (!$node || !isset($node->book['bid'])) {
return NULL;
}
else {
return array(
'content' => theme('book_navigation', $node->book),
);
}
default:
return;
}
}
/**
* Implementation of hook_form_FORM_ID_alter().
*/
function book_helper_form_book_admin_settings_alter(&$form, &$form_state) {
module_load_include('inc', 'book_helper', 'book_helper.admin');
_book_helper_form_book_admin_settings_alter($form, $form_state);
}
/**
* Implementation of hook_form_alter().
*/
function book_helper_form_alter(&$form, &$form_state, $form_id) {
if ($form['#id'] == 'node-form') {
$node =& $form['#node'];
$type = $form['type']['#value'];
if (isset($form['book']) && !book_type_is_allowed($type) && empty($node->book['bid'])) {
// Hide book fieldset.
$form['book']['#access'] = FALSE;
}
elseif (!isset($node->nid) && !isset($_GET['parent']) && in_array($type, variable_get('book_helper_create_new', array()))) {
// Create new book for selected nodes that are not being added as child pages.
$node->book['bid'] == 'new';
$form['book']['bid']['#default_value'] = 'new';
}
if (isset($form['book'])) {
// Define default book helper properties.
if (!isset($node->book_helper)) {
$node->book_helper = array(
'link_title_custom' => $node->title,
'link_title_sync' => TRUE,
);
}
// Add inputs to allow user to customize the book link title separately from the node's title.
drupal_add_js(drupal_get_path('module', 'book_helper') . '/book_helper.js');
$form['book']['book_helper_link_title_custom'] = array(
'#type' => 'textfield',
'#title' => t('Book link title'),
'#default_value' => $node->book_helper['link_title_custom'],
'#maxlength' => 255,
);
$form['book']['book_helper_link_title_sync'] = array(
'#type' => 'checkbox',
'#title' => t("Syncronize this node's title with its book link title."),
'#default_value' => $node->book_helper['link_title_sync'],
);
}
}
}
/**
* Implementation of hook_link_alter().
*/
function book_helper_link_alter(&$links, $node, $comment = NULL) {
$book_link_names = array(
'book_add_child',
'book_printer',
);
$book_helper_links = variable_get('book_helper_links', $book_link_names);
foreach ($book_link_names as $book_link_name) {
if (isset($links[$book_link_name]) && (empty($book_helper_links) || !in_array($book_link_name, $book_helper_links))) {
unset($links[$book_link_name]);
}
}
}
////////////////////////////////////////////////////////////////////////////////
// Utility functions
////////////////////////////////////////////////////////////////////////////////
/**
* Display a warning warning when deleting a book page that has child pages.
*/
function book_helper_display_delete_book_page_warning($nid) {
$node = node_load($nid);
if (isset($node->book) && $node->book['bid'] != $node->nid) {
$book_node = node_load($node->book['bid']);
$result = db_query('SELECT mlid, link_title AS title, link_path AS href FROM {menu_links} WHERE plid=%d ORDER BY weight', $node->book['mlid']);
$links = array();
while ($record = db_fetch_array($result)) {
$links[$record['mlid']] = $record;
}
if (empty($links)) {
return;
}
$t_args = array(
'!book' => l($book_node->title, 'node' . $book_node->nid),
);
$output = t('The below book pages are not going to be deleted, they will be moved to the root of the !book book.', $t_args) . '<br />' . t('It is recommended that you delete or move these pages before proceeding.') . theme('links', $links, array());
drupal_set_message($output, 'warning');
}
}
////////////////////////////////////////////////////////////////////////////////
// Theme functions
////////////////////////////////////////////////////////////////////////////////
/**
* Implementation of hook_theme_registry_alter(). Remove template_preprocess_book_navigation();
*
* Prevent book_navigation variables from being preprocessed multiple times.
*/
function book_helper_theme_registry_alter(&$theme_registry) {
if (isset($theme_registry['book_navigation']['preprocess functions']) && is_array($theme_registry['book_navigation']['preprocess functions'])) {
$theme_registry['book_navigation']['preprocess functions'] = array_diff($theme_registry['book_navigation']['preprocess functions'], array(
'template_preprocess_book_navigation',
));
}
}
/**
* Override; Process variables for book-navigation.tpl.php.
*/
function book_helper_preprocess_book_navigation(&$variables) {
$navigation_options = variable_get('book_helper_navigation_options', array(
'tree',
'prev',
'next',
'up',
));
// Below code is copied from template_preprocess_book_navigation();
$book_link = $variables['book_link'];
// Provide extra variables for themers. Not needed by default.
$variables['book_id'] = $book_link['bid'];
$variables['book_title'] = check_plain($book_link['link_title']);
$variables['book_url'] = 'node/' . $book_link['bid'];
$variables['current_depth'] = $book_link['depth'];
$variables['tree'] = '';
if ($book_link['mlid']) {
if (in_array('tree', $navigation_options)) {
$variables['tree'] = book_children($book_link);
}
if (in_array('prev', $navigation_options) && ($prev = book_prev($book_link))) {
$prev_href = url($prev['href']);
drupal_add_link(array(
'rel' => 'prev',
'href' => $prev_href,
));
$variables['prev_url'] = $prev_href;
$variables['prev_title'] = check_plain($prev['title']);
}
if (in_array('up', $navigation_options) && $book_link['plid'] && ($parent = book_link_load($book_link['plid']))) {
$parent_href = url($parent['href']);
drupal_add_link(array(
'rel' => 'up',
'href' => $parent_href,
));
$variables['parent_url'] = $parent_href;
$variables['parent_title'] = check_plain($parent['title']);
}
if (in_array('next', $navigation_options) && ($next = book_next($book_link))) {
$next_href = url($next['href']);
drupal_add_link(array(
'rel' => 'next',
'href' => $next_href,
));
$variables['next_url'] = $next_href;
$variables['next_title'] = check_plain($next['title']);
}
}
$variables['has_links'] = FALSE;
// Link variables to filter for values and set state of the flag variable.
$links = array(
'prev_url',
'prev_title',
'parent_url',
'parent_title',
'next_url',
'next_title',
);
foreach ($links as $link) {
if (isset($variables[$link])) {
// Flag when there is a value.
$variables['has_links'] = TRUE;
}
else {
// Set empty to prevent notices.
$variables[$link] = '';
}
}
}
/**
* Implementation of hook_theme().
*/
function book_helper_theme() {
return array(
'book_helper_admin_table' => array(
'arguments' => array(
'form' => NULL,
),
'file' => 'book_helper.admin.inc',
),
);
}