5 use Drupal\Core\Entity\EntityManagerInterface;
6 use Drupal\node\NodeInterface;
9 * Provides methods for exporting book to different formats.
11 * If you would like to add another format, swap this class in container.
18 * @var \Drupal\Core\Entity\EntityStorageInterface
20 protected $nodeStorage;
23 * The node view builder.
25 * @var \Drupal\Core\Entity\EntityViewBuilderInterface
27 protected $viewBuilder;
32 * @var \Drupal\book\BookManagerInterface
34 protected $bookManager;
37 * Constructs a BookExport object.
39 * @param \Drupal\Core\Entity\EntityManagerInterface $entityManager
41 * @param \Drupal\book\BookManagerInterface $book_manager
44 public function __construct(EntityManagerInterface $entityManager, BookManagerInterface $book_manager) {
45 $this->nodeStorage = $entityManager->getStorage('node');
46 $this->viewBuilder = $entityManager->getViewBuilder('node');
47 $this->bookManager = $book_manager;
51 * Generates HTML for export when invoked by book_export().
53 * The given node is embedded to its absolute depth in a top level section. For
54 * example, a child node with depth 2 in the hierarchy is contained in
55 * (otherwise empty) <div> elements corresponding to depth 0 and depth 1.
56 * This is intended to support WYSIWYG output; for instance, level 3 sections
57 * always look like level 3 sections, no matter their depth relative to the
58 * node selected to be exported as printer-friendly HTML.
60 * @param \Drupal\node\NodeInterface $node
64 * A render array representing the HTML for a node and its children in the
68 * Thrown when the node was not attached to a book.
70 public function bookExportHtml(NodeInterface $node) {
71 if (!isset($node->book)) {
72 throw new \Exception();
75 $tree = $this->bookManager->bookSubtreeData($node->book);
76 $contents = $this->exportTraverse($tree, [$this, 'bookNodeExport']);
78 '#theme' => 'book_export_html',
79 '#title' => $node->label(),
80 '#contents' => $contents,
81 '#depth' => $node->book['depth'],
83 'tags' => $node->getEntityType()->getListCacheTags(),
89 * Traverses the book tree to build printable or exportable output.
91 * During the traversal, the callback is applied to each node and is called
92 * recursively for each child of the node (in weight, title order).
95 * A subtree of the book menu hierarchy, rooted at the current page.
96 * @param callable $callable
97 * A callback to be called upon visiting a node in the tree.
100 * The output generated in visiting each node.
102 protected function exportTraverse(array $tree, $callable) {
103 // If there is no valid callable, use the default callback.
104 $callable = !empty($callable) ? $callable : [$this, 'bookNodeExport'];
107 foreach ($tree as $data) {
108 // Note- access checking is already performed when building the tree.
109 if ($node = $this->nodeStorage->load($data['link']['nid'])) {
110 $children = $data['below'] ? $this->exportTraverse($data['below'], $callable) : '';
111 $build[] = call_user_func($callable, $node, $children);
119 * Generates printer-friendly HTML for a node.
121 * @param \Drupal\node\NodeInterface $node
122 * The node that will be output.
123 * @param string $children
124 * (optional) All the rendered child nodes within the current node. Defaults
125 * to an empty string.
128 * A render array for the exported HTML of a given node.
130 * @see \Drupal\book\BookExport::exportTraverse()
132 protected function bookNodeExport(NodeInterface $node, $children = '') {
133 $build = $this->viewBuilder->view($node, 'print', NULL);
134 unset($build['#theme']);
137 '#theme' => 'book_node_export_html',
138 '#content' => $build,
140 '#children' => $children,