function views_menu_alter

Same name in other branches
  1. 6.x-3.x views.module \views_menu_alter()

Implements hook_menu_alter().

File

./views.module, line 457

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();
    }
}