3 namespace Drupal\devel;
5 use Drupal\Core\Cache\CacheableMetadata;
6 use Drupal\Core\Config\ConfigFactoryInterface;
7 use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
8 use Drupal\Core\Menu\MenuLinkTreeInterface;
9 use Drupal\Core\Menu\MenuTreeParameters;
10 use Drupal\Core\Session\AccountProxyInterface;
11 use Drupal\Core\StringTranslation\StringTranslationTrait;
13 use Symfony\Component\DependencyInjection\ContainerInterface;
16 * Toolbar integration handler.
18 class ToolbarHandler implements ContainerInjectionInterface {
20 use StringTranslationTrait;
23 * The menu link tree service.
25 * @var \Drupal\Core\Menu\MenuLinkTreeInterface
27 protected $menuLinkTree;
30 * The devel toolbar config.
32 * @var \Drupal\Core\Config\ImmutableConfig
39 * @var \Drupal\Core\Session\AccountProxyInterface
44 * ToolbarHandler constructor.
46 * @param \Drupal\Core\Menu\MenuLinkTreeInterface $menu_link_tree
47 * The menu link tree service.
48 * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
50 * @param \Drupal\Core\Session\AccountProxyInterface $account
53 public function __construct(MenuLinkTreeInterface $menu_link_tree, ConfigFactoryInterface $config_factory, AccountProxyInterface $account) {
54 $this->menuLinkTree = $menu_link_tree;
55 $this->config = $config_factory->get('devel.toolbar.settings');
56 $this->account = $account;
62 public static function create(ContainerInterface $container) {
64 $container->get('toolbar.menu_tree'),
65 $container->get('config.factory'),
66 $container->get('current_user')
74 * The devel toolbar items render array.
78 public function toolbar() {
81 'contexts' => ['user.permissions'],
85 if ($this->account->hasPermission('access devel information')) {
87 '#type' => 'toolbar_item',
91 '#title' => $this->t('Devel'),
92 '#url' => Url::fromRoute('devel.admin_settings'),
94 'title' => $this->t('Development menu'),
95 'class' => ['toolbar-icon', 'toolbar-icon-devel'],
99 '#heading' => $this->t('Development menu'),
101 // Currently devel menu is uncacheable, so instead of poisoning the
102 // entire page cache we use a lazy builder.
103 // @see \Drupal\devel\Plugin\Menu\DestinationMenuLink
104 // @see \Drupal\devel\Plugin\Menu\RouteDetailMenuItem
105 '#lazy_builder' => [ToolbarHandler::class . ':lazyBuilder', []],
106 // Force the creation of the placeholder instead of rely on the
107 // automatical placeholdering or otherwise the page results
108 // uncacheable when max-age 0 is bubbled up.
109 '#create_placeholder' => TRUE,
113 '#title' => $this->t('Configure'),
114 '#url' => Url::fromRoute('devel.toolbar.settings_form'),
116 'attributes' => ['class' => ['edit-devel-toolbar']],
121 'library' => 'devel/devel-toolbar',
130 * Lazy builder callback for the devel menu toolbar.
133 * The renderable array rapresentation of the devel menu.
135 public function lazyBuilder() {
136 $parameters = new MenuTreeParameters();
137 $parameters->onlyEnabledLinks()->setTopLevelOnly();
139 $tree = $this->menuLinkTree->load('devel', $parameters);
142 ['callable' => 'menu.default_tree_manipulators:checkAccess'],
143 ['callable' => 'menu.default_tree_manipulators:generateIndexAndSort'],
144 ['callable' => ToolbarHandler::class . ':processTree'],
146 $tree = $this->menuLinkTree->transform($tree, $manipulators);
148 $build = $this->menuLinkTree->build($tree);
150 CacheableMetadata::createFromRenderArray($build)
151 ->addCacheableDependency($this->config)
158 * Adds toolbar-specific attributes to the menu link tree.
160 * @param \Drupal\Core\Menu\MenuLinkTreeElement[] $tree
161 * The menu link tree to manipulate.
163 * @return \Drupal\Core\Menu\MenuLinkTreeElement[]
164 * The manipulated menu link tree.
166 public function processTree(array $tree) {
167 $visible_items = $this->config->get('toolbar_items') ?: [];
169 foreach ($tree as $element) {
170 $plugin_id = $element->link->getPluginId();
171 if (!in_array($plugin_id, $visible_items)) {
172 // Add a class that allow to hide the non prioritized menu items when
173 // the toolbar has horizontal orientation.
174 $element->options['attributes']['class'][] = 'toolbar-horizontal-item-hidden';