You are here

function admin_menu_tree_dynamic in Administration menu 8.3

Same name and namespace in other branches
  1. 7.3 admin_menu.inc \admin_menu_tree_dynamic()

Load menu link trees for router paths containing dynamic arguments.

Parameters

$expand_map: An array containing menu router path placeholder expansion argument mappings.

Return value

An associative array whose keys are the parent paths of the menu router paths given in $expand_map as well as the parent paths of any child link deeper down the tree. The parent paths are used in admin_menu_merge_tree() to check whether anything needs to be merged.

See also

hook_admin_menu_map()

1 call to admin_menu_tree_dynamic()
admin_menu_tree in ./admin_menu.inc
Build the full administration menu tree from static and expanded dynamic items.

File

./admin_menu.inc, line 66
Menu builder functions for Administration menu.

Code

function admin_menu_tree_dynamic(array $expand_map) {
  $p_columns = [];
  for ($i = 1; $i <= MENU_MAX_DEPTH; $i++) {
    $p_columns[] = 'p' . $i;
  }

  // Fetch p* columns for all router paths to expand.
  $router_paths = array_keys($expand_map);

  // TODO: Drupal Rector Notice: Please delete the following comment after you've made any necessary changes.
  // You will need to use `\Drupal\core\Database\Database::getConnection()` if you do not yet have access to the container here.
  $plids = \Drupal::database()
    ->select('menu_links', 'ml')
    ->fields('ml', $p_columns)
    ->condition('router_path', $router_paths)
    ->execute()
    ->fetchAll(PDO::FETCH_ASSOC);

  // Unlikely, but possible.
  if (empty($plids)) {
    return [];
  }

  // Use queried plid columns to query sub-trees for the router paths.
  // TODO: Drupal Rector Notice: Please delete the following comment after you've made any necessary changes.
  // You will need to use `\Drupal\core\Database\Database::getConnection()` if you do not yet have access to the container here.
  $query = \Drupal::database()
    ->select('menu_links', 'ml');
  $query
    ->join('menu_router', 'm', 'ml.router_path = m.path');
  $query
    ->fields('ml')
    ->fields('m', array_diff(drupal_schema_fields_sql('menu_router'), drupal_schema_fields_sql('menu_links')));

  // The retrieved menu link trees have to be ordered by depth, so parents
  // always come before their children for the storage logic below.
  foreach ($p_columns as $column) {
    $query
      ->orderBy($column, 'ASC');
  }
  $db_or = db_or();
  foreach ($plids as $path_plids) {
    $db_and = db_and();

    // plids with value 0 may be ignored.
    foreach (array_filter($path_plids) as $column => $plid) {
      $db_and
        ->condition($column, $plid);
    }
    $db_or
      ->condition($db_and);
  }
  $query
    ->condition($db_or);
  $result = $query
    ->execute()
    ->fetchAllAssoc('mlid', PDO::FETCH_ASSOC);

  // Store dynamic links grouped by parent path for later merging and assign
  // placeholder expansion arguments.
  $tree_dynamic = [];
  foreach ($result as $link) {

    // If contained in $expand_map, then this is a (first) parent, and we need
    // to store by the defined 'parent' path for later merging, as well as
    // provide the expansion map arguments to apply to the dynamic tree.
    if (isset($expand_map[$link['path']])) {
      $parent_path = $expand_map[$link['path']]['parent'];
      $link['expand_map'] = $expand_map[$link['path']]['arguments'];
    }
    else {
      $parent_path = $result[$link['plid']]['path'];
    }
    $tree_dynamic[$parent_path][] = $link;
  }
  return $tree_dynamic;
}