? context_and_or.patch
Index: context.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/context/Attic/context.install,v
retrieving revision 1.1.2.1.2.6.2.3
diff -u -p -r1.1.2.1.2.6.2.3 context.install
--- context.install	23 Dec 2009 16:39:32 -0000	1.1.2.1.2.6.2.3
+++ context.install	9 Feb 2010 01:27:31 -0000
@@ -66,6 +66,11 @@ function context_schema() {
         'type' => 'text',
         'serialize' => TRUE,
       ),
+      'condition_mode' => array(
+        'description' => 'Condition mode for this context.',
+        'type' => 'int',
+        'default' => 0,
+      ),
     ),
     'primary key' => array('name'),
   );
@@ -250,6 +255,20 @@ function context_update_6302() {
 }
 
 /**
+ * Update 6303: Add field for context condition mode.
+ */
+function context_update_6303() {
+  $ret = array();
+  $spec = array(
+    'description' => 'Condition mode for this context.',
+    'type' => 'int',
+    'default' => 0,
+  );
+  db_add_field(&$ret, 'context', 'condition_mode', $spec);
+  return $ret;
+}
+
+/**
  * Helper function to update context 2 objects to context 3.
  */
 function context_migrate_api_3($contexts) {
Index: context.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/context/context.module,v
retrieving revision 1.6.2.6.2.6.2.4
diff -u -p -r1.6.2.6.2.6.2.4 context.module
--- context.module	6 Feb 2010 02:16:57 -0000	1.6.2.6.2.6.2.4
+++ context.module	9 Feb 2010 01:27:31 -0000
@@ -8,6 +8,9 @@ define('CONTEXT_SET', 1);
 define('CONTEXT_ISSET', 2);
 define('CONTEXT_CLEAR', 3);
 
+define('CONTEXT_CONDITION_MODE_OR', 0);
+define('CONTEXT_CONDITION_MODE_AND', 1);
+
 /**
  * Master context function. Avoid calling this directly -- use one of the helper functions below.
  *
@@ -302,10 +305,42 @@ function context_enabled_contexts($reset
 }
 
 /**
+ * Queue or activate contexts that have met the specified condition.
+ *
+ * @param $context
+ *   The context object to queue or activate.
+ * @param $condition
+ *   String. Name for the condition that has been met.
+ * @param $reset
+ *   Reset flag for the queue static cache.
+ */
+function context_condition_met($context, $condition, $reset = FALSE) {
+  static $queue;
+  if (!isset($queue) || $reset) {
+    $queue = array();
+  }
+  if (!context_isset('context', $context->name)) {
+    // Context is using AND mode. Queue it.
+    if (isset($context->condition_mode) && $context->condition_mode == CONTEXT_CONDITION_MODE_AND) {
+      $queue[$context->name][$condition] = $condition;
+
+      // If all conditions have been met. set the context.
+      if (!array_diff(array_keys($context->conditions), $queue[$context->name])) {
+        context_set('context', $context->name, $context);
+      }
+    }
+    // Context is using OR mode. Set it.
+    else {
+      context_set('context', $context->name, $context);
+    }
+  }
+}
+
+/**
  * Loads any active contexts with associated reactions. This should be run
  * at a late stage of the page load to ensure that relevant contexts have been set.
  */
-function context_active_contexts($reset = FALSE) {
+function context_active_contexts() {
   $contexts = context_get('context');
   return !empty($contexts) && is_array($contexts) ? $contexts : array();
 }
Index: context_ui/context_ui.admin.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/context/context_ui/Attic/context_ui.admin.inc,v
retrieving revision 1.1.2.7.2.12.2.2
diff -u -p -r1.1.2.7.2.12.2.2 context_ui.admin.inc
--- context_ui/context_ui.admin.inc	22 Dec 2009 19:29:35 -0000	1.1.2.7.2.12.2.2
+++ context_ui/context_ui.admin.inc	9 Feb 2010 01:27:31 -0000
@@ -132,6 +132,14 @@ function context_ui_form(&$form_state, $
     '#description' => t('The description of this context definition.'),
   );
 
+  // Condition mode
+  $form['condition_mode'] = array(
+    '#type' => 'checkbox',
+    '#default_value' => isset($context->condition_mode) ? $context->condition_mode : FALSE,
+    '#title' => t('Require all conditions'),
+    '#description' => t('If checked, all conditions must be met for this context to be active. Otherwise, the first condition that is met will activate this context.')
+  );
+
   // Condition plugin forms
   $form['conditions'] = array(
     '#theme' => 'context_ui_plugins',
@@ -368,6 +376,7 @@ function context_ui_form_process($form) 
   $context->name = isset($form['name']) ? $form['name'] : NULL;
   $context->description = isset($form['description']) ? $form['description'] : NULL;
   $context->tag = isset($form['tag']) ? $form['tag'] : NULL;
+  $context->condition_mode = isset($form['condition_mode']) ? $form['condition_mode'] : NULL;
   $context->conditions = array();
   $context->reactions = array();
   if (!empty($form['conditions'])) {
Index: plugins/context_condition.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/context/plugins/Attic/context_condition.inc,v
retrieving revision 1.1.2.1
diff -u -p -r1.1.2.1 context_condition.inc
--- plugins/context_condition.inc	14 Dec 2009 22:34:05 -0000	1.1.2.1
+++ plugins/context_condition.inc	9 Feb 2010 01:27:31 -0000
@@ -94,12 +94,20 @@ class context_condition {
    * points with Drupal.
    */
   function execute($value) {
-    $contexts = $this->get_contexts($value);
-    $this->values[$value] = array();
-    foreach ($contexts as $context) {
+    foreach ($this->get_contexts($value) as $context) {
+      $this->condition_met($context, $value);
+    }
+  }
+
+  /**
+   * Marks a context as having met this particular condition.
+   */
+  function condition_met($context, $value = NULL) {
+    if (isset($value)) {
+      $this->values[$value] = isset($this->values[$value]) ? $this->values[$value] : array();
       $this->values[$value][] = $context->name;
-      context_set('context', $context->name, $context);
     }
+    context_condition_met($context, $this->plugin);
   }
 
   /**
Index: plugins/context_condition_book.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/context/plugins/Attic/context_condition_book.inc,v
retrieving revision 1.1.2.2
diff -u -p -r1.1.2.2 context_condition_book.inc
--- plugins/context_condition_book.inc	21 Jan 2010 20:00:27 -0000	1.1.2.2
+++ plugins/context_condition_book.inc	9 Feb 2010 01:27:31 -0000
@@ -15,11 +15,8 @@ class context_condition_book extends con
 
   function execute($node, $op) {
     if (isset($node->book, $node->book['menu_name'])) {
-      $this->values[$node->book['menu_name']] = array();
-      $contexts = $this->get_contexts($node->book['menu_name']);
-      foreach ($contexts as $context) {
-        $this->values[$node->book['menu_name']][] = $context->name;
-        context_set('context', $context->name, $context);
+      foreach ($this->get_contexts($node->book['menu_name']) as $context) {
+        $this->condition_met($context, $node->book['menu_name']);
       }
     }
   }
Index: plugins/context_condition_menu.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/context/plugins/Attic/context_condition_menu.inc,v
retrieving revision 1.1.2.1
diff -u -p -r1.1.2.1 context_condition_menu.inc
--- plugins/context_condition_menu.inc	14 Dec 2009 22:34:05 -0000	1.1.2.1
+++ plugins/context_condition_menu.inc	9 Feb 2010 01:27:31 -0000
@@ -38,11 +38,9 @@ class context_condition_menu extends con
     // and menu_get_active_menu_name() for the details.
     $trail = menu_get_active_trail();
     foreach ($trail as $item) {
-      $this->values[$item['href']] = array();
-      if (!empty($item['href']) && $contexts = $this->get_contexts($item['href'])) {
-        foreach ($contexts as $context) {
-          $this->values[$item['href']][] = $condition->name;
-          context_set('context', $context->name, $context);
+      if (!empty($item['href'])) {
+        foreach ($this->get_contexts($item['href']) as $context) {
+          $this->condition_met($context, $item['href']);
         }
       }
     }
Index: plugins/context_condition_node.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/context/plugins/Attic/context_condition_node.inc,v
retrieving revision 1.1.2.1
diff -u -p -r1.1.2.1 context_condition_node.inc
--- plugins/context_condition_node.inc	14 Dec 2009 22:34:05 -0000	1.1.2.1
+++ plugins/context_condition_node.inc	9 Feb 2010 01:27:31 -0000
@@ -26,20 +26,16 @@ class context_condition_node extends con
   }
 
   function execute($node, $op) {
-    $contexts = $this->get_contexts($node->type);
-    $this->values[$node->type] = array();
-    foreach ($contexts as $context) {
+    foreach ($this->get_contexts($node->type) as $context) {
       // Check the node form option.
       if ($op === 'form') {
         $options = $this->fetch_from_context($context, 'options');
         if (!empty($options['node_form'])) {
-          $this->values[$node->type][] = $context->name;
-          context_set('context', $context->name, $context);
+          $this->condition_met($context, $node->type);
         }
       }
       else {
-        $this->values[$node->type][] = $context->name;
-        context_set('context', $context->name, $context);
+        $this->condition_met($context, $node->type);
       }
     }
   }
Index: plugins/context_condition_path.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/context/plugins/Attic/context_condition_path.inc,v
retrieving revision 1.1.2.1
diff -u -p -r1.1.2.1 context_condition_path.inc
--- plugins/context_condition_path.inc	14 Dec 2009 22:34:05 -0000	1.1.2.1
+++ plugins/context_condition_path.inc	9 Feb 2010 01:27:31 -0000
@@ -46,7 +46,6 @@ class context_condition_path extends con
    */
   function execute() {
     $current_path = drupal_get_path_alias($_GET['q']);
-    $this->values[$current_path] = array();
     foreach (context_enabled_contexts() as $context) {
       if ($paths = $this->fetch_from_context($context, 'values')) {
         $paths = implode("\n", $paths);
@@ -55,8 +54,7 @@ class context_condition_path extends con
           $path_match = $path_match || drupal_match_path($_GET['q'], $paths);
         }
         if ($path_match) {
-          $this->values[$current_path][] = $context->name;
-          context_set('context', $context->name, $context);
+          $this->condition_met($context, $current_path);
         }
       }
     }
Index: plugins/context_condition_user.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/context/plugins/Attic/context_condition_user.inc,v
retrieving revision 1.1.2.1
diff -u -p -r1.1.2.1 context_condition_user.inc
--- plugins/context_condition_user.inc	14 Dec 2009 22:34:05 -0000	1.1.2.1
+++ plugins/context_condition_user.inc	9 Feb 2010 01:27:31 -0000
@@ -13,12 +13,8 @@ class context_condition_user extends con
     if ($op == 'view') {
       $roles = $account->roles;
       foreach ($roles as $role) {
-        $this->values[$role] = array();
-        if ($contexts = $this->get_contexts($role)) {
-          foreach ($contexts as $context) {
-            $this->values[$role][] = $context->name;
-            context_set('context', $context->name, $context);
-          }
+        foreach ($this->get_contexts($role) as $context) {
+          $this->condition_met($context, $role);
         }
       }
     }
Index: plugins/context_condition_views.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/context/plugins/Attic/context_condition_views.inc,v
retrieving revision 1.1.2.3
diff -u -p -r1.1.2.3 context_condition_views.inc
--- plugins/context_condition_views.inc	8 Feb 2010 14:29:13 -0000	1.1.2.3
+++ plugins/context_condition_views.inc	9 Feb 2010 01:27:31 -0000
@@ -33,20 +33,14 @@ class context_condition_views extends co
     switch ($view->display_handler->display->display_plugin) {
       case 'page':
       case 'calendar':
-        $this->values[$view->name] = array();
-        $this->values["{$view->name}:{$view->current_display}"] = array();
         // Set contexts for this view.
-        $contexts = $this->get_contexts($view->name);
-        foreach ($contexts as $context) {
-          $this->values[$view->name][] = $context->name;
-          context_set('context', $context->name, $context);
+        foreach ($this->get_contexts($view->name) as $context) {
+          $this->condition_met($context, $view->name);
         }
         // Set any contexts associated with the current display
         if (!empty($view->current_display)) {
-          $contexts = $this->get_contexts("{$view->name}:{$view->current_display}");
-          foreach ($contexts as $context) {
-            $this->values["{$view->name}:{$view->current_display}"][] = $context->name;
-            context_set('context', $context->name, $context);
+          foreach ($this->get_contexts("{$view->name}:{$view->current_display}") as $context) {
+            $this->condition_met($context, "{$view->name}:{$view->current_display}");
           }
         }
         break;
