Same name and namespace in other branches
  1. 4.6.x modules/book.module \book_nodeapi()
  2. 4.7.x modules/book.module \book_nodeapi()
  3. 5.x modules/book/book.module \book_nodeapi()

Implementation of hook_nodeapi().

Appends book navigation to all nodes in the book, and handles book outline insertions and updates via the node form.

File

modules/book/book.module, line 652
Allows users to structure the pages of a site in a hierarchy or outline.

Code

function book_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
  switch ($op) {
    case 'load':

      // Note - we cannot use book_link_load() because it will call node_load()
      $info['book'] = db_fetch_array(db_query('SELECT * FROM {book} b INNER JOIN {menu_links} ml ON b.mlid = ml.mlid WHERE b.nid = %d', $node->nid));
      if ($info['book']) {
        $info['book']['href'] = $info['book']['link_path'];
        $info['book']['title'] = $info['book']['link_title'];
        $info['book']['options'] = unserialize($info['book']['options']);
        return $info;
      }
      break;
    case 'view':
      if (!$teaser) {
        if (!empty($node->book['bid']) && $node->build_mode == NODE_BUILD_NORMAL) {
          $node->content['book_navigation'] = array(
            '#value' => theme('book_navigation', $node->book),
            '#weight' => 100,
          );
          if ($page) {
            menu_set_active_trail(book_build_active_trail($node->book));
            menu_set_active_menu_name($node->book['menu_name']);
          }
        }
      }
      break;
    case 'presave':

      // Always save a revision for non-administrators.
      if (!empty($node->book['bid']) && !user_access('administer nodes')) {
        $node->revision = 1;
      }

      // Make sure a new node gets a new menu link.
      if (empty($node->nid)) {
        $node->book['mlid'] = NULL;
      }
      break;
    case 'insert':
    case 'update':
      if (!empty($node->book['bid'])) {
        if ($node->book['bid'] == 'new') {

          // New nodes that are their own book.
          $node->book['bid'] = $node->nid;
        }
        $node->book['nid'] = $node->nid;
        $node->book['menu_name'] = book_menu_name($node->book['bid']);
        _book_update_outline($node);
      }
      break;
    case 'delete':
      if (!empty($node->book['bid'])) {
        if ($node->nid == $node->book['bid']) {

          // Handle deletion of a top-level post.
          $result = db_query("SELECT b.nid FROM {menu_links} ml INNER JOIN {book} b on b.mlid = ml.mlid WHERE ml.plid = %d", $node->book['mlid']);
          while ($child = db_fetch_array($result)) {
            $child_node = node_load($child['nid']);
            $child_node->book['bid'] = $child_node->nid;
            _book_update_outline($child_node);
          }
        }
        menu_link_delete($node->book['mlid']);
        db_query('DELETE FROM {book} WHERE mlid = %d', $node->book['mlid']);
      }
      break;
    case 'prepare':

      // Prepare defaults for the add/edit form.
      if (empty($node->book) && (user_access('add content to books') || user_access('administer book outlines'))) {
        $node->book = array();
        if (empty($node->nid) && isset($_GET['parent']) && is_numeric($_GET['parent'])) {

          // Handle "Add child page" links:
          $parent = book_link_load($_GET['parent']);
          if ($parent && $parent['access']) {
            $node->book['bid'] = $parent['bid'];
            $node->book['plid'] = $parent['mlid'];
            $node->book['menu_name'] = $parent['menu_name'];
          }
        }

        // Set defaults.
        $node->book += _book_link_defaults(!empty($node->nid) ? $node->nid : 'new');
      }
      else {
        if (isset($node->book['bid']) && !isset($node->book['original_bid'])) {
          $node->book['original_bid'] = $node->book['bid'];
        }
      }

      // Find the depth limit for the parent select.
      if (isset($node->book['bid']) && !isset($node->book['parent_depth_limit'])) {
        $node->book['parent_depth_limit'] = _book_parent_depth_limit($node->book);
      }
      break;
  }
}