annotate core/modules/book/src/BookExport.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents af1871eacc83
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\book;
Chris@0 4
Chris@18 5 use Drupal\Core\Entity\EntityTypeManagerInterface;
Chris@0 6 use Drupal\node\NodeInterface;
Chris@0 7
Chris@0 8 /**
Chris@0 9 * Provides methods for exporting book to different formats.
Chris@0 10 *
Chris@0 11 * If you would like to add another format, swap this class in container.
Chris@0 12 */
Chris@0 13 class BookExport {
Chris@0 14
Chris@0 15 /**
Chris@0 16 * The node storage.
Chris@0 17 *
Chris@0 18 * @var \Drupal\Core\Entity\EntityStorageInterface
Chris@0 19 */
Chris@0 20 protected $nodeStorage;
Chris@0 21
Chris@0 22 /**
Chris@0 23 * The node view builder.
Chris@0 24 *
Chris@0 25 * @var \Drupal\Core\Entity\EntityViewBuilderInterface
Chris@0 26 */
Chris@0 27 protected $viewBuilder;
Chris@0 28
Chris@0 29 /**
Chris@0 30 * The book manager.
Chris@0 31 *
Chris@0 32 * @var \Drupal\book\BookManagerInterface
Chris@0 33 */
Chris@0 34 protected $bookManager;
Chris@0 35
Chris@0 36 /**
Chris@0 37 * Constructs a BookExport object.
Chris@0 38 *
Chris@18 39 * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
Chris@18 40 * The entity type manager.
Chris@0 41 * @param \Drupal\book\BookManagerInterface $book_manager
Chris@0 42 * The book manager.
Chris@0 43 */
Chris@18 44 public function __construct(EntityTypeManagerInterface $entity_type_manager, BookManagerInterface $book_manager) {
Chris@18 45 $this->nodeStorage = $entity_type_manager->getStorage('node');
Chris@18 46 $this->viewBuilder = $entity_type_manager->getViewBuilder('node');
Chris@0 47 $this->bookManager = $book_manager;
Chris@0 48 }
Chris@0 49
Chris@0 50 /**
Chris@0 51 * Generates HTML for export when invoked by book_export().
Chris@0 52 *
Chris@0 53 * The given node is embedded to its absolute depth in a top level section. For
Chris@0 54 * example, a child node with depth 2 in the hierarchy is contained in
Chris@0 55 * (otherwise empty) <div> elements corresponding to depth 0 and depth 1.
Chris@0 56 * This is intended to support WYSIWYG output; for instance, level 3 sections
Chris@0 57 * always look like level 3 sections, no matter their depth relative to the
Chris@0 58 * node selected to be exported as printer-friendly HTML.
Chris@0 59 *
Chris@0 60 * @param \Drupal\node\NodeInterface $node
Chris@0 61 * The node to export.
Chris@0 62 *
Chris@0 63 * @return array
Chris@0 64 * A render array representing the HTML for a node and its children in the
Chris@0 65 * book hierarchy.
Chris@0 66 *
Chris@0 67 * @throws \Exception
Chris@0 68 * Thrown when the node was not attached to a book.
Chris@0 69 */
Chris@0 70 public function bookExportHtml(NodeInterface $node) {
Chris@0 71 if (!isset($node->book)) {
Chris@0 72 throw new \Exception();
Chris@0 73 }
Chris@0 74
Chris@0 75 $tree = $this->bookManager->bookSubtreeData($node->book);
Chris@0 76 $contents = $this->exportTraverse($tree, [$this, 'bookNodeExport']);
Chris@0 77 return [
Chris@0 78 '#theme' => 'book_export_html',
Chris@0 79 '#title' => $node->label(),
Chris@0 80 '#contents' => $contents,
Chris@0 81 '#depth' => $node->book['depth'],
Chris@0 82 '#cache' => [
Chris@0 83 'tags' => $node->getEntityType()->getListCacheTags(),
Chris@0 84 ],
Chris@0 85 ];
Chris@0 86 }
Chris@0 87
Chris@0 88 /**
Chris@0 89 * Traverses the book tree to build printable or exportable output.
Chris@0 90 *
Chris@0 91 * During the traversal, the callback is applied to each node and is called
Chris@0 92 * recursively for each child of the node (in weight, title order).
Chris@0 93 *
Chris@0 94 * @param array $tree
Chris@0 95 * A subtree of the book menu hierarchy, rooted at the current page.
Chris@0 96 * @param callable $callable
Chris@0 97 * A callback to be called upon visiting a node in the tree.
Chris@0 98 *
Chris@0 99 * @return string
Chris@0 100 * The output generated in visiting each node.
Chris@0 101 */
Chris@0 102 protected function exportTraverse(array $tree, $callable) {
Chris@0 103 // If there is no valid callable, use the default callback.
Chris@0 104 $callable = !empty($callable) ? $callable : [$this, 'bookNodeExport'];
Chris@0 105
Chris@0 106 $build = [];
Chris@0 107 foreach ($tree as $data) {
Chris@0 108 // Note- access checking is already performed when building the tree.
Chris@0 109 if ($node = $this->nodeStorage->load($data['link']['nid'])) {
Chris@0 110 $children = $data['below'] ? $this->exportTraverse($data['below'], $callable) : '';
Chris@0 111 $build[] = call_user_func($callable, $node, $children);
Chris@0 112 }
Chris@0 113 }
Chris@0 114
Chris@0 115 return $build;
Chris@0 116 }
Chris@0 117
Chris@0 118 /**
Chris@0 119 * Generates printer-friendly HTML for a node.
Chris@0 120 *
Chris@0 121 * @param \Drupal\node\NodeInterface $node
Chris@0 122 * The node that will be output.
Chris@0 123 * @param string $children
Chris@0 124 * (optional) All the rendered child nodes within the current node. Defaults
Chris@0 125 * to an empty string.
Chris@0 126 *
Chris@0 127 * @return array
Chris@0 128 * A render array for the exported HTML of a given node.
Chris@0 129 *
Chris@0 130 * @see \Drupal\book\BookExport::exportTraverse()
Chris@0 131 */
Chris@0 132 protected function bookNodeExport(NodeInterface $node, $children = '') {
Chris@0 133 $build = $this->viewBuilder->view($node, 'print', NULL);
Chris@0 134 unset($build['#theme']);
Chris@0 135
Chris@0 136 return [
Chris@0 137 '#theme' => 'book_node_export_html',
Chris@0 138 '#content' => $build,
Chris@0 139 '#node' => $node,
Chris@0 140 '#children' => $children,
Chris@0 141 ];
Chris@0 142 }
Chris@0 143
Chris@0 144 }