Initial code using Drupal 6.38

This commit is contained in:
Manuel Cillero 2017-07-24 15:21:05 +02:00
commit 4824608a33
467 changed files with 90887 additions and 0 deletions

View file

@ -0,0 +1,21 @@
<?php
/**
* @file book-all-books-block.tpl.php
* Default theme implementation for rendering book outlines within a block.
* This template is used only when the block is configured to "show block on
* all pages" which presents Multiple independent books on all pages.
*
* Available variables:
* - $book_menus: Array of book outlines rendered as an unordered list. It is
* keyed to the parent book ID which is also the ID of the parent node
* containing an entire outline.
*
* @see template_preprocess_book_all_books_block()
*/
?>
<?php foreach ($book_menus as $book_id => $menu) : ?>
<div id="book-block-menu-<?php print $book_id; ?>" class="book-block-menu">
<?php print $menu; ?>
</div>
<?php endforeach; ?>

View file

@ -0,0 +1,52 @@
<?php
/**
* @file book-export-html.tpl.php
* Default theme implementation for printed version of book outline.
*
* Available variables:
* - $title: Top level node title.
* - $head: Header tags.
* - $language: Language code. e.g. "en" for english.
* - $language_rtl: TRUE or FALSE depending on right to left language scripts.
* - $base_url: URL to home page.
* - $content: Nodes within the current outline rendered through
* book-node-export-html.tpl.php.
*
* @see template_preprocess_book_export_html()
*/
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="<?php print $language->language; ?>" xml:lang="<?php print $language->language; ?>">
<head>
<?php print $head; ?>
<title><?php print $title; ?></title>
<base href="<?php print $base_url; ?>" />
<link type="text/css" rel="stylesheet" href="misc/print.css" />
<?php if ($language_rtl): ?>
<link type="text/css" rel="stylesheet" href="misc/print-rtl.css" />
<?php endif; ?>
</head>
<body>
<?php
/**
* The given node is /embedded to its absolute depth in a top level
* section/. For example, a child node with depth 2 in the hierarchy is
* contained in (otherwise empty) &lt;div&gt; elements corresponding to
* depth 0 and depth 1. This is intended to support WYSIWYG output - e.g.,
* level 3 sections always look like level 3 sections, no matter their
* depth relative to the node selected to be exported as printer-friendly
* HTML.
*/
$div_close = '';
?>
<?php for ($i = 1; $i < $depth; $i++) : ?>
<div class="section-<?php print $i; ?>">
<?php $div_close .= '</div>'; ?>
<?php endfor; ?>
<?php print $contents; ?>
<?php print $div_close; ?>
</body>
</html>

View file

@ -0,0 +1,51 @@
<?php
/**
* @file book-navigation.tpl.php
* Default theme implementation to navigate books. Presented under nodes that
* are a part of book outlines.
*
* Available variables:
* - $tree: The immediate children of the current node rendered as an
* unordered list.
* - $current_depth: Depth of the current node within the book outline.
* Provided for context.
* - $prev_url: URL to the previous node.
* - $prev_title: Title of the previous node.
* - $parent_url: URL to the parent node.
* - $parent_title: Title of the parent node. Not printed by default. Provided
* as an option.
* - $next_url: URL to the next node.
* - $next_title: Title of the next node.
* - $has_links: Flags TRUE whenever the previous, parent or next data has a
* value.
* - $book_id: The book ID of the current outline being viewed. Same as the
* node ID containing the entire outline. Provided for context.
* - $book_url: The book/node URL of the current outline being viewed.
* Provided as an option. Not used by default.
* - $book_title: The book/node title of the current outline being viewed.
* Provided as an option. Not used by default.
*
* @see template_preprocess_book_navigation()
*/
?>
<?php if ($tree || $has_links): ?>
<div id="book-navigation-<?php print $book_id; ?>" class="book-navigation">
<?php print $tree; ?>
<?php if ($has_links): ?>
<div class="page-links clear-block">
<?php if ($prev_url) : ?>
<a href="<?php print $prev_url; ?>" class="page-previous" title="<?php print t('Go to previous page'); ?>"><?php print t(' ') . $prev_title; ?></a>
<?php endif; ?>
<?php if ($parent_url) : ?>
<a href="<?php print $parent_url; ?>" class="page-up" title="<?php print t('Go to parent page'); ?>"><?php print t('up'); ?></a>
<?php endif; ?>
<?php if ($next_url) : ?>
<a href="<?php print $next_url; ?>" class="page-next" title="<?php print t('Go to next page'); ?>"><?php print $next_title . t(' '); ?></a>
<?php endif; ?>
</div>
<?php endif; ?>
</div>
<?php endif; ?>

