Chris@0: nodeStorage = $entity_type_manager->getStorage('node');
Chris@18: $this->viewBuilder = $entity_type_manager->getViewBuilder('node');
Chris@0: $this->bookManager = $book_manager;
Chris@0: }
Chris@0:
Chris@0: /**
Chris@0: * Generates HTML for export when invoked by book_export().
Chris@0: *
Chris@0: * The given node is embedded to its absolute depth in a top level section. For
Chris@0: * example, a child node with depth 2 in the hierarchy is contained in
Chris@0: * (otherwise empty)
elements corresponding to depth 0 and depth 1.
Chris@0: * This is intended to support WYSIWYG output; for instance, level 3 sections
Chris@0: * always look like level 3 sections, no matter their depth relative to the
Chris@0: * node selected to be exported as printer-friendly HTML.
Chris@0: *
Chris@0: * @param \Drupal\node\NodeInterface $node
Chris@0: * The node to export.
Chris@0: *
Chris@0: * @return array
Chris@0: * A render array representing the HTML for a node and its children in the
Chris@0: * book hierarchy.
Chris@0: *
Chris@0: * @throws \Exception
Chris@0: * Thrown when the node was not attached to a book.
Chris@0: */
Chris@0: public function bookExportHtml(NodeInterface $node) {
Chris@0: if (!isset($node->book)) {
Chris@0: throw new \Exception();
Chris@0: }
Chris@0:
Chris@0: $tree = $this->bookManager->bookSubtreeData($node->book);
Chris@0: $contents = $this->exportTraverse($tree, [$this, 'bookNodeExport']);
Chris@0: return [
Chris@0: '#theme' => 'book_export_html',
Chris@0: '#title' => $node->label(),
Chris@0: '#contents' => $contents,
Chris@0: '#depth' => $node->book['depth'],
Chris@0: '#cache' => [
Chris@0: 'tags' => $node->getEntityType()->getListCacheTags(),
Chris@0: ],
Chris@0: ];
Chris@0: }
Chris@0:
Chris@0: /**
Chris@0: * Traverses the book tree to build printable or exportable output.
Chris@0: *
Chris@0: * During the traversal, the callback is applied to each node and is called
Chris@0: * recursively for each child of the node (in weight, title order).
Chris@0: *
Chris@0: * @param array $tree
Chris@0: * A subtree of the book menu hierarchy, rooted at the current page.
Chris@0: * @param callable $callable
Chris@0: * A callback to be called upon visiting a node in the tree.
Chris@0: *
Chris@0: * @return string
Chris@0: * The output generated in visiting each node.
Chris@0: */
Chris@0: protected function exportTraverse(array $tree, $callable) {
Chris@0: // If there is no valid callable, use the default callback.
Chris@0: $callable = !empty($callable) ? $callable : [$this, 'bookNodeExport'];
Chris@0:
Chris@0: $build = [];
Chris@0: foreach ($tree as $data) {
Chris@0: // Note- access checking is already performed when building the tree.
Chris@0: if ($node = $this->nodeStorage->load($data['link']['nid'])) {
Chris@0: $children = $data['below'] ? $this->exportTraverse($data['below'], $callable) : '';
Chris@0: $build[] = call_user_func($callable, $node, $children);
Chris@0: }
Chris@0: }
Chris@0:
Chris@0: return $build;
Chris@0: }
Chris@0:
Chris@0: /**
Chris@0: * Generates printer-friendly HTML for a node.
Chris@0: *
Chris@0: * @param \Drupal\node\NodeInterface $node
Chris@0: * The node that will be output.
Chris@0: * @param string $children
Chris@0: * (optional) All the rendered child nodes within the current node. Defaults
Chris@0: * to an empty string.
Chris@0: *
Chris@0: * @return array
Chris@0: * A render array for the exported HTML of a given node.
Chris@0: *
Chris@0: * @see \Drupal\book\BookExport::exportTraverse()
Chris@0: */
Chris@0: protected function bookNodeExport(NodeInterface $node, $children = '') {
Chris@0: $build = $this->viewBuilder->view($node, 'print', NULL);
Chris@0: unset($build['#theme']);
Chris@0:
Chris@0: return [
Chris@0: '#theme' => 'book_node_export_html',
Chris@0: '#content' => $build,
Chris@0: '#node' => $node,
Chris@0: '#children' => $children,
Chris@0: ];
Chris@0: }
Chris@0:
Chris@0: }