You are here

function menu_position_evaluate_rules in Menu Position 6

Same name and namespace in other branches
  1. 7.2 menu_position.module \menu_position_evaluate_rules()
  2. 7 menu_position.module \menu_position_evaluate_rules()

Evaluates all rules based on the given path.

Parameters

$path: The path used to evaluate all rules.

$context: The full node object if the path is a node page.

1 call to menu_position_evaluate_rules()
menu_position_page_preprocess_callback in ./menu_position.module
Implements hook_page_delivery_callback_alter().

File

./menu_position.module, line 114
Provides menu links for dynamic positioning of nodes based on configurable rules.

Code

function menu_position_evaluate_rules($context = array()) {
  $path = $context['path'];

  // Retrieve the rules from the database.
  $rules = db_query('SELECT * FROM {menu_position_rules} WHERE enabled = 1 ORDER BY weight, rid');

  // Retrieve the list of menus the path is already in.
  $result = db_query('SELECT menu_name FROM {menu_links} WHERE link_path = "%s"', $path);
  $menu_names = array();
  while ($menu_name = db_fetch_array($result)) {
    $menu_names[] = $menu_name['menu_name'];
  }

  // Retrieve the main and secondary menu names.
  $main_menu = theme_get_setting('toggle_primary_links') ? variable_get('menu_main_links_source', 'primary-links') : FALSE;
  $secondary_menu = theme_get_setting('toggle_secondary_links') ? variable_get('menu_secondary_links_source', 'secondary-links') : FALSE;

  // Retrieve the original router item.
  $original_router_item = menu_get_item();

  // Flag that we haven't set the breadcrumb yet.
  $breadcrumb_set = FALSE;

  // Examine each rule and check its conditions.
  while ($rule = db_fetch_object($rules)) {
    if (in_array($rule->menu_name, $menu_names)) {

      // If the node is already placed in the rule's menu, skip the rule.
      $rule_matches = FALSE;
      if ($rule->menu_name == $main_menu) {

        // Don't override the main menu links.
        $main_menu = FALSE;
      }
      if ($rule->menu_name == $secondary_menu) {
        $secondary_menu = FALSE;
      }
      $breadcrumb_set = TRUE;
    }
    else {

      // A rule with no conditions always matches.
      $rule_matches = TRUE;

      // Go through each condition, ANDing each result.
      $rule->conditions = unserialize($rule->conditions);
      foreach ($rule->conditions as $plugin => $variables) {

        // Add the current rule and node to the callback's variables.
        $variables['rule'] = $rule;
        $variables['context'] = $context;

        // Find the plugin's callback function.
        $callback = menu_position_get_condition_callback($plugin);
        if ($callback) {

          // Check if this condition matches.
          $rule_matches = $callback($variables);
        }
        else {

          // If the callback cannot be found, the condition has failed.
          $rule_matches = FALSE;
        }

        // No need to check other conditions if this condition failed.
        if (!$rule_matches) {
          break;
        }
      }
    }

    // We've found a matching rule.
    if ($rule_matches) {

      // Retrieve menu item specified in the rule.
      $menu_item = menu_link_load($rule->mlid);

      // Clone the original router item, but insert our menu_position path.
      $router_item = $original_router_item;
      $router_item['href'] = $menu_item['link_path'];

      // Even if we are denied access to the page, we still want to show the
      // navigational paths to the page.
      $router_item['access'] = TRUE;

      // Temporarily override the original router item.
      menu_set_item(NULL, $router_item);

      // Set the theme's secondary menu links if the rule matches the secondary menu.
      if ($rule->menu_name == $secondary_menu) {

        // Mark that we no longer need to set the secondary menu's tree.
        $secondary_menu = FALSE;
      }

      // Set the theme's main menu links if the rule matches the main menu.
      if ($rule->menu_name == $main_menu) {

        // Mark that we no longer need to set the main menu's tree.
        $main_menu = FALSE;
      }
      menu_position_precache_tree($router_item, $original_router_item, $menu_item['menu_name']);

      // Use our fake router item to influence the active trail.
      if (!$breadcrumb_set) {

        // Find the fake active trail.
        $active_trail = menu_position_get_active_trail($menu_item['menu_name']);

        // Replace the menu_position item with the original menu item.
        array_pop($active_trail);
        $active_trail[] = $original_router_item;
        menu_set_active_trail($active_trail);

        // Also override any trail set with drupal_set_breadcrumb().
        $breadcrumbs = menu_get_active_breadcrumb();
        array_pop($breadcrumbs);
        drupal_set_breadcrumb($breadcrumbs);
        $breadcrumb_set = TRUE;
      }

      // Restore the original router item.
      menu_set_item(NULL, $original_router_item);

      // Don't let other rules match against this rule's menu.
      $menu_names[] = $rule->menu_name;
    }
  }
}