Hi,

Unless I'm mistaken, it seems that context doesn't seem to recognize paths with query string parameters such as my/path?my=value.

This would be quite useful.

Best,

Jun.

Comments

ar-jan’s picture

Category: feature » support
Status: Active » Fixed

It seems Persistent URL will do this for you.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

ar-jan’s picture

Status: Closed (fixed) » Active

Hm, it seems I was wrong. When I read that Persistent URL was started as context_prefix, I assumed it was something that played together with Context module and it would therefore work with query strings. But you could have query strings without using PURL, and now that I'm experimenting with this, I can see that defining a condition with Path "*?query=string" does indeed not trigger the condition.
Is there a way to make Context work with query strings? Or would that be a feature request. Thanks!

doublejosh’s picture

Sounds like a feature request... and I want it too!

tribe_of_dan’s picture

Me too!

ar-jan’s picture

Category: support » feature

Changing status.

kristen pol’s picture

+1... actually need this right now... am trying to figure out a workaround.

Kristen

kristen pol’s picture

I have created a patch that extends the path condition plugin to create a query string condition plugin that works in the same way as the path plugin. The patch is against version 6.x-3.0. Please see attached.

It seemed cleaner to me to make a new plugin but, if you prefer that the path condition plugin be changed to work with query strings instead, please let me know and I can see if I can to do that.

The nice thing about having it be it's own plugin is that it could be used with the path plugin as well, e.g.

paths:

some/*
*/another

query strings:

destination=foobar
destination=somewhere*

I have only tested this for a simple case so it would be great if others could apply the patch to their context module and try it out (clear your drupal cache after applying the patch).

Kristen

kristen pol’s picture

StatusFileSize
new2.87 KB

argh... here's the patch

(Updating attribution on November 23, 2015.)

kristen pol’s picture

Status: Active » Needs review
Offlein’s picture

Hi, I tried that. Specifically I wanted the context to be set for only the first page of a paginated query.
So, I tried:

page=0
~page=*

That way it would still work on the first page. Seems to not work, however! I'm setting this in the "query string" condition (which is, I believe, the right place).

NaX’s picture

Status: Needs review » Needs work

I also could not get the code in the patch to run, so after some digging I added the following to context_init() after the "path" context. Now the code at leasts runs, but I cant get it to work as expected.

  if ($plugin = context_get_plugin('condition', 'query_string')) {
    $plugin->execute();
  }
NaX’s picture

Status: Needs work » Needs review

Ok, I found that the match function inherited from path was just not working for me. So changed context_condition_query_string.inc to use a custom query string matching function and it now seems to work. Its maybe not the most elegant why of doing it but I am not good at regular expressions and I did this in a bit of a hurry.

I hope it helps.

// $Id: context_condition_query_string.inc,v 1.1.2.6 2010/07/30 14:39:06 yhahn Exp $

/**
 * @file context_condition_query_string.inc
 *
 * Similar to context_condition_path but for entire query string.
 */

/**
 * Expose query strings as a context condition.
 */
class context_condition_query_string extends context_condition_path {

  /**
   * Execute.
   */
  function execute() {
    if ($this->condition_used()) {
      $current_query_string = $_SERVER["QUERY_STRING"];
      foreach ($this->get_contexts() as $context) {
        $query_strings = $this->fetch_from_context($context, 'values');
        if ($this->match($current_query_string, $query_strings)) {
          $this->condition_met($context);
        }
      }
    }
  }

  protected function match($subject, $patterns) {
    $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, '~');

