You can also define child pages by content-type in !content-type-settings in the BookMadeSimple section',array('!content-type-settings' => l(t('content type settings'),'admin/content/types/list'))); return $output; break; } } function book_made_simple_init() { if (! variable_get('book_made_simple_admin_use_css',false)) { drupal_add_css(drupal_get_path('module', 'book_made_simple') . '/book_made_simple.css'); } } function book_made_simple_perm() { return array('show book reorder tab','show core Outline form element'); } /** * Implementation of hook_menu(). */ function book_made_simple_menu() { $items = array(); $items['admin/settings/book_made_simple'] = array( 'title' => t('BookMadeSimple settings'), 'page callback' => 'drupal_get_form', 'page arguments' => array('book_made_simple_settings_form'), 'access arguments' => array('administer site configuration'), 'description' => t('BookMadeSimple module settings.'), 'type' => MENU_NORMAL_ITEM, ); $items['node/%node/reorder'] = array( 'title' => 'Rearrange', 'page callback' => 'book_made_simple_reorder', 'page arguments' => array(1), 'access callback' => 'is_reorder_access', 'access arguments' => array(1), 'type' => MENU_LOCAL_TASK, 'weight' => 2 ); /* $items['node/%node/outline'] = array( 'title' => 'Outline', 'page callback' => 'book_outline', 'page arguments' => array(1), 'access arguments' => array('show core Outline tab'), 'type' => MENU_LOCAL_TASK, 'weight' => 10, 'file' => 'book.pages.inc', 'file path' => drupal_get_path('module','book') ); */ return $items; } function is_outline_access($node = NULL) { if (isset($node->nid) && ! user_access('administer book outlines')) { return false; } return user_access("show core Outline form element"); } /** * Return access rights for book */ function is_reorder_access($node = NULL) { if (isset($node->book) && $node->book['bid'] > 0) { if (! _book_outline_access($node) || ! user_access('show book reorder tab')) { return false; } // Cheching permissions according to rules/ $book = $node->book; $linkVisibilty = variable_get('book_made_simple_reorder_link', "0"); $allowed = true; if ($linkVisibilty == "0") { $mainBook = $book; if ($book['nid'] != $book['bid']) { $mainBook = node_load($book['bid'])->book; } $allowed = (count(book_toc($mainBook['bid'],array(),9999)) > 2); } return $allowed; } return false; } /** * Shortcut to reorder book page */ function book_made_simple_reorder($node) { drupal_goto("admin/content/book/" . $node->book['bid'] , "destination=node/" . $node->nid); } /** * Implementation of hook_settings_form). */ function book_made_simple_settings_form() { $types = node_get_types("names"); $form['book_made_simple'] = array( '#type' => 'fieldset', '#attributes' => array('class' => 'allowed-child'), '#title' => t('Select node types that can be included in a book'), '#collapsible' => TRUE, '#collapsed' => FALSE, '#description' => t('Check content-type that can be included as child in a book. This selection is overriden by selection in content-type settings.'), ); $form['book_made_simple']['book_made_simple_add_types'] = array( '#type' => 'checkboxes', '#options' => $types, '#multiple' => true, '#default_value' => variable_get('book_made_simple_add_types', array()), ); $form['book_made_simple2'] = array( '#type' => 'fieldset', '#attributes' => array('class' => 'auto-main'), '#title' => t('Select node types to auto-create main book page'), '#collapsible' => TRUE, '#collapsed' => FALSE, '#description' => t('Check content-types if you want they will automatically be created as main page of a book.'), ); $form['book_made_simple2']['book_made_simple_auto_main_page'] = array( '#type' => 'checkboxes', '#options' => $types, '#multiple' => true, '#default_value' => variable_get('book_made_simple_auto_main_page', array()), ); $form['book_made_simple3'] = array( '#type' => 'fieldset', '#attributes' => array('class' => 'other-settings'), '#title' => t('Other settings'), '#collapsible' => TRUE, '#collapsed' => FALSE, ); $form['book_made_simple3']['book_made_simple_limit_depth'] = array( '#type' => 'textfield', '#title' => t('Default limit book depth'), '#default_value' => variable_get('book_made_simple_limit_depth', 99), '#description' => t('Maximum number of childs for a book'), '#maxlength' => 2, '#size' => 2, ); $form['book_made_simple3']['book_made_simple_admin_use_css'] = array( '#type' => 'checkbox', '#title' => t('Disable BMS settings layout'), '#default_value' => variable_get('book_made_simple_admin_use_css', false), '#description' => t('Check to disable BMS layout (content types as columns).'), ); $form['book_made_simple3']['book_made_simple_hide_default_add_child'] = array( '#type' => 'checkbox', '#title' => t('Hide default add child link'), '#default_value' => variable_get('book_made_simple_hide_default_add_child', true), '#description' => t('Check to hide default add child page link.'), ); $form['book_made_simple3']['book_made_simple_child_list_style'] = array( '#type' => 'radios', '#title' => t('Style of child list'), '#options' => array("DDLIST" => t("Dropdown listbox"),"LI" => t("Unordered list"),"THEME" => t("Themeable function")), '#default_value' => variable_get('book_made_simple_child_list_style', "DDLIST"), '#description' => t('Choose the style of the child list.'), ); $form['book_made_simple3']['book_made_simple_child_list_style_position'] = array( '#type' => 'select', '#title' => t('Child list position in links area'), '#options' => array("FIRST" => t("First"),"LAST" => t("Last")), '#default_value' => variable_get('book_made_simple_child_list_style_position', "FIRST"), '#description' => t('Choose where to print child list in the links area'), ); $form['book_made_simple3']['book_made_simple_reorder_link'] = array( '#type' => 'radios', '#title' => t('Show reorder tab even if book is empty'), '#options' => array("0"=>t("No"),"1" => t("Yes")), '#default_value' => variable_get('book_made_simple_reorder_link', "0"), '#description' => t('Show reorder tab even if book is empty. A book is considered empty when it has less than 2 subpages. In this case, does reordering make sense ?'), ); return system_settings_form($form); } /** * Implementation of hook_form_alter(). */ function book_made_simple_form_alter(&$form, $form_state, $form_id) { if (isset($form['type']) && isset($form['#node']) && $form['type']['#value'] .'_node_form' == $form_id) { $node = $form['#node']; $type = $form['type']['#value']; // Not a book => Nothing to do if (! isset($node->book)) return; // 1 : Main page book. Verify if not forbidden $isMainForbidden = (array_key_exists($type, variable_get('book_made_simple_forbid_main_page_creation', array()))); $isForbidden = ($isMainForbidden && $node->book['bid']== 0); if ($isMainForbidden && $user->uid != 1) { //$form['book']['bid']['#default_value'] = 0; $nid = isset($node->nid) ? $node->nid : 'new'; unset($form['book']['bid']['#options'][$nid]); $form['#node']->nid = isset($form['#node']->nid) ? $form['#node']->nid : '0'; $form['#node']->book['original_bid'] = $form['#node']->nid; } if (arg(1) == "add" && ! array_key_exists("parent", $_GET)) { $isOnlyForBook = array_key_exists($type, variable_get("book_made_simple_only_on_books",array())); if ($isOnlyForBook) { $form = _book_made_simple_print_error("This type can't be created outside a book",$form['#id']); $form_state['process_input'] = FALSE; return; } } // 2 : Add child page : Verify if parent allowed if (arg(1) == "add" && array_key_exists("parent", $_GET)) { $parent = book_link_load($_GET['parent']); if (isset($parent)) { $parentNode = node_load($parent['nid']); $parentType = $parentNode->type; $allowedChilds = variable_get('book_made_simple_for_type_' . $parentType,array()); if (count($allowedChilds) > 0 && ! in_array($type, $allowedChilds)) { $form = _book_made_simple_print_error("This type is not allowed as child for type $parentType",$form['#id']); $form_state['process_input'] = FALSE; return; } } } //3 : show/hide Outline section $book = $node->book; if (is_outline_access($node)) { if (isset($node->nid) && is_reorder_access($node)) { $form['book']['reorder'] = array( '#type' => 'item', '#value' => l(t("Reorder the book"), "admin/content/book/" . $book['bid'] , array('query' => array("destination" => "node/" . $node->nid))), '#description' => t("Shortcut to reorder the entire book"), '#weight' => 10, ); } } else { $form['book']['#type'] = 'hidden'; // $form['book']['bid']['#default_value'] = 0; } if ($node->status == 0) { $form['book']['bid']['#options'][$node->nid] = $node->title; } return $form; } switch ($form["#id"]) { case "node-type-form" : // $type . '_node_settings': $type = $form["#node_type"]->type; $default = array_key_exists($type,variable_get('book_made_simple_auto_main_page',array())); $form['book_made_simple'] = array( '#type' => 'fieldset', '#attributes' => array('class' => 'bms-fieldset'), '#title' => t('BookMadeSimple'), '#collapsible' => TRUE, '#collapsed' => TRUE, ); $form['book_made_simple']['1'] = array( '#attributes' => array('class' => 'allowed-child'), '#type' => 'fieldset', '#title' => t('Select content-types allowed as child.'), '#collapsible' => TRUE, '#collapsed' => FALSE, ); $types = node_get_types("names"); $form['book_made_simple']['1']['book_made_simple_for_type'] = array( '#type' => 'checkboxes', '#options' => $types, '#multiple' => true, '#default_value' => variable_get('book_made_simple_for_type_' . $type, array()), ); $aa = array(); unset($types[$type]); foreach ($types as $ctype => $name) { $a = variable_get('book_made_simple_for_type_' . $ctype, array()); if (array_search($type,$a) !== FALSE) { array_push($aa,$ctype); } } $form['book_made_simple']['2'] = array( '#attributes' => array('class' => 'allowed-child'), '#title' => t('Select content-types allowed as parent'), '#type' => 'fieldset', '#collapsible' => TRUE, '#collapsed' => FALSE, ); $form['book_made_simple']['2']['book_made_simple_for_book'] = array( '#type' => 'checkboxes', '#options' => $types, '#multiple' => true, '#default_value' => $aa, ); $form['book_made_simple']['3'] = array( '#attributes' => array('class' =>'bms-other-settings'), '#type' => 'fieldset', '#collapsible' => TRUE, '#collapsed' => FALSE, ); $varTypes = variable_get('book_made_simple_auto_main_page',array()); $default = (array_key_exists($type, $varTypes) && $varTypes[$type] != "0"); $form['book_made_simple']['3']['book_made_simple_auto_main_page'] = array( '#attributes' => array('style' =>'float:none;clear:both'), '#type' => 'checkbox', '#title' => t('Auto create book main page'), '#default_value' => $default, '#description' => t('Checked will create a new book main page when adding.'), ); $varTypes = variable_get('book_made_simple_forbid_main_page_creation', array()); $default = (array_key_exists($type, $varTypes) && $varTypes[$type] != "0"); $form['book_made_simple']['3']['book_made_simple_forbid_main_page_creation'] = array( '#type' => 'checkbox', '#title' => t('Forbid creation of book main page'), '#default_value' => $default, '#description' => t('Checked will prevent books from being manually created with this content type as main page type.'), ); $varTypes = variable_get('book_made_simple_only_on_books', array()); $default = (array_key_exists($type, $varTypes) && $varTypes[$type] != "0"); $form['book_made_simple']['3']['book_made_simple_only_on_books'] = array( '#type' => 'checkbox', '#title' => t('Content type can only be created inside a book'), '#default_value' => $default, '#description' => t('Checked will prevent this content type be created outside a book.'), ); $varTypes = variable_get('book_made_simple_add_types',array()); $default = (array_key_exists($type, $varTypes) && $varTypes[$type] != "0"); $form['book_made_simple']['3']['book_made_simple_add_types'] = array( '#type' => 'checkbox', '#title' => t('Allow content type as child of default book.'), '#default_value' => $default, '#description' => t('Checked will add this content-type to books where no content-types has been selected.'), ); array_push($form['#submit'],"book_made_simple_form_submit"); break; } // endswitch $form_id } // endfunction book_made_simple_form_alter() /** * Implementation of hook_form_submit(). */ function book_made_simple_form_submit($form, &$form_state) { $values = $form_state["values"]; $text = $values["book_made_simple_auto_main_page"]; $type = $values["type"]; variable_del("book_made_simple_add_types_" . $type); variable_del("book_made_simple_auto_main_page_" . $type); $types = variable_get('book_made_simple_auto_main_page', array()); if ($text != "0") { $types[$type]= $type; } else { unset($types[$type]); } variable_set('book_made_simple_auto_main_page', $types); $text = $values["book_made_simple_only_on_books"]; $type = $values["type"]; $types = variable_get('book_made_simple_only_on_books', array()); if ($text != "0") { $types[$type]= $type; } else { unset($types[$type]); } variable_set('book_made_simple_only_on_books', $types); $text = $values["book_made_simple_forbid_main_page_creation"]; $type = $values["type"]; variable_del("book_made_simple_forbid_main_page_creation_" . $type); $types = variable_get('book_made_simple_forbid_main_page_creation', array()); if ($text != "0") { $types[$type]= $type; } else { unset($types[$type]); } variable_set('book_made_simple_forbid_main_page_creation', $types); $text = $values["book_made_simple_add_types"]; $types = variable_get('book_made_simple_add_types', array()); if ($text != "0") { $types[$type]= $type; } else { unset($types[$type]); } variable_set('book_made_simple_add_types', $types); $text = $values["book_made_simple_for_type"]; if (count($text) == 0) { variable_del("book_made_simple_for_type_" . $type); } $types = node_get_types("names"); $saved = $values["book_made_simple_for_book"]; $a2 = array(); foreach ($types as $ctype => $name) { if ($ctype != $type) { $a = variable_get('book_made_simple_for_type_' . $ctype, array()); $ind = array_search($type,$a); if ($ind !== FALSE) { unset($a[$ind]); } variable_set('book_made_simple_for_type_' . $ctype, $a); } } foreach ($saved as $ctype => $name) { if ($name != "0") { $a = variable_get('book_made_simple_for_type_' . $ctype, array()); $a[$type]= $type; variable_set('book_made_simple_for_type_' . $ctype, $a); } } variable_del("book_made_simple_for_book_" . $type); } /** * Implementation of hook_link(). Add dropdown listbox to links */ function book_made_simple_link($type, $node = null, $teaser = false) { $links = array(); $max_depth = variable_get('book_made_simple_limit_depth',99); if ($type == 'node' && !$teaser && isset($node->book["bid"]) && user_access('add content to books')&& $node->book['depth'] < $max_depth) { $html = ""; $allowedTypes = array(); // Search for content-type for this one $aTypes = variable_get('book_made_simple_for_type_' . $node->type, array()); $style = variable_get('book_made_simple_child_list_style', "DDLIST"); // No content-type, so print all if (count($aTypes) == 0) { $aTypes = variable_get('book_made_simple_add_types', array()); } foreach ($aTypes as $allowedType => $allowedName) { $type = node_get_types("type",$allowedName); if (node_access('create', $type->type)) { $allowedTypes[str_replace("_","-",$type->type)] = $type->name; } } $book_link = $node->book; if (count($allowedTypes) > 0) { asort($allowedTypes,SORT_STRING); if ($style == "LI") { foreach ($allowedTypes as $type => $name ) { $query = array("parent" => $node->book['mlid']); if (module_exists('og')) { $group_node = og_get_group_context(); if ($group_node && og_is_group_member($group_node)) { $query['gids[]'] = $group_node->nid; } } $links['book_made_simple_' . $type] = array( 'title' => t('Add !content-type', array('!content-type' => t($name))), 'href' => "node/add/" . $type, 'query' => $query, ); } } elseif ($style == "DDLIST") { $links['book_made_simple'] = array( 'title' => "" . book_made_simple_add_child_book_content_types_ddlist($allowedTypes, $node) . "", 'html'=>true ); } else { $links['book_made_simple'] = array( 'title' => theme('add_child_book_content_types',$allowedTypes, $node), 'html'=>true ); } } } //$links["book_add_child"] = array(); return $links; } /** * Implementation of hook_theme(). */ function book_made_simple_theme() { return array( 'add_child_book_content_types' => array( 'arguments' => array( 'allowedTypes' => NULL, "node"=>null), ), ); } /** * Themeable function to display alloawed child types of book(). * @param $allowedTypes * Array of allowed child type. * @param $node * Source node * @return * Html code to display allowed child type */ function theme_add_child_book_content_types($allowedTypes, $node) { return ""; } /** * Display alloawed child type as dropdown listbox. */ function book_made_simple_add_child_book_content_types_ddlist($allowedTypes, $node) { $child_type = variable_get('book_child_type', 'book'); $html = ""; foreach ($allowedTypes as $type => $name ) { $html .= ""; } $isCleanUrl = variable_get('clean_url', 0); $url = url("node/add/"); $op = "&"; if ($isCleanUrl) { $op = "?"; } $newUrl = $url ."\" + this.value + \"" . $op . "parent=" . $node->book["mlid"]; if (module_exists('og')) { $group_node = og_get_group_context(); if ($group_node && og_is_group_member($group_node)) { $newUrl .= '&gids[]=' . $group_node->nid; } } return ""; } /** * Implementation of hook_nodeapi(). */ function book_made_simple_nodeapi(&$node, $op, $teaser, $page) { if (empty($node->book["bid"])) { $type = $node->type; switch ($op) { // Node creation case 'insert': $max_depth = variable_get('book_made_simple_limit_depth',99); if ((user_access('add content to books') || user_access('administer book outlines')) && node_access('create', $type) && $node->book['depth'] < $max_depth) { $bookTypes = variable_get('book_made_simple_auto_main_page',array()); $bookType = $bookTypes[$type]; $toCreate = false; if (null != $bookType && $bookType != "0") { $toCreate = true; } if ($toCreate && ! isset($_GET['parent'])) { $node->book["bid"] = $node->nid; $node->book['nid'] = $node->nid; $node->book['module'] = 'book'; $node->book['menu_name'] = book_menu_name($node->book['bid']); $node->book['options'] = array( 'type' => $node->type); _book_update_outline($node); } } break; // Hack for translation module. Adding parent property to automatically select parent book. case "prepare translation": $translation = $node->translation_source; if (isset($translation->book) && (! isset($_GET["parent"]))) { // get parent menu link for the node + language $plid = $translation->book['plid']; $parentPage = book_link_load($plid); if (isset($parentPage) && $parentPage > 0) { $pnid = $parentPage['nid']; if (isset($pnid) && $pnid <> "") { $query= "SELECT bid, mlid FROM {node} n left join {book} b on b.nid = n.nid where tnid= $pnid and language='" . $node->language . "'"; $translatedParent = db_fetch_object(db_query($query)); if ($translatedParent) { $mlid = $translatedParent->mlid; $params = array(); $params[] = "parent=$mlid"; foreach ($_GET as $key => $value) { if ($key == "q") { $path = $value; } else {$params[] = $key . "=" . $value; } } $queryString = implode("&",$params); drupal_goto($path, $queryString); $ok = true; } else { drupal_set_message(t("This node has no translated parent, so no book selected"),"warning"); } } } } break; } } else { switch ($op) { // Hide standard add Child link case 'alter': if ($node->links) { if (variable_get('book_made_simple_hide_default_add_child',true)) { if (array_key_exists("book_add_child",$node->links)) { unset($node->links["book_add_child"]); } } $position = variable_get("book_made_simple_child_list_style_position","FIRST"); if ($position == "FIRST") { if (array_key_exists("book_made_simple",$node->links)) { $a = $node->links["book_made_simple"]; unset($node->links["book_made_simple"]); array_unshift($node->links,$a); } } break; } } } } function book_made_simple_theme_registry_alter(&$theme_registry) { global $theme; $theme_registry['BMS']['menu_item_link'] = $theme_registry['menu_item_link']; // Replace them with our own. These will "preprocess" and call the real functions. $theme_registry['menu_item_link']['function'] = 'book_made_simple_theme_menu_item_link'; } /** * Preprocessor for menu_item_link. * Adds an ID attribute to menu links and helps the module * follow the recursion of menu_tree_output(). */ function book_made_simple_theme_menu_item_link($link) { // Find out which theme function to dispatch to after preprocessing. $registry = theme_get_registry(); $function = $registry['BMS']['menu_item_link']['function']; if ($function) { return $function($link); } return theme_menu_item_link($link); } function _book_made_simple_print_error($message, $formid) { $form = array(); $form['#id'] = $formid . '-node-form'; $form['#tree'] = ""; $form['nid'] = Array('#type' => "value",'#value' => '' ); $form['title'] = Array('#type' => 'item', '#title' => '', '#value' => t($message) ); return $form; }