<?php

/**
 * @file
 * This is the module to create a drop-down menu for the core toolbar.
 */

use Drupal\Core\Menu\MenuTreeParameters;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Url;
use Drupal\Component\Utility\Html;

/**
 * Implements hook_toolbar_alter().
 */
function admin_toolbar_toolbar_alter(&$items) {
  $items['administration']['tray']['toolbar_administration']['#pre_render'] = ['admin_toolbar_prerender_toolbar_administration_tray'];
  $items['administration']['#attached']['library'][] = 'admin_toolbar/toolbar.tree';
}

/**
 * Implements hook_help().
 */
function admin_toolbar_help($route_name, RouteMatchInterface $route_match) {
  switch ($route_name) {
    case 'help.page.admin_toolbar':
      $variables = [
        ':toolbar' => Url::fromRoute('help.page', ['name' => 'toolbar'])->toString(),
        ':automated_cron' => (\Drupal::moduleHandler()->moduleExists('automated_cron')) ? Url::fromRoute('help.page', ['name' => 'automated_cron'])->toString() : '#',
      ];

      $output = '';
      $output .= '<h3>' . t('About') . '</h3>';
      $output .= '<p>' . t('The Admin Toolbar module enhances the <a href=":toolbar">Toolbar</a> module by providing fast access to all the administrative links at the top of your site. Admin Toolbar remains a very "lightweight" module by closely integrating with all Toolbar functionality. It can be used in conjunction with all the sub modules included on Admin Toolbar, for quick access to system commands such as Flush all caches, <a href=":automated_cron">Run cron</a>, Run Updates, etc.', $variables) . '</p>';
      $output .= '<h3>' . t('Uses') . '</h3>';
      $output .= '<p>' . t('The Admin Toolbar greatly improves the user experience for those who regularly interact with the site Toolbar by providing fast, full access to all links in the site Toolbar without having to click to get there.') . '</p>';

      return $output;
  }
}

/**
 * Renders the toolbar's administration tray.
 *
 * This is a clone of core's toolbar_prerender_toolbar_administration_tray()
 * function, which uses setMaxDepth(4) instead of setTopLevelOnly().
 *
 * @param array $element
 *   A renderable array.
 *
 * @return array
 *   The updated renderable array.
 *
 * @see toolbar_prerender_toolbar_administration_tray()
 */
function admin_toolbar_prerender_toolbar_administration_tray(array $element) {
  $menu_tree = \Drupal::service('toolbar.menu_tree');
  $parameters = new MenuTreeParameters();
  $parameters->setRoot('system.admin')->excludeRoot()->setMaxDepth(4)->onlyEnabledLinks();
  $tree = $menu_tree->load(NULL, $parameters);
  $manipulators = [
    ['callable' => 'menu.default_tree_manipulators:checkAccess'],
    ['callable' => 'menu.default_tree_manipulators:generateIndexAndSort'],
    ['callable' => 'toolbar_tools_menu_navigation_links'],
  ];
  $tree = $menu_tree->transform($tree, $manipulators);
  $element['administration_menu'] = $menu_tree->build($tree);

  return $element;
}

/**
 * Adds toolbar-specific attributes to the menu link tree.
 *
 * @param \Drupal\Core\Menu\MenuLinkTreeElement[] $tree
 *   The menu link tree to manipulate.
 *
 * @return \Drupal\Core\Menu\MenuLinkTreeElement[]
 *   The manipulated menu link tree.
 */
function toolbar_tools_menu_navigation_links(array $tree) {
  foreach ($tree as $element) {
    if ($element->subtree) {
      toolbar_tools_menu_navigation_links($element->subtree);
    }
    $link = $element->link;

    // Get the non-localized title to make the icon class.
    $definition = $link->getPluginDefinition();

    $element->options['attributes']['class'][] = 'toolbar-icon';
    $string = strtolower(str_replace(['.', ' ', '_'], ['-', '-', '-'], $definition['id']));
    $element->options['attributes']['class'][] = Html::cleanCssIdentifier('toolbar-icon-' . $string);
    $element->options['attributes']['title'] = $link->getDescription();
  }
  return $tree;
}
