BookBreadcrumbBuilder.php 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. <?php
  2. namespace Drupal\book;
  3. use Drupal\Core\Breadcrumb\Breadcrumb;
  4. use Drupal\Core\Breadcrumb\BreadcrumbBuilderInterface;
  5. use Drupal\Core\Entity\EntityTypeManagerInterface;
  6. use Drupal\Core\Link;
  7. use Drupal\Core\Routing\RouteMatchInterface;
  8. use Drupal\Core\Session\AccountInterface;
  9. use Drupal\Core\StringTranslation\StringTranslationTrait;
  10. use Drupal\node\NodeInterface;
  11. /**
  12. * Provides a breadcrumb builder for nodes in a book.
  13. */
  14. class BookBreadcrumbBuilder implements BreadcrumbBuilderInterface {
  15. use StringTranslationTrait;
  16. /**
  17. * The node storage.
  18. *
  19. * @var \Drupal\Core\Entity\EntityStorageInterface
  20. */
  21. protected $nodeStorage;
  22. /**
  23. * The current user account.
  24. *
  25. * @var \Drupal\Core\Session\AccountInterface
  26. */
  27. protected $account;
  28. /**
  29. * Constructs the BookBreadcrumbBuilder.
  30. *
  31. * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
  32. * The entity type manager service.
  33. * @param \Drupal\Core\Session\AccountInterface $account
  34. * The current user account.
  35. */
  36. public function __construct(EntityTypeManagerInterface $entity_type_manager, AccountInterface $account) {
  37. $this->nodeStorage = $entity_type_manager->getStorage('node');
  38. $this->account = $account;
  39. }
  40. /**
  41. * {@inheritdoc}
  42. */
  43. public function applies(RouteMatchInterface $route_match) {
  44. $node = $route_match->getParameter('node');
  45. return $node instanceof NodeInterface && !empty($node->book);
  46. }
  47. /**
  48. * {@inheritdoc}
  49. */
  50. public function build(RouteMatchInterface $route_match) {
  51. $book_nids = [];
  52. $breadcrumb = new Breadcrumb();
  53. $links = [Link::createFromRoute($this->t('Home'), '<front>')];
  54. $book = $route_match->getParameter('node')->book;
  55. $depth = 1;
  56. // We skip the current node.
  57. while (!empty($book['p' . ($depth + 1)])) {
  58. $book_nids[] = $book['p' . $depth];
  59. $depth++;
  60. }
  61. $parent_books = $this->nodeStorage->loadMultiple($book_nids);
  62. if (count($parent_books) > 0) {
  63. $depth = 1;
  64. while (!empty($book['p' . ($depth + 1)])) {
  65. if (!empty($parent_books[$book['p' . $depth]]) && ($parent_book = $parent_books[$book['p' . $depth]])) {
  66. $access = $parent_book->access('view', $this->account, TRUE);
  67. $breadcrumb->addCacheableDependency($access);
  68. if ($access->isAllowed()) {
  69. $breadcrumb->addCacheableDependency($parent_book);
  70. $links[] = Link::createFromRoute($parent_book->label(), 'entity.node.canonical', ['node' => $parent_book->id()]);
  71. }
  72. }
  73. $depth++;
  74. }
  75. }
  76. $breadcrumb->setLinks($links);
  77. $breadcrumb->addCacheContexts(['route.book_navigation']);
  78. return $breadcrumb;
  79. }
  80. }