ultimenu-8.x-2.x-dev/src/UltimenuTree.php

src/UltimenuTree.php
<?php

namespace Drupal\ultimenu;

use Drupal\Component\Utility\Html;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Menu\MenuActiveTrailInterface;
use Drupal\Core\Menu\MenuTreeParameters;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Provides Ultimenu utility methods.
 */
class UltimenuTree implements UltimenuTreeInterface {

  use StringTranslationTrait;

  /**
   * The menu link tree manager.
   *
   * @var \Drupal\Core\Menu\MenuLinkTreeInterface
   */
  protected $menuTree;

  /**
   * The active menu trail service.
   *
   * @var \Drupal\Core\Menu\MenuActiveTrailInterface
   */
  protected $menuActiveTrail;

  /**
   * Drupal\Core\Extension\ModuleHandler definition.
   *
   * @var \Drupal\Core\Extension\ModuleHandler
   */
  protected $moduleHandler;

  /**
   * Constructs a UltimenuTree object.
   */
  public function __construct(
    MenuActiveTrailInterface $menu_active_trail,
    ModuleHandlerInterface $module_handler,
  ) {
    $this->menuActiveTrail = $menu_active_trail;
    $this->moduleHandler = $module_handler;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('menu.active_trail'),
      $container->get('module_handler')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function menuTree() {
    if (!isset($this->menuTree)) {
      $this->menuTree = Ultimenu::service('menu.link_tree');
    }
    return $this->menuTree;
  }

  /**
   * {@inheritdoc}
   */
  public function menuActiveTrail() {
    return $this->menuActiveTrail;
  }

  /**
   * {@inheritdoc}
   */
  public function getMenus(array $menus = []) {
    $custom_menus = [];
    if ($menus) {
      foreach ($menus as $menu_name => $menu) {
        $custom_menus[$menu_name] = Html::escape($menu->label());
      }
    }

    $excluded_menus = [
      'admin' => $this->t('Administration'),
      'devel' => $this->t('Development'),
      'tools' => $this->t('Tools'),
    ];

    $options = array_diff_key($custom_menus, $excluded_menus);
    asort($options);
    return $options;
  }

  /**
   * {@inheritdoc}
   */
  public function loadMenuTree($menu_name) {
    $parameters = new MenuTreeParameters();
    $parameters->setTopLevelOnly()->onlyEnabledLinks();

    return $this->loadAndTransform($menu_name, $parameters);
  }

  /**
   * {@inheritdoc}
   */
  public function loadSubMenuTree(array $config) {
    $build = [];
    $level = 1;
    $depth = 4;
    $menu_name = $config['menu_name'];
    $link_id = $config['mlid'];
    $title = $config['title'];
    $collapsible = $config['submenu_collapsible'] ?? FALSE;

    $parameters = $this->menuTree()->getCurrentRouteMenuTreeParameters($menu_name);
    $parameters->setRoot($link_id)->excludeRoot()->onlyEnabledLinks();
    $parameters->setMaxDepth(min($level + $depth - 1, $this->menuTree()->maxDepth()));
    $tree = $this->loadAndTransform($menu_name, $parameters, FALSE);

    if ($tree) {
      $content = $this->menuTree()->build($tree);
      $css_name = Html::cleanCssIdentifier(mb_strtolower($menu_name . '-' . $title));
      $classes = ['ultimenusub', 'ultimenusub--' . $css_name];

      if (!empty($content['#items'])) {
        if ($collapsible) {
          $classes[] = 'ultimenusub--collapsible';
        }

        $this->modifyItems($content['#items'], $config);
      }

      $build['content'] = $content;
      $build['#attributes']['class'] = $classes;
      $build['#theme_wrappers'][] = 'container';
    }

    return $build;
  }

  /**
   * Modifies sub-menu items.
   */
  private function modifyItems(array &$items, array $config): void {
    $collapsible = $config['submenu_collapsible'] ?? FALSE;

    foreach ($items as &$item) {
      $li_classes = ['ultimenu__item'];

      // Might be removed by some module.
      if ($url = $item['url'] ?? NULL) {
        $url->mergeOptions([
          'attributes' =>
            ['class' => ['ultimenu__link']],
        ]);
      }

      if ($item['is_expanded']) {
        $subtitle = $item['title'];

        if ($collapsible) {
          $li_classes[] = 'is-uitem-collapsible';
          $subtitle .= Ultimenu::CARET;
        }

        $item['title'] = [
          '#markup' => $subtitle,
          '#allowed_tags' => Ultimenu::TAGS,
        ];

        $subitems = &$item['below'];
        if ($subitems) {
          $this->modifyItems($subitems, $config);
        }
      }

      // Ensures we have something in case overriden.
      $item['attributes']->addClass($li_classes);
    }
  }

  /**
   * Load and transform a menu tree.
   */
  private function loadAndTransform($menu_name, $parameters, $flatten = TRUE) {
    $tree = $this->menuTree()->load($menu_name, $parameters);

    $manipulators = [
      ['callable' => 'menu.default_tree_manipulators:checkAccess'],
      ['callable' => 'menu.default_tree_manipulators:generateIndexAndSort'],
    ];

    if ($flatten) {
      $manipulators[] = [
        'callable' => 'menu.default_tree_manipulators:flatten',
      ];
    }

    if ($this->moduleHandler->moduleExists('menu_manipulator')) {
      $manipulators[] = ['callable' => 'menu_manipulator.menu_tree_manipulators:filterTreeByCurrentLanguage'];
    }

    return $this->menuTree()->transform($tree, $manipulators);
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc