You are here

function menu_position_evaluate_rules in Menu Position 7.2

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

Evaluates all rules based on a given context.

Parameters

$context: A small context variable which contains:

  • path: The path of the current page.
  • entity_type: If the current page is an "entity" page, the type of entity.
  • bundle_name: The bundle (entity type) of the current page's entity.
  • [entity]: The page's entity object, such as "node", "user", etc.
1 call to menu_position_evaluate_rules()
menu_position_page_delivery_callback_alter in ./menu_position.module
Implements hook_page_delivery_callback_alter().

File

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

Code

function menu_position_evaluate_rules($context = array()) {

  // Sanity check: if there is no existing menu item, Drupal won't display any
  // navigation menus anyway and will error out when we try methods below.
  if (menu_get_item() === FALSE) {
    return;
  }

  // Retrieve the rules from the database. For speed, we don't call
  // menu_position_read_rules() and unserialize the conditions only if needed.
  $rules = db_query('SELECT * FROM {menu_position_rules} WHERE enabled = :enabled ORDER BY weight, rid', array(
    ':enabled' => 1,
  ));

  // Retrieve the list of menus the path is already in.
  $menu_names = db_query('SELECT menu_name FROM {menu_links} WHERE link_path = :path', array(
    ':path' => $context['path'],
  ))
    ->fetchCol();

  // Flag that we still need to set the breadcrumb.
  $set_breadcrumb = TRUE;

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

      // If the page is already placed in the rule's menu, skip the rule.
      $rule_matches = FALSE;
      $set_breadcrumb = FALSE;
    }
    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;
        }
      }
    }

    // Let other modules manipulate the rule.
    drupal_alter('menu_position_rule', $rule, $context, $rule_matches, $set_breadcrumb);

    // We've found a matching rule.
    if ($rule_matches && menu_position_activate_rule($rule, $context, $set_breadcrumb)) {

      // Don't let other rules set the breadcrumb.
      $set_breadcrumb = FALSE;

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