association-1.0.0-alpha2/modules/association_menu/src/AssociationMenuBuilder.php

modules/association_menu/src/AssociationMenuBuilder.php
<?php

namespace Drupal\association_menu;

use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Template\Attribute;

/**
 * Builds the association menu data into renderable menus for display.
 */
class AssociationMenuBuilder implements AssociationMenuBuilderInterface {

  /**
   * The default route match to use when determining the menu active trail.
   *
   * @var \Drupal\Core\Routing\RouteMatchInterface
   */
  protected $routeMatch;

  /**
   * Creates a new instance of the AssociationMenuBuilder class.
   *
   * @param \Drupal\Core\Routing\RouteMatchInterface $current_route_match
   *   The default route match to use when determining the menu active trail.
   */
  public function __construct(RouteMatchInterface $current_route_match) {
    $this->routeMatch = $current_route_match;
  }

  /**
   * {@inheritdoc}
   */
  public function buildMenu(array $menu, RouteMatchInterface $route_match = NULL): array {
    $build = [
      '#theme' => 'menu',
      '#menu_name' => 'association_nav:' . $menu['id'],
      '#items' => $this->buildMenuItems($menu['items'], $route_match),
    ];

    // Apply caching from the menu data if the cache metadata exists.
    if (isset($menu['cache']) && $menu['cache'] instanceof CacheableMetadata) {
      $menu['cache']->applyTo($build);
    }

    return $build;
  }

  /**
   * {@inheritdoc}
   */
  public function buildMenuItems(array $menu_items, RouteMatchInterface $route_match = NULL): array {
    $routeMatch = $route_match ?? $this->routeMatch;

    $tree = [];
    $items = [];
    foreach ($menu_items as $id => $item) {
      $parentId = $item->getParentId();

      if (!$parentId) {
        // Root level menu items.
        $tree[$id] = $item;
      }
      elseif (isset($menu_items[$parentId])) {
        // Found parent item, append as child item. Menu storage handler
        // loads from the datasource weight sorted already.
        $menu_items[$parentId]->getChildren()[$id] = $item;
      }
      // Else parent item is disabled, or is missing. This will cause children
      // items to not appear. It might be possible to elevate items, but
      // this might have unintended consequences or lose intended structure.
    }

    // Transform the menu data objects into the renderable links array.
    foreach ($tree as $id => $item) {
      if ($processed = $this->buildItem($item, $routeMatch)) {
        $items[$id] = $processed;
      }
    }

    return $items;
  }

  /**
   * Transform menu objects into renderable menu link items recursively.
   *
   * Transform the loaded tree menu objects from AssociationMenuStorage to menu
   * items ready for use with the menu.html.twig template recursively. Menu
   * items that are not expanded or are not accessible, will not render their
   * child items.
   *
   * @param \Drupal\association_menu\MenuItemInterface $item
   *   The loaded association menu storage item, with children attached.
   * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
   *   The route match to use to determine the active trail.
   * @param int $max_depth
   *   The maximum depth that the menu navigation should build to.
   * @param int $depth
   *   The current menu depth the menu items are currently being built.
   *
   * @return array|false
   *   Menu item sub-tree for the menu item data passed. This should be a
   *   renderable array ready to be used with menu.html.twig or FALSE if menu
   *   item cannot be display or access to the item link is denied.
   */
  protected function buildItem(MenuItemInterface $item, RouteMatchInterface $route_match, $max_depth = self::MAX_MENU_DEPTH, $depth = 0) {
    if (!$item->hasAccess()) {
      return FALSE;
    }

    $build = [
      'title' => $item->getTitle(),
      'url' => $item->getUrl(),
      'attributes' => new Attribute(),
      'in_active_trail' => FALSE,
      'is_expanded' => $item->isExpanded(),
      'is_collapsed' => FALSE,
      'below' => [],
    ];

    if ($children = $item->getChildren()) {
      if (!empty($build['is_expanded']) && $depth < $max_depth) {
        foreach ($children as $id => $child) {
          $subItem = $this->buildItem($child, $route_match, $max_depth, $depth + 1);

          if ($subItem) {
            $build['below'][$id] = $subItem;
            $build['in_active_trail'] |= $subItem['in_active_trail'];
          }
        }
      }
      else {
        // There are children, but the parent menu is not expanded.
        $build['is_collapsed'] = TRUE;
      }
    }

    // If not already selected as in the active trail by one of its descendents
    // check if this URL itself matches the current route.
    if (empty($build['in_active_trail']) && $build['url']->isRouted()) {
      $build['in_active_trail'] = $build['url']->getRouteName() === $route_match->getRouteName()
        && $build['url']->getRouteParameters() == $route_match->getParameters();
    }

    return $build;
  }

}

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

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