View file

@ -0,0 +1,24 @@
<?php
/**
* @file book-node-export-html.tpl.php
* Default theme implementation for rendering a single node in a printer
* friendly outline.
*
* @see book-node-export-html.tpl.php
* Where it is collected and printed out.
*
* Available variables:
* - $depth: Depth of the current node inside the outline.
* - $title: Node title.
* - $content: Node content.
* - $children: All the child nodes recursively rendered through this file.
*
* @see template_preprocess_book_node_export_html()
*/
?>
<div id="node-<?php print $node->nid; ?>" class="section-<?php print $depth; ?>">
<h1 class="book-heading"><?php print $title; ?></h1>
<?php print $content; ?>
<?php print $children; ?>
</div>

View file

@ -0,0 +1,7 @@
.book-navigation .page-previous {
float: right;
}
.book-navigation .page-up {
float: right;
}

249
modules/book/book.admin.inc Normal file
View file

@ -0,0 +1,249 @@
<?php
/**
* @file
* Admin page callbacks for the book module.
*/
/**
* Returns an administrative overview of all books.
*/
function book_admin_overview() {
$rows = array();
foreach (book_get_books() as $book) {
$rows[] = array(l($book['title'], $book['href'], $book['options']), l(t('edit order and titles'), "admin/content/book/". $book['nid']));
}
$headers = array(t('Book'), t('Operations'));
return theme('table', $headers, $rows);
}
/**
* Builds and returns the book settings form.
*
* @see book_admin_settings_validate()
*
* @ingroup forms
*/
function book_admin_settings() {
$types = node_get_types('names');
$form['book_allowed_types'] = array(
'#type' => 'checkboxes',
'#title' => t('Allowed book outline types'),
'#default_value' => variable_get('book_allowed_types', array('book')),
'#options' => $types,
'#description' => t('Select content types which users with the %add-perm permission will be allowed to add to the book hierarchy. Users with the %outline-perm permission can add all content types.', array('%add-perm' => t('add content to books'), '%outline-perm' => t('administer book outlines'))),
'#required' => TRUE,
);
$form['book_child_type'] = array(
'#type' => 'radios',
'#title' => t('Default child page type'),
'#default_value' => variable_get('book_child_type', 'book'),
'#options' => $types,
'#description' => t('The content type for the %add-child link must be one of those selected as an allowed book outline type.', array('%add-child' => t('Add child page'))),
'#required' => TRUE,
);
$form['array_filter'] = array('#type' => 'value', '#value' => TRUE);
$form['#validate'][] = 'book_admin_settings_validate';
return system_settings_form($form);
}
/**
* Validate the book settings form.
*
* @see book_admin_settings()
*/
function book_admin_settings_validate($form, &$form_state) {
$child_type = $form_state['values']['book_child_type'];
if (empty($form_state['values']['book_allowed_types'][$child_type])) {
form_set_error('book_child_type', t('The content type for the %add-child link must be one of those selected as an allowed book outline type.', array('%add-child' => t('Add child page'))));
}
}
/**
* Build the form to administrate the hierarchy of a single book.
*
* @see book_admin_edit_submit()
*
* @ingroup forms.
*/
function book_admin_edit($form_state, $node) {
drupal_set_title(check_plain($node->title));
$form = array();
$form['#node'] = $node;
_book_admin_table($node, $form);
$form['save'] = array(
'#type' => 'submit',
'#value' => t('Save book pages'),
);
return $form;
}
/**
* Check that the book has not been changed while using the form.
*
* @see book_admin_edit()
*/
function book_admin_edit_validate($form, &$form_state) {
if ($form_state['values']['tree_hash'] != $form_state['values']['tree_current_hash']) {
form_set_error('', t('This book has been modified by another user, the changes could not be saved.'));
$form_state['rebuild'] = TRUE;
}
}
/**
* Handle submission of the book administrative page form.
*
* This function takes care to save parent menu items before their children.
* Saving menu items in the incorrect order can break the menu tree.
*
* @see book_admin_edit()
* @see menu_overview_form_submit()
*/
function book_admin_edit_submit($form, &$form_state) {
// Save elements in the same order as defined in post rather than the form.
// This ensures parents are updated before their children, preventing orphans.
$order = array_flip(array_keys($form['#post']['table']));
$form['table'] = array_merge($order, $form['table']);
foreach (element_children($form['table']) as $key) {
if ($form['table'][$key]['#item']) {
$row = $form['table'][$key];
$values = $form_state['values']['table'][$key];
// Update menu item if moved.
if ($row['plid']['#default_value'] != $values['plid'] || $row['weight']['#default_value'] != $values['weight']) {
$row['#item']['plid'] = $values['plid'];
$row['#item']['weight'] = $values['weight'];
menu_link_save($row['#item']);
}
// Update the title if changed.
if ($row['title']['#default_value'] != $values['title']) {
$node = node_load($values['nid'], FALSE);
$node->title = $values['title'];
$node->book['link_title'] = $values['title'];
$node->revision = 1;
$node->log = t('Title changed from %original to %current.', array('%original' => $node->title, '%current' => $values['title']));
node_save($node);
watchdog('content', 'book: updated %title.', array('%title' => $node->title), WATCHDOG_NOTICE, l(t('view'), 'node/'. $node->nid));
}
}
}
drupal_set_message(t('Updated book %title.', array('%title' => $form['#node']->title)));
}
/**
* Build the table portion of the form for the book administration page.
*
* @see book_admin_edit()
*/
function _book_admin_table($node, &$form) {
$form['table'] = array(
'#theme' => 'book_admin_table',
'#tree' => TRUE,
);
$tree = book_menu_subtree_data($node->book);
$tree = array_shift($tree); // Do not include the book item itself.
if ($tree['below']) {
$hash = sha1(serialize($tree['below']));
// Store the hash value as a hidden form element so that we can detect
// if another user changed the book hierarchy.
$form['tree_hash'] = array(
'#type' => 'hidden',
'#default_value' => $hash,
);
$form['tree_current_hash'] = array(
'#type' => 'value',
'#value' => $hash,
);
_book_admin_table_tree($tree['below'], $form['table']);
}
}
/**
* Recursive helper to build the main table in the book administration page form.
*
* @see book_admin_edit()
*/
function _book_admin_table_tree($tree, &$form) {
foreach ($tree as $data) {
$form['book-admin-'. $data['link']['nid']] = array(
'#item' => $data['link'],
'nid' => array('#type' => 'value', '#value' => $data['link']['nid']),
'depth' => array('#type' => 'value', '#value' => $data['link']['depth']),
'href' => array('#type' => 'value', '#value' => $data['link']['href']),
'title' => array(
'#type' => 'textfield',
'#default_value' => $data['link']['link_title'],
'#maxlength' => 255,
'#size' => 40,
),
'weight' => array(
'#type' => 'weight',
'#default_value' => $data['link']['weight'],
'#delta' => 15,
),
'plid' => array(
'#type' => 'textfield',
'#default_value' => $data['link']['plid'],
'#size' => 6,
),
'mlid' => array(
'#type' => 'hidden',
'#default_value' => $data['link']['mlid'],
),
);
if ($data['below']) {
_book_admin_table_tree($data['below'], $form);
}
}
return $form;
}
/**
* Theme function for the book administration page form.
*
* @ingroup themeable
* @see book_admin_table()
*/
function theme_book_admin_table($form) {
drupal_add_tabledrag('book-outline', 'match', 'parent', 'book-plid', 'book-plid', 'book-mlid', TRUE, MENU_MAX_DEPTH - 2);
drupal_add_tabledrag('book-outline', 'order', 'sibling', 'book-weight');
$header = array(t('Title'), t('Weight'), t('Parent'), array('data' => t('Operations'), 'colspan' => '3'));
$rows = array();
$destination = drupal_get_destination();
$access = user_access('administer nodes');
foreach (element_children($form) as $key) {
$nid = $form[$key]['nid']['#value'];
$href = $form[$key]['href']['#value'];
// Add special classes to be used with tabledrag.js.
$form[$key]['plid']['#attributes']['class'] = 'book-plid';
$form[$key]['mlid']['#attributes']['class'] = 'book-mlid';
$form[$key]['weight']['#attributes']['class'] = 'book-weight';
$data = array(
theme('indentation', $form[$key]['depth']['#value'] - 2) . drupal_render($form[$key]['title']),
drupal_render($form[$key]['weight']),
drupal_render($form[$key]['plid']) . drupal_render($form[$key]['mlid']),
l(t('view'), $href),
$access ? l(t('edit'), 'node/'. $nid .'/edit', array('query' => $destination)) : '&nbsp',
$access ? l(t('delete'), 'node/'. $nid .'/delete', array('query' => $destination) ) : '&nbsp',
);
$row = array('data' => $data);
if (isset($form[$key]['#attributes'])) {
$row = array_merge($row, $form[$key]['#attributes']);
}
$row['class'] = empty($row['class']) ? 'draggable' : $row['class'] .' draggable';
$rows[] = $row;
}
return theme('table', $header, $rows, array('id' => 'book-outline'));
}

