Trying to get expires working with Varnish, and it seems to be getting confused with translations. If I edit content from example.com then everything is fine, but from example.com/en/ it seems to add the extra /en/ in to half of the paths. Any suggestions?

Input: Array
(
    [0] => node/add
    [1] => node/add/page
    [2] => node/add/blog
    [node] => node/3787
)

Output: Array
(
    [0] => https://example.com/en/node/add
    [1] => https://example.com/en/en/node/add
    [2] => https://example.com/en/node/add/page
    [3] => https://example.com/en/en/node/add/page
    [4] => https://example.com/en/node/add/blog
    [5] => https://example.com/en/en/node/add/blog
    [6] => https://example.com/en/node/3787
    [7] => https://example.com/en/en/path-alias
)

Modules Using hook_expire_cache(): Array
(
    [0] => varnish
)

Comments

pjnes’s picture

This seems to be caused by the way the base path part is generated:

It uses 2 separate url() function calls and joins them together. Both of those url calls are adding the /en/ part to the path.

budda’s picture

Version: 7.x-1.0-beta1 » 7.x-1.x-dev
Priority: Normal » Major

This problem still occurs with the -dev release.

I can recreate it and the url() function double use seems to be the cause, but I can't quite get a 100% fix for it to work myself :-S

Input: Array
(
    [node] => node/3614
    [term520] => taxonomy/term/520
)

Output: Array
(
    [0] => http://test.drupal.dev:8080/en/node/3614
    [1] => http://test.drupal.dev:8080/en/en/node/3614
    [2] => http://test.drupal.dev:8080/en/taxonomy/term/520
    [3] => http://test.drupal.dev:8080/en/en/english
)

This problem may be related to the fix committed in #1471926: Invalid expire URLs when "Include base URL in expires" is enabled. ?

budda’s picture

If I disable the include base_url option the output is:

Input: Array
(
    [node] => node/3614
    [term520] => taxonomy/term/520
)

Output: Array
(
    [0] => node/3614
    [1] => en/node/3614
    [2] => taxonomy/term/520
    [3] => en/english
)
budda’s picture

So the problem of the language being added in to the path is caused by $path_alias = url($path, array('absolute' => FALSE));

In comment above example the path '[1] => en/node/3614' should not be valid as that's the french version of a node. The en version is node/3062.

budda’s picture

This problem may be more deep rooted in the expire_node() module function.

If i update a node of the french translation (nid: 3614) - the $node being passed in to the function expire_node($node) is actually the french $node->tnid (node:3602), rather than the one I just edited (nid: 3614)!

My knowledge of Drupal's multilingual stuff is fading at this point.

ravencoder’s picture

Hi Guys,

I have also looked into this issue. And I found a fix to the issue. Can you help check if it this works:

+++ expire.module
@ -414,7 +414,7 @@ function expire_cache_derivative($paths,
     }

     // Path alias
-    $path_alias = url($path, array('absolute' => FALSE));
+    $path_alias = drupal_lookup_path('alias', $path);
     // Remove the base path
     $expire[] = substr($path_alias, strlen($base_path));

basically, it replaces the url() function with the drupal_lookup_path() instead.

budda’s picture

By using drupal_lookup_path() we're now not seeing any country prefix in the url at all. Should the 3rd argument $path_language be used ?

ravencoder’s picture

Hi,

I've checked the code again. I left out the fact that the module has option to exclude/include base_url's.

Basically, the issue is that url() function in D7 always adds the language prefix by default. and the function expire_cache_derivative() (in expire.module) is calling the url() function twice, leading to extra language prefixes on the output's URL.

Please have a look at my new patch this time:
I still havent tested this with domain access module enabled.

+++ expire.module       2013-05-08 13:23:19.895333959 +0800
@@ -452,10 +452,12 @@ function expire_cache_derivative($paths,
         // If domain access is enabled the $base_urls is an array with configured subdomains
         if (is_array($base)) {
           foreach ($base as $subdomain) {
+            $subdomain = str_replace(parse_url($subdomain, PHP_URL_PATH), "", $subdomain);
             $urls[] = $subdomain . $path;
           }
         }
         else {
+          $base = str_replace(parse_url($base, PHP_URL_PATH), "", $base);
           $base = rtrim($base, '/') . '/';
           $urls[] = $base . $path;
         }
pjnes’s picture

StatusFileSize
new1012 bytes

I've tested the changes posted by ravencoder and they work for me.

Attaching a patch of those changes that applies to the 1.x-dev branch

jaydub’s picture

Status: Active » Needs review
budda’s picture

ravencoder’s picture

StatusFileSize
new712 bytes

Hi,

the issue are not quite the same. But the solution is pretty similar to my first suggestion at #6. For this issue here, PJnes's patch (#9) combines both my suggestions which should not be the case, the problem with it is that we will not have country prefix at all.

I am attaching a patch version of comment #8. Please see if fixes the problem.

pobster’s picture

I figure I can probably hijack this thread as I'm having a similar problem to the title (which is generic enough that maybe it should be changed?) However my problem is a bit more nasty and I'm using domain language URLs...

$path_alias = url($path, array('absolute' => FALSE));

In certain circumstances the 'absolute' *always* gets parsed as TRUE. In my case, because locale module eventually runs 'locale_language_url_rewrite_url' which when used with LOCALE_LANGUAGE_NEGOTIATION_URL_DOMAIN enforces absolute URLs. The huge downside to this is that now expire module receives something its not expecting and so with this line;

$expire[] = substr($path_alias, strlen($base_path));

Strips off the first character of the path!

Mine looks like this...

[0] =>
[1] => ttp://stage.xxx.com.au/%3Cnolink%3E
[2] => node/1183
[3] => ttp://stage.xxx.com.au/node/1183
[4] =>
[5] => rss.xml
[6] => node/424
[7] => ttp://stage.xxx.com.au/
[8] => taxonomy/term/137
[9] => ttp://stage.xxx.com.au/taxonomy/term/137

It looks even worse if expire_include_base_url isn't disabled!

If you think this is unrelated enough, I'll raise another ticket.

Here's what I'm currently doing (based on https://drupal.org/node/1936490#comment-7342340), although I feel dirty doing it;

    // Path alias
    $path_alias = drupal_lookup_path('alias', $path);
    // Remove the base path
    if (preg_match('/^' . preg_quote($base_path, '/') . '/', $path_alias)) {
      $expire[] = substr($path_alias, strlen($base_path));
    }
    else {
      $expire[] = $path_alias;
    }

Thanks,

Pobster

spleshka’s picture

Status: Needs review » Fixed

Please, check out new 7.x-2.x branch. This problem should gone.

spleshka’s picture

Version: 7.x-1.x-dev » 7.x-2.x-dev

Forgot to change version number.

Status: Fixed » Closed (fixed)

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