BookOutline.php 3.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
<?php

/**
 * @file
 * Contains \Drupal\book\BookOutline.
 */

namespace Drupal\book;

/**
 * Provides handling to render the book outline.
 */
class BookOutline {

  /**
   * The book manager.
   *
   * @var \Drupal\book\BookManagerInterface
   */
  protected $bookManager;

  /**
   * Constructs a new BookOutline.
   *
   * @param \Drupal\book\BookManagerInterface $book_manager
   *   The book manager.
   */
  public function __construct(BookManagerInterface $book_manager) {
    $this->bookManager = $book_manager;
  }

  /**
   * Fetches the book link for the previous page of the book.
   *
   * @param array $book_link
   *   A fully loaded book link that is part of the book hierarchy.
   *
   * @return array
   *   A fully loaded book link for the page before the one represented in
   *   $book_link.
   */
  public function prevLink(array $book_link) {
    // If the parent is zero, we are at the start of a book.
    if ($book_link['pid'] == 0) {
      return NULL;
    }
    // Assigning the array to $flat resets the array pointer for use with each().
    $flat = $this->bookManager->bookTreeGetFlat($book_link);
    $curr = NULL;
    do {
      $prev = $curr;
      list($key, $curr) = each($flat);
    } while ($key && $key != $book_link['nid']);

    if ($key == $book_link['nid']) {
      // The previous page in the book may be a child of the previous visible link.
      if ($prev['depth'] == $book_link['depth']) {
        // The subtree will have only one link at the top level - get its data.
        $tree = $this->bookManager->bookSubtreeData($prev);
        $data = array_shift($tree);
        // The link of interest is the last child - iterate to find the deepest one.
        while ($data['below']) {
          $data = end($data['below']);
        }
        $this->bookManager->bookLinkTranslate($data['link']);
        return $data['link'];
      }
      else {
        $this->bookManager->bookLinkTranslate($prev);
        return $prev;
      }
    }
  }

  /**
   * Fetches the book link for the next page of the book.
   *
   * @param array $book_link
   *   A fully loaded book link that is part of the book hierarchy.
   *
   * @return array
   *   A fully loaded book link for the page after the one represented in
   *   $book_link.
   */
  public function nextLink(array $book_link) {
    // Assigning the array to $flat resets the array pointer for use with each().
    $flat = $this->bookManager->bookTreeGetFlat($book_link);
    do {
      list($key,) = each($flat);
    } while ($key && $key != $book_link['nid']);

    if ($key == $book_link['nid']) {
      $next = current($flat);
      if ($next) {
        $this->bookManager->bookLinkTranslate($next);
      }
      return $next;
    }
  }

  /**
   * Formats the book links for the child pages of the current page.
   *
   * @param array $book_link
   *   A fully loaded book link that is part of the book hierarchy.
   *
   * @return array
   *   HTML for the links to the child pages of the current page.
   */
  public function childrenLinks(array $book_link) {
    $flat = $this->bookManager->bookTreeGetFlat($book_link);

    $children = array();

    if ($book_link['has_children']) {
      // Walk through the array until we find the current page.
      do {
        $link = array_shift($flat);
      } while ($link && ($link['nid'] != $book_link['nid']));
      // Continue though the array and collect the links whose parent is this page.
      while (($link = array_shift($flat)) && $link['pid'] == $book_link['nid']) {
        $data['link'] = $link;
        $data['below'] = '';
        $children[] = $data;
      }
    }

    if ($children) {
      $elements = $this->bookManager->bookTreeOutput($children);
      return drupal_render($elements);
    }
    return '';
  }

}