51
modules/book/book.css Normal file
View file

@ -0,0 +1,51 @@
.book-navigation .menu {
border-top: 1px solid #888;
padding: 1em 0 0 3em;
}
.book-navigation .page-links {
border-top: 1px solid #888;
border-bottom: 1px solid #888;
text-align: center;
padding: 0.5em;
}
.book-navigation .page-previous {
text-align: left;
width: 42%;
display: block;
float: left; /* LTR */
}
.book-navigation .page-up {
margin: 0 5%;
width: 4%;
display: block;
float: left; /* LTR */
}
.book-navigation .page-next {
text-align: right;
width: 42%;
display: block;
float: right;
}
#book-outline {
min-width: 56em;
}
.book-outline-form .form-item {
margin-top: 0;
margin-bottom: 0;
}
#edit-book-bid-wrapper .description {
clear: both;
}
#book-admin-edit select {
margin-right: 24px;
}
#book-admin-edit select.progress-disabled {
margin-right: 0;
}
#book-admin-edit tr.ahah-new-content {
background-color: #ffd;
}
#book-admin-edit .form-item {
float: left;
}

11
modules/book/book.info Normal file
View file

@ -0,0 +1,11 @@
name = Book
description = Allows users to structure site pages in a hierarchy or outline.
package = Core - optional
version = VERSION
core = 6.x
; Information added by Drupal.org packaging script on 2016-02-24
version = "6.38"
project = "drupal"
datestamp = "1456343372"

