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: }