2007-09-11 17:35:58 +00:00
< ? php
// $Id$
/**
* @ 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' ]);
}
2009-10-09 01:00:08 +00:00
return theme ( 'item_list' , array ( 'items' => $book_list ));
2007-09-11 17:35:58 +00:00
}
/**
* 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 ) {
$type = drupal_strtolower ( $type );
2008-04-14 17:48:46 +00:00
$export_function = 'book_export_' . $type ;
2007-09-11 17:35:58 +00:00
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' )) {
2007-11-04 14:29:09 +00:00
$export_data = array ();
2007-09-11 17:35:58 +00:00
$node = node_load ( $nid );
if ( isset ( $node -> book )) {
$tree = book_menu_subtree_data ( $node -> book );
2007-11-04 14:29:09 +00:00
$contents = book_export_traverse ( $tree , 'book_node_export' );
2007-09-11 17:35:58 +00:00
}
2008-05-15 21:19:24 +00:00
2010-01-09 21:54:01 +00:00
return theme ( 'book_export_html' , array ( 'title' => $node -> title , 'contents' => $contents , 'depth' => $node -> book [ 'depth' ]));
2007-09-11 17:35:58 +00:00
}
else {
drupal_access_denied ();
}
}
/**
* Menu callback ; show the outline form for a single node .
*/
2009-11-08 10:02:41 +00:00
function book_outline ( $node ) {
2010-01-09 21:54:01 +00:00
drupal_set_title ( $node -> title );
2007-09-11 17:35:58 +00:00
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
*/
2009-11-08 10:02:41 +00:00
function book_outline_form ( $form , & $form_state , $node ) {
2007-09-11 17:35:58 +00:00
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' ];
}
2008-05-15 21:19:24 +00:00
2007-09-11 17:35:58 +00:00
// 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' ;
2009-11-18 18:51:11 +00:00
_book_add_form_elements ( $form , $form_state , $node );
2007-09-11 17:35:58 +00:00
$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 ()
*/
2007-12-22 23:24:26 +00:00
function book_remove_button_submit ( $form , & $form_state ) {
2008-04-14 17:48:46 +00:00
$form_state [ 'redirect' ] = 'node/' . $form [ '#node' ] -> nid . '/outline/remove' ;
2007-09-11 17:35:58 +00:00
}
/**
* Handles book outline form submissions from the outline tab .
*
* @ see book_outline_form ()
*/
function book_outline_form_submit ( $form , & $form_state ) {
$node = $form [ '#node' ];
2008-04-14 17:48:46 +00:00
$form_state [ 'redirect' ] = " node/ " . $node -> nid ;
2007-09-11 17:35:58 +00:00
$book_link = $form_state [ 'values' ][ 'book' ];
if ( ! $book_link [ 'bid' ]) {
drupal_set_message ( t ( 'No changes were made' ));
2008-05-15 21:19:24 +00:00
2007-09-11 17:35:58 +00:00
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.' ));
2008-04-14 17:48:46 +00:00
$form_state [ 'redirect' ] = " node/ " . $node -> nid . " /outline " ;
2007-09-11 17:35:58 +00:00
}
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
*/
2009-11-08 10:02:41 +00:00
function book_remove_form ( $form , & $form_state , $node ) {
2007-09-11 17:35:58 +00:00
$form [ '#node' ] = $node ;
2010-01-09 21:54:01 +00:00
$title = array ( '%title' => $node -> title );
2007-09-11 17:35:58 +00:00
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 );
}
2008-04-14 17:48:46 +00:00
return confirm_form ( $form , t ( 'Are you sure you want to remove %title from the book hierarchy?' , $title ), 'node/' . $node -> nid , $description , t ( 'Remove' ));
2007-09-11 17:35:58 +00:00
}
/**
* 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' ]);
2008-11-16 15:02:45 +00:00
db_delete ( 'book' )
-> condition ( 'nid' , $node -> nid )
-> execute ();
2007-09-11 17:35:58 +00:00
drupal_set_message ( t ( 'The post has been removed from the book.' ));
}
2008-04-14 17:48:46 +00:00
$form_state [ 'redirect' ] = 'node/' . $node -> nid ;
2007-09-11 17:35:58 +00:00
}
/**
* AJAX callback to replace the book parent select options .
*
2008-12-20 18:24:41 +00:00
* This function is called when the selected book is changed . It updates the
2007-09-11 17:35:58 +00:00
* cached form ( either the node form or the book outline form ) and returns
* rendered output to be used to replace the select containing the possible
* parent pages in the newly selected book .
*
* @ param $build_id
* The form ' s build_id .
* @ param $bid
* A bid from from among those in the form ' s book select .
* @ return
* Prints the replacement HTML in JSON format .
*/
2007-10-15 19:33:27 +00:00
function book_form_update () {
2009-08-17 07:12:16 +00:00
// Load the form based upon the $_POST data sent via the ajax call.
list ( $form , $form_state ) = ajax_get_form ();
$commands = array ();
2007-10-15 19:33:27 +00:00
$bid = $_POST [ 'book' ][ 'bid' ];
2009-08-17 07:12:16 +00:00
// 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 ( $form [ 'values' ][ 'form_build_id' ], $form , $form_state );
// Build and render the new select element, then return it in JSON format.
$form_state = array ();
$form = form_builder ( $form [ 'form_id' ][ '#value' ], $form , $form_state );
$commands [] = ajax_command_replace ( NULL , drupal_render ( $form [ 'book' ][ 'plid' ]));
2007-10-15 19:33:27 +00:00
}
2009-08-17 07:12:16 +00:00
2009-10-15 14:07:30 +00:00
// @todo: We could and should just return $form['book']['plid'] and skip the
// ajax_command_replace() above. But for now, this provides a test case of
// returning an AJAX commands array.
return array ( '#type' => 'ajax_commands' , '#ajax_commands' => $commands );
2007-09-11 17:35:58 +00:00
}