      foreach ($subject as $value) {

        $q_subject = $this->parse_query_string($value);
        $q_pattern = $this->parse_query_string($pattern);
        
        foreach ($q_subject as $k => $v) {
          if (isset($q_pattern[$k])) {
            if ($q_pattern[$k] == '*' || $q_pattern[$k] == $v) {
              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;
  }

  protected function parse_query_string($str) {
    $op = array();
    $pairs = explode("&", $str);
    foreach ($pairs as $pair) {
      list($k, $v) = explode('=', $pair);
      $op[$k] = $v;
    }
    return $op;
  }
}
doublejosh’s picture

So excited to see this. My use case to let editors create multiple layouts of a page (or block inclusions) that can be arranged dynamically!!!

fxarte’s picture

Has anyone tested this?

fxarte’s picture

This needs work not only the the match function but elsewhere in the code because the variable $subject does only include the $_GET['q'] value

mrfelton’s picture

Patch in worked fine for me. Thanks.

mrfelton’s picture

StatusFileSize
new3.86 KB

I'm not sure what the other problems postes were with the original soution, but it's working well for me - aokhough the patch in #9 doesn't work without the modification mentioned in #12.

Attached patch combines those two changes into a patch that can be applied with Drush make.

betty66’s picture

After apply patch #18
My url: www.mysite.com/restaurants/wogaboo?title=a&zone=2&type=24&kids=31&offer=33

Conditions:
path: restaurants/*
query-string: title=a

Reaction:
theme->Section class: myclass

Don't work, "myclass" not show in body tag
any help?
thanks

dmenefee’s picture

I found that if I include the match() function in #13 in the patch at #18, it works like a charm.

kalis1’s picture

StatusFileSize
new3.04 KB

Here is another version of the patch provided in #18 (same code, just a more classical format).
This patch works very well for me (on 7.x-3.0-beta2).

@dmenefee : could you provide more info on what was wrong with the match() function inherited from the context_condition_path class ?

Thanks

kalis1’s picture

Version: 6.x-3.0 » 7.x-3.x-dev

Changing the version of the feature request...

rsaddington’s picture

Great patch, tested with 7.x-3.x-dev 2012-Jun-30 and works perfectly.

Would be really keen to see this in the next official release.

Offlein’s picture

I've been using this (#13) now actually for almost a year and it's been working fine. I'd really like to see it implemented.

Two things to note -- there's some [potentially] undefined variable issues going on in /plugins/context_condition_query_string.inc. One, in

/**
   * Execute.
   */
  function execute() {
    if ($this->condition_used()) {
      $current_query_string = $_SERVER["QUERY_STRING"];
      foreach ($this->get_contexts() as $context) {
        $query_strings = $this->fetch_from_context($context, 'values');
        if ($this->match($current_query_string, $query_strings)) {
          $this->condition_met($context);
        }
      }
    }
  }

$_SERVER["QUERY_STRING"] is not always defined (and throws a PHP Notice when I run Cron).

Later, in this function of class context_condition_query_string...

protected function parse_query_string($str) {
    $op = array();
    $pairs = explode("&", $str);
    foreach ($pairs as $pair) {
      list($k, $v) = explode('=', $pair);
      $op[$k] = $v;
    }
    return $op;
  }

I get an undefined offset PHP notice - I guess because $pair may not actually be an array. If those are (or were) fixed, I'd call this bad boy "ready to go". Both are minor issues.

zabelc’s picture

This works very well for me against 7.x-3.0-beta4. I did have to patch with -p1 though.

alanom’s picture

StatusFileSize
new4.42 KB

Is there a good reason why this work from well over a year ago hasn't been tidied up and committed? Maybe it's just my setup but the patch(es) seem to have gone stale against -dev.

Here's a patch that:

  • Merges #21 and #13
  • Acts on #24's comments:
    • It checks $_SERVER["QUERY_STRING"] exists before trying to use it
    • It forces any query strings without '=' that it encounters (e.g ?one=1&two&three=3) into the same array structure as the others, using true as the value

Based on the latest -dev release. If you don't see the 'Query string' option in the Context UI dropdown after applying, I found I had to disable then enable the module before it appeared (clearing caches didn't help).

mrfelton’s picture

StatusFileSize
new2.1 KB

Patch from ##26 updated to apply cleanly against latest code

mrfelton’s picture

StatusFileSize
new2.99 KB

Last patch seemed to be missing the new file that provides the plugin.

tsi’s picture

Status: Needs review » Reviewed & tested by the community

Last patch works great with 7.x-3.0-beta4.
@alanomaly - no need to disable-enable context, running update.php did the trick for me.

tribe_of_dan’s picture

Is it possible to backport this to d6? I have a site that would love to have this.

weseze’s picture

#28 works great here. I did have the clear cache 2 times before the plugin showed up in context.

nightlife2008’s picture

Is this going to be added to any release any time soon?

I got some remarks from a client that I should move this patch into a separate module with context hooks, but if this is going to be in the upcoming release, it's an obsolete remark.

Thanks in advance!

colin_young’s picture

I vote for including this in the core context. It seems like a general enough requirement and is very similar to the existing path context.

I am trying to implement this in the meantime in my custom feature-based module, but I can't get the new context to appear. Both hooks (hook_context_plugins and hook_context_registry) seem to run (at least watchdog adds events to the log if I log events within those hooks). I'm going to keep an eye on this thread, but in the meantime I'm going to enhance my PHP condition to satisfy my requirements for query string matches.

kalis1’s picture

Just a note to confirm that patch in #28 works well with 7.x-3.0-beta6.

brunorios1’s picture

it is working on my localhost but it isn't in production.
any help?

NaX’s picture

@brunorios1
Is there a difference in PHP versions maybe and have you flushed the cache

brunorios1’s picture

@Nax,

i was using .htaccess rules to redirect the users to a folder with the drupal site, like this:

Options -Indexes
RewriteEngine on
Options +FollowSymLinks

RewriteRule ^$ mydomain/index.php [L]
RewriteCond %{DOCUMENT_ROOT}/mydomain%{REQUEST_URI} -f
RewriteRule .* mydomain/$0 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* mydomain/index.php?q=$0 [QSA]

so i moved the site to the root and it works!

thanks!

lpeabody’s picture

Figured I would add my vote to move this into core Context.

dealancer’s picture

The patch #28 does not add new context condition for me :-/ 7.x-3.0-beta6 is used.

NaX’s picture

@dealancer
Try flushing your Drupal cache or some have suggested that you need to run update.php.

kristen pol’s picture

RTBC++ #28 works great! This is very useful and works great with Meta Tags (you can specify meta tags for pager pages like foobar?page=1) using the metatag_context module. Please commit :)

[update] For those not seeing it, clear your cache multiple times.

dddbbb’s picture

RBTC +1

Have used the patch in #28 against Context 7.x-3.0-beta6 and it works great (flushed cache several times as recommended).

iamEAP’s picture

For those who need this functionality and are not able or willing to patch Context, I broke this off into a module with a little bit more flexibility (and unit tests):

https://drupal.org/project/context_query_param

kristen pol’s picture

Thanks @iamEAP! That sounds awesome :) Since this issue is 3 years old and the patch is 9 months old, it doesn't look like this is getting into Context any time soon :/

f0ns’s picture

When I install this module (https://drupal.org/project/context_query_param) with Context 7.x-3.0-beta7 the Context Module stops working, no errors are given. The patch on #28 works with Context 7.x-3.0-beta7!

iamEAP’s picture

@f0ns, could you file a bug report in the Context Query Parameters issue queue?

iamEAP’s picture

Issue summary: View changes

fix typos

colan’s picture

Issue summary: View changes
Status: Reviewed & tested by the community » Fixed

Committed in cf46694.

leex’s picture

Great to see this committed.

For those having trouble I had to format like this when targetting a specific value equals:

*shs_term_node_tid_depth=30*

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

tmcfarlin4’s picture

#48 Thank you. The context was being recognized on my local without the asterisks, but migrating to server resulted in it not! The asterisks were necessary.. have yet to identify why this worked in one environment.

steveOR’s picture

Yes #48 thank you, I was lucky to find this thread right away. You may not need the asterisks around the query string value when working locally, but when you try your contexts on Pantheon or Acquia for instance then they ain't gonna work without the enclosing asterisks!

Katy Jockelson’s picture

Thank you everyone, particularly iamEAP for the module :)