289
modules/book/book.install Normal file
View file

@ -0,0 +1,289 @@
<?php
/**
* Implementation of hook_install().
*/
function book_install() {
// Create tables.
drupal_install_schema('book');
// Add the node type.
_book_install_type_create();
}
/**
* Implementation of hook_uninstall().
*/
function book_uninstall() {
// Delete menu links.
db_query("DELETE FROM {menu_links} WHERE module = 'book'");
menu_cache_clear_all();
// Remove tables.
drupal_uninstall_schema('book');
}
function _book_install_type_create() {
// Create an additional node type
$book_node_type = array(
'type' => 'book',
'name' => t('Book page'),
'module' => 'node',
'description' => t('A <em>book page</em> is a page of content, organized into a collection of related entries collectively known as a <em>book</em>. A <em>book page</em> automatically displays links to adjacent pages, providing a simple navigation system for organizing and reviewing structured content.'),
'custom' => TRUE,
'modified' => TRUE,
'locked' => FALSE,
);
$book_node_type = (object)_node_type_set_defaults($book_node_type);
node_type_save($book_node_type);
// Default to not promoted.
variable_set('node_options_book', array('status'));
// Use this default type for adding content to books.
variable_set('book_allowed_types', array('book'));
variable_set('book_child_type', 'book');
}
/**
* Drupal 5.x to 6.x update.
*
* This function moves any existing book hierarchy into the new structure used
* in the 6.x module. Rather than storing the hierarchy in the {book} table,
* the menu API is used to store the hierarchy in the {menu_links} table and the
* {book} table serves to uniquely connect a node to a menu link.
*
* In order to accomplish this, the current hierarchy is processed using a stack.
* The stack insures that each parent is processed before any of its children
* in the book hierarchy, and is compatible with batched update processing.
*
*/
function book_update_6000() {
$ret = array();
// Set up for a multi-part update.
if (!isset($_SESSION['book_update_6000'])) {
$schema['book'] = array(
'fields' => array(
'mlid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
'nid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
'bid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
),
'primary key' => array('mlid'),
'unique keys' => array(
'nid' => array('nid'),
),
'indexes' => array(
'bid' => array('bid'),
),
);
// Add the node type.
_book_install_type_create();
// Fix role permissions to account for the changed names
// Setup the array holding strings to match and the corresponding
// strings to replace them with.
$replace = array(
'outline posts in books' => 'administer book outlines',
'create book pages' => 'create book content',
'edit book pages' => 'edit any book content',
'edit own book pages' => 'edit own book content',
'see printer-friendly version' => 'access printer-friendly version',
);
// Loop over all the roles, and do the necessary transformations.
$query = db_query("SELECT rid, perm FROM {permission} ORDER BY rid");
while ($role = db_fetch_object($query)) {
// Replace all the old permissions with the corresponding new permissions.
$fixed_perm = strtr($role->perm, $replace);
// If the user could previously create book pages, they should get the new
// 'add content to books' permission.
if (strpos($role->perm, 'create book pages') !== FALSE) {
$fixed_perm .= ', add content to books';
}
// Only save if the permissions have changed.
if ($fixed_perm != $role->perm) {
$ret[] = update_sql("UPDATE {permission} SET perm = '$fixed_perm' WHERE rid = $role->rid");
}
}
// Determine whether there are any existing nodes in the book hierarchy.
if (db_result(db_query("SELECT COUNT(*) FROM {book}"))) {
// Temporary table for the old book hierarchy; we'll discard revision info.
$schema['book_temp'] = array(
'fields' => array(
'nid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
'parent' => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
'weight' => array('type' => 'int', 'not null' => TRUE, 'default' => 0, 'size' => 'tiny')
),
'indexes' => array(
'parent' => array('parent')
),
'primary key' => array('nid'),
);
db_create_table($ret, 'book_temp', $schema['book_temp']);
// Insert each node in the old table into the temporary table.
$ret[] = update_sql("INSERT INTO {book_temp} (nid, parent, weight) SELECT b.nid, b.parent, b.weight FROM {book} b INNER JOIN {node} n on b.vid = n.vid");
$ret[] = update_sql("DROP TABLE {book}");
db_create_table($ret, 'book', $schema['book']);
$_SESSION['book_update_6000_orphans']['from'] = 0;
$_SESSION['book_update_6000'] = array();
$result = db_query("SELECT * from {book_temp} WHERE parent = 0");
// Collect all books - top-level nodes.
while ($a = db_fetch_array($result)) {
$_SESSION['book_update_6000'][] = $a;
}
$ret['#finished'] = FALSE;
return $ret;
}
else {
// No exising nodes in the hierarchy, so drop the table and re-create it.
$ret[] = update_sql("DROP TABLE {book}");
db_create_table($ret, 'book', $schema['book']);
return $ret;
}
}
elseif ($_SESSION['book_update_6000_orphans']) {
// Do the first batched part of the update - collect orphans.
$update_count = 400; // Update this many at a time
$result = db_query_range("SELECT * FROM {book_temp}", $_SESSION['book_update_6000_orphans']['from'], $update_count);
$has_rows = FALSE;
// Go through the next $update_count book pages and locate the orphans.
while ($book = db_fetch_array($result)) {
$has_rows = TRUE;
// Orphans are defined as nodes whose parent does not exist in the table.
if ($book['parent'] && !db_result(db_query("SELECT COUNT(*) FROM {book_temp} WHERE nid = %d", $book['parent']))) {
if (empty($_SESSION['book_update_6000_orphans']['book'])) {
// The first orphan becomes the parent for all other orphans.
$book['parent'] = 0;
$_SESSION['book_update_6000_orphans']['book'] = $book;
$ret[] = array('success' => TRUE, 'query' => 'Relocated orphan book pages.');
}
else {
// Re-assign the parent value of the book, and add it to the stack.
$book['parent'] = $_SESSION['book_update_6000_orphans']['book']['nid'];
$_SESSION['book_update_6000'][] = $book;
}
}
}
if ($has_rows) {
$_SESSION['book_update_6000_orphans']['from'] += $update_count;
}
else {
// Done with this part
if (!empty($_SESSION['book_update_6000_orphans']['book'])) {
// The orphans' parent is added last, so it will be processed first.
$_SESSION['book_update_6000'][] = $_SESSION['book_update_6000_orphans']['book'];
}
$_SESSION['book_update_6000_orphans'] = FALSE;
}
$ret['#finished'] = FALSE;
return $ret;
}
else {
// Do the next batched part of the update
$update_count = 100; // Update this many at a time
while ($update_count && $_SESSION['book_update_6000']) {
// Get the last node off the stack.
$book = array_pop($_SESSION['book_update_6000']);
// Add all of this node's children to the stack
$result = db_query("SELECT * FROM {book_temp} WHERE parent = %d", $book['nid']);
while ($a = db_fetch_array($result)) {
$_SESSION['book_update_6000'][] = $a;
}
if ($book['parent']) {
// If its not a top level page, get its parent's mlid.
$parent = db_fetch_array(db_query("SELECT b.mlid AS plid, b.bid FROM {book} b WHERE b.nid = %d", $book['parent']));
$book = array_merge($book, $parent);
}
else {
// There is not a parent - this is a new book.
$book['plid'] = 0;
$book['bid'] = $book['nid'];
}
$book += array(
'module' => 'book',
'link_path' => 'node/'. $book['nid'],
'router_path' => 'node/%',
'menu_name' => 'book-toc-'. $book['bid'],
);
$book = array_merge($book, db_fetch_array(db_query("SELECT title AS link_title FROM {node} WHERE nid = %d", $book['nid'])));
// Items with depth > MENU_MAX_DEPTH cannot be saved.
if (menu_link_save($book)) {
db_query("INSERT INTO {book} (mlid, nid, bid) VALUES (%d, %d, %d)", $book['mlid'], $book['nid'], $book['bid']);
}
else {
// The depth was greater then MENU_MAX_DEPTH, so attach it to the
// closest valid parent.
$book['plid'] = db_result(db_query("SELECT plid FROM {menu_links} WHERE mlid = %d", $book['plid']));
if (menu_link_save($book)) {
db_query("INSERT INTO {book} (mlid, nid, bid) VALUES (%d, %d, %d)", $book['mlid'], $book['nid'], $book['bid']);
}
}
$update_count--;
}
$ret['#finished'] = FALSE;
}
if (empty($_SESSION['book_update_6000'])) {
$ret['#finished'] = TRUE;
$ret[] = array('success' => TRUE, 'query' => 'Relocated existing book pages.');
$ret[] = update_sql("DROP TABLE {book_temp}");
unset($_SESSION['book_update_6000']);
unset($_SESSION['book_update_6000_orphans']);
}
return $ret;
}
/**
* Implementation of hook_schema().
*/
function book_schema() {
$schema['book'] = array(
'description' => 'Stores book outline information. Uniquely connects each node in the outline to a link in {menu_links}',
'fields' => array(
'mlid' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
'description' => "The book page's {menu_links}.mlid.",
),
'nid' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
'description' => "The book page's {node}.nid.",
),
'bid' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
'description' => "The book ID is the {book}.nid of the top-level page.",
),
),
'primary key' => array('mlid'),
'unique keys' => array(
'nid' => array('nid'),
),
'indexes' => array(
'bid' => array('bid'),
),
);
return $schema;
}

