? 813954_context_condition.patch
Index: context.core.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/context/Attic/context.core.inc,v
retrieving revision 1.1.2.3.2.20.2.22
diff -u -p -r1.1.2.3.2.20.2.22 context.core.inc
--- context.core.inc	28 Jul 2010 23:16:45 -0000	1.1.2.3.2.20.2.22
+++ context.core.inc	29 Jul 2010 22:53:49 -0000
@@ -7,6 +7,11 @@
 function context_context_registry() {
   $registry = array();
   $registry['conditions'] = array(
+    'context' => array(
+      'title' => t('Context'),
+      'description' => t('Set this context on the basis of other active contexts. Put each context on a separate line. You can use the <code>*</code> character as a wildcard and <code>~</code> to exclude one or more contexts.'),
+      'plugin' => 'context_condition_context',
+    ),
     'node' => array(
       'title' => t('Node type'),
       'description' => t('Set this context when viewing a node page or using the add/edit form of one of these content types.'),
@@ -19,7 +24,7 @@ function context_context_registry() {
     ),
     'path' => array(
       'title' => t('Path'),
-      'description' => t('Set this context when any of the paths above match the page path. Put each path on a separate line. You can use the "*" character as a wildcard and &lt;front&gt; for the front page.'),
+      'description' => t('Set this context when any of the paths above match the page path. Put each path on a separate line. You can use the "*" character as a wildcard and <code>~</code> to exclude one or more paths. Use &lt;front&gt; for the site front page.'),
       'plugin' => 'context_condition_path',
     ),
     'user' => array(
@@ -363,6 +368,9 @@ function context_context_page_condition(
   if ($plugin = context_get_plugin('condition', 'sitewide')) {
     $plugin->execute(1);
   }
+  if ($plugin = context_get_plugin('condition', 'context')) {
+    $plugin->execute();
+  }
 }
 
 /**
Index: context.plugins.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/context/Attic/context.plugins.inc,v
retrieving revision 1.1.2.5
diff -u -p -r1.1.2.5 context.plugins.inc
--- context.plugins.inc	8 Jun 2010 15:33:58 -0000	1.1.2.5
+++ context.plugins.inc	29 Jul 2010 22:53:49 -0000
@@ -17,6 +17,14 @@ function _context_context_plugins() {
       'class' => 'context_condition',
     ),
   );
+  $plugins['context_condition_context'] = array(
+    'handler' => array(
+      'path' => drupal_get_path('module', 'context') .'/plugins',
+      'file' => 'context_condition_context.inc',
+      'class' => 'context_condition_context',
+      'parent' => 'context_condition_path',
+    ),
+  );
   $plugins['context_condition_node'] = array(
     'handler' => array(
       'path' => drupal_get_path('module', 'context') .'/plugins',
Index: plugins/context_condition_context.inc
===================================================================
RCS file: plugins/context_condition_context.inc
diff -N plugins/context_condition_context.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ plugins/context_condition_context.inc	29 Jul 2010 22:53:49 -0000
@@ -0,0 +1,24 @@
+<?php
+// $Id$
+
+/**
+ * Expose active contexts as a context condition.
+ */
+class context_condition_context extends context_condition_path {
+  function execute() {
+    if ($this->condition_used()) {
+      $active_contexts = array_keys(context_active_contexts());
+      foreach ($this->get_contexts() as $context) {
+        if (!in_array($context->name, $active_contexts, TRUE) && $values = $this->fetch_from_context($context, 'values')) {
+          if ($this->match($active_contexts, $values)) {
+            $this->condition_met($context);
+          }
+        }
+      }
+      // If the list of active contexts has changed, we need to recurse.
+      if ($active_contexts != array_keys(context_active_contexts())) {
+        $this->execute();
+      }
+    }
+  }
+}
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.5
diff -u -p -r1.1.2.5 context_condition_path.inc
--- plugins/context_condition_path.inc	29 Jul 2010 21:23:34 -0000	1.1.2.5
+++ plugins/context_condition_path.inc	29 Jul 2010 22:53:49 -0000
@@ -48,16 +48,69 @@ class context_condition_path extends con
     if ($this->condition_used()) {
       $current_path = drupal_get_path_alias($_GET['q']);
       foreach ($this->get_contexts() as $context) {
-        foreach ($this->fetch_from_context($context, 'values') as $path) {
-          $path_match = FALSE;
-          if ($path_match = drupal_match_path($current_path, $path)) {
-            $this->condition_met($context, $path);
-          }
-          else if ($current_path != $_GET['q'] && drupal_match_path($_GET['q'], $path)) {
-            $this->condition_met($context, $path);
+        $paths = $this->fetch_from_context($context, 'values');
+        if ($this->match($current_path, $paths, TRUE)) {
+          $this->condition_met($context);
+        }
+        elseif ($current_path != $_GET['q'] && $this->match($_GET['q'], $paths, TRUE)) {
+          $this->condition_met($context);
+        }
+      }
+    }
+  }
+
+  /**
+   * Match the subject against a set of regex patterns.
+   * Similar to drupal_match_path() but also handles negation through the use
+   * of the ~ character.
+   *
+   * @param mixed $subject
+   *   The subject string or an array of strings to be matched.
+   * @param array $patterns
+   *   An array of patterns. Any patterns that begin with ~ are considered
+   *   negative or excluded conditions.
+   * @param boolean $path
+   *   Whether the given subject should be matched as a Drupal path. If TRUE,
+   *   '<front>' will be replaced with the site frontpage when matching against
+   *   $patterns.
+   */
+  protected function match($subject, $patterns, $path = FALSE) {
+    static $regexps;
+    $match = FALSE;
+    $positives = $negatives = 0;
+    $subject = !is_array($subject) ? array($subject) : $subject;
+    foreach ($patterns as $pattern) {
+      if (strpos($pattern, '~') === 0) {
+        $negate = TRUE;
+        $negatives++;
+      }
+      else {
+        $negate = FALSE;
+        $positives++;
+      }
+      $pattern = ltrim($pattern, '~');
+      if (!isset($regexps[$pattern])) {
+        if ($path) {
+          $regexps[$pattern] = '/^('. preg_replace(array('/(\r\n?|\n)/', '/\\\\\*/', '/(^|\|)\\\\<front\\\\>($|\|)/'), array('|', '.*', '\1'. preg_quote(variable_get('site_frontpage', 'node'), '/') .'\2'), preg_quote($pattern, '/')) .')$/';
+        }
+        else {
+          $regexps[$pattern] = '/^('. preg_replace(array('/(\r\n?|\n)/', '/\\\\\*/'), array('|', '.*'), preg_quote($pattern, '/')) .')$/';
+        }
+      }
+      foreach ($subject as $value) {
+        if (preg_match($regexps[$pattern], $value)) {
+          if ($negate) {
+            return FALSE;
           }
+          $match = TRUE;
         }
       }
     }
+    // If there are **only** negative conditions and we've gotten this far none
+    // we actually have a match.
+    if ($positives === 0 && $negatives) {
+      return TRUE;
+    }
+    return $match;
   }
 }
