You are here

public function MenuTreeStorage::rebuild in Zircon Profile 8

Same name and namespace in other branches
  1. 8.0 core/lib/Drupal/Core/Menu/MenuTreeStorage.php \Drupal\Core\Menu\MenuTreeStorage::rebuild()

Rebuilds the stored menu link definitions.

Links that saved by passing definitions into this method must be included on all future calls, or they will be purged. This allows for automatic cleanup e.g. when modules are uninstalled.

Parameters

array $definitions: The new menu link definitions.

Overrides MenuTreeStorageInterface::rebuild

File

core/lib/Drupal/Core/Menu/MenuTreeStorage.php, line 149
Contains \Drupal\Core\Menu\MenuTreeStorage.

Class

MenuTreeStorage
Provides a menu tree storage using the database.

Namespace

Drupal\Core\Menu

Code

public function rebuild(array $definitions) {
  $links = array();
  $children = array();
  $top_links = array();

  // Fetch the list of existing menus, in case some are not longer populated
  // after the rebuild.
  $before_menus = $this
    ->getMenuNames();
  if ($definitions) {
    foreach ($definitions as $id => $link) {

      // Flag this link as discovered, i.e. saved via rebuild().
      $link['discovered'] = 1;

      // Note: The parent we set here might be just stored in the {menu_tree}
      // table, so it will not end up in $top_links. Therefore the later loop
      // on the orphan links, will handle those cases.
      if (!empty($link['parent'])) {
        $children[$link['parent']][$id] = $id;
      }
      else {

        // A top level link - we need them to root our tree.
        $top_links[$id] = $id;
        $link['parent'] = '';
      }
      $links[$id] = $link;
    }
  }
  foreach ($top_links as $id) {
    $this
      ->saveRecursive($id, $children, $links);
  }

  // Handle any children we didn't find starting from top-level links.
  foreach ($children as $orphan_links) {
    foreach ($orphan_links as $id) {

      // Check for a parent that is not loaded above since only internal links
      // are loaded above.
      $parent = $this
        ->loadFull($links[$id]['parent']);

      // If there is a parent add it to the links to be used in
      // ::saveRecursive().
      if ($parent) {
        $links[$links[$id]['parent']] = $parent;
      }
      else {

        // Force it to the top level.
        $links[$id]['parent'] = '';
      }
      $this
        ->saveRecursive($id, $children, $links);
    }
  }
  $result = $this
    ->findNoLongerExistingLinks($definitions);

  // Remove all such items.
  if ($result) {
    $this
      ->purgeMultiple($result);
  }
  $this
    ->resetDefinitions();
  $affected_menus = $this
    ->getMenuNames() + $before_menus;

  // Invalidate any cache tagged with any menu name.
  $cache_tags = Cache::buildTags('config:system.menu', $affected_menus, '.');
  $this->cacheTagsInvalidator
    ->invalidateTags($cache_tags);
  $this
    ->resetDefinitions();

  // Every item in the cache bin should have one of the menu cache tags but it
  // is not guaranteed, so invalidate everything in the bin.
  $this->menuCacheBackend
    ->invalidateAll();
}