You are here

function views_menu_alter in Views (for Drupal 7) 7.3

Same name and namespace in other branches
  1. 8.3 views.module \views_menu_alter()
  2. 6.3 views.module \views_menu_alter()
  3. 6.2 views.module \views_menu_alter()

Implements hook_menu_alter().

File

./views.module, line 457
Primarily Drupal hooks and global API functions to manipulate views.

Code

function views_menu_alter(&$callbacks) {
  $our_paths = array();
  $views = views_get_applicable_views('uses hook menu');
  foreach ($views as $data) {
    list($view, $display_id) = $data;
    $result = $view
      ->execute_hook_menu($display_id, $callbacks);
    if (is_array($result)) {

      // The menu system doesn't support having two otherwise identical paths
      // with different placeholders. So we want to remove the existing items
      // from the menu whose paths would conflict with ours. First, we must find
      // any existing menu items that may conflict. We use a regular expression
      // because we don't know what placeholders they might use. Note that we
      // first construct the regex itself by replacing %views_arg in the display
      // path, then we use this constructed regex (which will be something like
      // '#^(foo/%[^/]*/bar)$#') to search through the existing paths.
      $regex = '#^(' . preg_replace('#%views_arg#', '%[^/]*', implode('|', array_keys($result))) . ')$#';
      $matches = preg_grep($regex, array_keys($callbacks));

      // Remove any conflicting items that were found.
      foreach ($matches as $path) {

        // Don't remove the paths we just added!
        if (!isset($our_paths[$path])) {
          unset($callbacks[$path]);
        }
      }
      foreach ($result as $path => $item) {
        if (!isset($callbacks[$path])) {

          // Add a new item, possibly replacing (and thus effectively
          // overriding) one that we removed above.
          $callbacks[$path] = $item;
        }
        else {

          // This item already exists, so it must be one that we added.
          // We change the various callback arguments to pass an array
          // of possible display IDs instead of a single ID.
          $callbacks[$path]['page arguments'][1] = (array) $callbacks[$path]['page arguments'][1];
          $callbacks[$path]['page arguments'][1][] = $display_id;
          $callbacks[$path]['access arguments'] = $item['access arguments'];
          $callbacks[$path]['load arguments'][1] = (array) $callbacks[$path]['load arguments'][1];
          $callbacks[$path]['load arguments'][1][] = $display_id;
        }
        $our_paths[$path] = TRUE;
      }
    }
  }

  // Save memory: Destroy those views.
  foreach ($views as $data) {
    list($view, $display_id) = $data;
    $view
      ->destroy();
  }
}