1095
modules/book/book.module Normal file

File diff suppressed because it is too large Load diff

266
modules/book/book.pages.inc Normal file
View file

@ -0,0 +1,266 @@
<?php
/**
* @file
* User page callbacks for the book module.
*/
/**
* Menu callback; prints a listing of all books.
*/
function book_render() {
$book_list = array();
foreach (book_get_books() as $book) {
$book_list[] = l($book['title'], $book['href'], $book['options']);
}
return theme('item_list', $book_list);
}
/**
* Menu callback; Generates various representation of a book page and its children.
*
* The function delegates the generation of output to helper functions.
* The function name is derived by prepending 'book_export_' to the
* given output type. So, e.g., a type of 'html' results in a call to
* the function book_export_html().
*
* @param $type
* A string encoding the type of output requested. The following
* types are currently supported in book module:
*
* - html: HTML (printer friendly output)
*
* Other types may be supported in contributed modules.
* @param $nid
* An integer representing the node id (nid) of the node to export
* @return
* A string representing the node and its children in the book hierarchy
* in a format determined by the $type parameter.
*/
function book_export($type, $nid) {
// Check that the node exists and that the current user has access to it.
$node = node_load($nid);
if (!$node) {
return MENU_NOT_FOUND;
}
if (!node_access('view', $node)) {
return MENU_ACCESS_DENIED;
}
$type = drupal_strtolower($type);
$export_function = 'book_export_'. $type;
if (function_exists($export_function)) {
print call_user_func($export_function, $nid);
}
else {
drupal_set_message(t('Unknown export format.'));
drupal_not_found();
}
}
/**
* This function is called by book_export() to generate HTML for export.
*
* The given node is /embedded to its absolute depth in a top level
* section/. For example, a child node with depth 2 in the hierarchy
* is contained in (otherwise empty) &lt;div&gt; elements
* corresponding to depth 0 and depth 1. This is intended to support
* WYSIWYG output - e.g., level 3 sections always look like level 3
* sections, no matter their depth relative to the node selected to be
* exported as printer-friendly HTML.
*
* @param $nid
* An integer representing the node id (nid) of the node to export.
* @return
* A string containing HTML representing the node and its children in
* the book hierarchy.
*/
function book_export_html($nid) {
if (user_access('access printer-friendly version')) {
$export_data = array();
$node = node_load($nid);
if (isset($node->book)) {
$tree = book_menu_subtree_data($node->book);
$contents = book_export_traverse($tree, 'book_node_export');
return theme('book_export_html', $node->title, $contents, $node->book['depth']);
}
else {
drupal_not_found();
}
}
else {
drupal_access_denied();
}
}
/**
* Menu callback; show the outline form for a single node.
*/
function book_outline($node) {
drupal_set_title(check_plain($node->title));
return drupal_get_form('book_outline_form', $node);
}
/**
* Build the form to handle all book outline operations via the outline tab.
*
* @see book_outline_form_submit()
* @see book_remove_button_submit()
*
* @ingroup forms
*/
function book_outline_form(&$form_state, $node) {
if (!isset($node->book)) {
// The node is not part of any book yet - set default options.
$node->book = _book_link_defaults($node->nid);
}
else {
$node->book['original_bid'] = $node->book['bid'];
}
// Find the depth limit for the parent select.
if (!isset($node->book['parent_depth_limit'])) {
$node->book['parent_depth_limit'] = _book_parent_depth_limit($node->book);
}
$form['#node'] = $node;
$form['#id'] = 'book-outline';
_book_add_form_elements($form, $node);
$form['book']['#collapsible'] = FALSE;
$form['update'] = array(
'#type' => 'submit',
'#value' => $node->book['original_bid'] ? t('Update book outline') : t('Add to book outline'),
'#weight' => 15,
);
$form['remove'] = array(
'#type' => 'submit',
'#value' => t('Remove from book outline'),
'#access' => $node->nid != $node->book['bid'] && $node->book['bid'],
'#weight' => 20,
'#submit' => array('book_remove_button_submit'),
);
return $form;
}
/**
* Button submit function to redirect to removal confirm form.
*
* @see book_outline_form()
*/
function book_remove_button_submit($form, &$form_state) {
$form_state['redirect'] = 'node/'. $form['#node']->nid .'/outline/remove';
}
/**
* Handles book outline form submissions from the outline tab.
*
* @see book_outline_form()
*/
function book_outline_form_submit($form, &$form_state) {
$node = $form['#node'];
$form_state['redirect'] = "node/". $node->nid;
$book_link = $form_state['values']['book'];
if (!$book_link['bid']) {
drupal_set_message(t('No changes were made'));
return;
}
$book_link['menu_name'] = book_menu_name($book_link['bid']);
$node->book = $book_link;
if (_book_update_outline($node)) {
if ($node->book['parent_mismatch']) {
// This will usually only happen when JS is disabled.
drupal_set_message(t('The post has been added to the selected book. You may now position it relative to other pages.'));
$form_state['redirect'] = "node/". $node->nid ."/outline";
}
else {
drupal_set_message(t('The book outline has been updated.'));
}
}
else {
drupal_set_message(t('There was an error adding the post to the book.'), 'error');
}
}
/**
* Menu callback; builds a form to confirm removal of a node from the book.
*
* @see book_remove_form_submit()
*
* @ingroup forms
*/
function book_remove_form(&$form_state, $node) {
$form['#node'] = $node;
$title = array('%title' => $node->title);
if ($node->book['has_children']) {
$description = t('%title has associated child pages, which will be relocated automatically to maintain their connection to the book. To recreate the hierarchy (as it was before removing this page), %title may be added again using the Outline tab, and each of its former child pages will need to be relocated manually.', $title);
}
else {
$description = t('%title may be added to hierarchy again using the Outline tab.', $title);
}
return confirm_form($form, t('Are you sure you want to remove %title from the book hierarchy?', $title), 'node/'. $node->nid, $description, t('Remove'));
}
/**
* Confirm form submit function to remove a node from the book.
*
* @see book_remove_form()
*/
function book_remove_form_submit($form, &$form_state) {
$node = $form['#node'];
if ($node->nid != $node->book['bid']) {
// Only allowed when this is not a book (top-level page).
menu_link_delete($node->book['mlid']);
db_query('DELETE FROM {book} WHERE nid = %d', $node->nid);
drupal_set_message(t('The post has been removed from the book.'));
}
$form_state['redirect'] = 'node/'. $node->nid;
}
/**
* Renders a new parent page select element when the book selection changes.
*
* This function is called via AJAX when the selected book is changed on a node
* or book outline form. It creates a new parent page select element, adds it
* to the cached form, and then returns the rendered element so it can be
* displayed on the form.
*
* @return
* The rendered parent page select element.
*/
function book_form_update() {
$bid = $_POST['book']['bid'];
if ($form = form_get_cache($_POST['form_build_id'], $form_state)) {
// Validate the bid.
if (isset($form['book']['bid']['#options'][$bid])) {
$book_link = $form['#node']->book;
$book_link['bid'] = $bid;
// Get the new options and update the cache.
$form['book']['plid'] = _book_parent_select($book_link);
form_set_cache($_POST['form_build_id'], $form, $form_state);
// Build and render the new select element, then return it in JSON format.
$form_state = array();
$form['#post'] = array();
$form = form_builder($form['form_id']['#value'] , $form, $form_state);
$output = drupal_render($form['book']['plid']);
drupal_json(array('status' => TRUE, 'data' => $output));
}
else {
drupal_json(array('status' => FALSE, 'data' => ''));
}
}
else {
drupal_json(array('status' => FALSE, 'data' => ''));
}
exit();
}