You are here

public function MenuTreeStorage::loadTreeData in Colossal Menu 8

Same name and namespace in other branches
  1. 2.x src/Menu/MenuTreeStorage.php \Drupal\colossal_menu\Menu\MenuTreeStorage::loadTreeData()

Loads a menu link tree from the storage.

This function may be used build the data for a menu tree only, for example to further massage the data manually before further processing happens. MenuLinkTree::checkAccess() needs to be invoked afterwards.

The tree order is maintained using an optimized algorithm, for example by storing each parent in an individual field, see https://www.drupal.org/node/141866 for more details. However, any details of the storage should not be relied upon since it may be swapped with a different implementation.

Parameters

string $menu_name: The name of the menu.

\Drupal\Core\Menu\MenuTreeParameters $parameters: The parameters to determine which menu links to be loaded into a tree.

Return value

array An array with 2 elements:

  • tree: A fully built menu tree containing an array. @see static::treeDataRecursive()
  • route_names: An array of all route names used in the tree.

Overrides MenuTreeStorageInterface::loadTreeData

1 call to MenuTreeStorage::loadTreeData()
MenuTreeStorage::loadSubtreeData in src/Menu/MenuTreeStorage.php
Loads a subtree rooted by the given ID.

File

src/Menu/MenuTreeStorage.php, line 148

Class

MenuTreeStorage
Provides a menu tree storage using the database.

Namespace

Drupal\colossal_menu\Menu

Code

public function loadTreeData($menu_name, MenuTreeParameters $parameters) {
  $query = $this->connection
    ->select($this->table, 't')
    ->fields('t', [
    'ancestor',
    'descendant',
    'depth',
  ])
    ->condition('e.menu', $menu_name)
    ->orderBy('t.depth', 'ASC')
    ->orderBy('e.weight', 'ASC');
  $query
    ->innerJoin($this->storage
    ->getEntityType()
    ->get('base_table'), 'e', 't.ancestor = e.id');
  if ($parameters->root) {
    $query
      ->condition('t.ancestor', $parameters->root);
  }
  if ($parameters->minDepth > 1) {

    // Since the default depth is 1, and in our storage it's 0, we'll
    // decrement the minimum depth.
    $query
      ->condition('t.depth', '>=', $parameters->minDepth - 1);
  }
  if ($parameters->maxDepth) {
    $query
      ->condition('t.depth', '<=', $parameters->maxDepth);
  }
  $result = $query
    ->execute();
  $flat = [];
  $depth = [];
  while ($row = $result
    ->fetchObject()) {
    $flat[$row->ancestor][] = $row->descendant;
    if (isset($depth[$row->descendant]) && $row->depth > $depth[$row->descendant]) {
      $depth[$row->descendant] = $row->depth;
    }
    elseif (!isset($depth[$row->descendant])) {
      $depth[$row->descendant] = $row->depth;
    }
  }
  $links = $this
    ->loadMultiple(array_keys($flat));
  $routes = [];
  foreach ($links as $link) {
    if (!$link
      ->isExternal() && ($name = $link
      ->getRouteName())) {
      $routes[$link
        ->id()] = $name;
    }
  }
  $tree = $this
    ->treeDataRecursive($flat, $links, $depth, $routes);
  return [
    'tree' => $tree,
    'route_names' => $routes,
  ];
}