Requested feature - Support the rewriting of paths to images that have been created by the ImageCache module. Presumably, this would require two things:

1) Additions/changes to the custom_file_url_rewrite() function in the cdn.module to support paths that were created by ImageCache in addition to the Drupal core paths.

2) Additions/changes to the imagecache_create_url() function in the imagecache.module file. I am assuming these changes would look very similar to the Drupal Core modifications inside of file.inc. The only difference would be to either call a new function custom_file_imagecache_url_rewrite or a modification of the custom_file_url_rewrite as mentioned above, with a notice that it is dealing with imagecache paths and not Drupal core paths.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

rjbrown99’s picture

I'm actually thinking it may be better to do it a bit differently. Inside of the ImageCache module and imagecache_create_url() function, sort out all of the path issues first and then pass the full path to the ImageCache-created images to custom_file_url_rewrite. That way the CDN module can keep on doing its thing and it just happens to get the right path from the get-go rather than having to deal with passing presets or other variables.

Thoughts?

elliotttf’s picture

I ran into this same problem recently. I have attached the code I used to side-step the issue at the theme layer although I'm not sure this is optimal.

<?php
/**
 * Implementation of theme_imagecache()
 * NOTE: change theme_ to your theme's name and put this in template.php
 */
function theme_imagecache($presetname, $path, $alt = '', $title = '', $attributes = NULL, $getsize = TRUE) {
  // Check is_null() so people can intentionally pass an empty array of
  // to override the defaults completely.
  if (is_null($attributes)) {
    $attributes = array('class' => 'imagecache imagecache-'. $presetname);
  }
  if ($getsize && ($image = image_get_info(imagecache_create_path($presetname, $path)))) {
    $attributes['width'] = $image['width'];
    $attributes['height'] = $image['height'];
  }

  $attributes = drupal_attributes($attributes);

  $path = _imagecache_strip_file_directory($path);
  if (module_exists('transliteration')) {
    $path = transliteration_get($path);
  }

  // check to see if the file exists locally.  If not get it so imagecache will
  // build the derivative image
  if (!file_exists(file_directory_path() .'/imagecache/'. $presetname .'/'. $path)) {
    drupal_http_request(url(file_directory_path() .'/imagecache/'. $presetname .'/'. $path, array('absolute' => TRUE)));
  }

  $args = array('absolute' => TRUE, 'query' => empty($bypass_browser_cache) ? NULL : time());
  if (variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC) == FILE_DOWNLOADS_PUBLIC) {
    $imagecache_url = file_create_url(file_directory_path() .'/imagecache/'. $presetname .'/'. $path);
  }
  else {
    $imagecache_url = url('system/files/imagecache/'. $presetname .'/'. $path, $args);
  }

  return '<img src="'. $imagecache_url .'" alt="'. check_plain($alt) .'" title="'. check_plain($title) .'" '. $attributes .' />';
}
?>

Basically I put the imagecache_create_url() code in theme_imagecache and added a line to check to see if the derivative image had been built yet. If not I requested it without the CDN so the derivative would be built. I'm not sure if others had this problem as well but in my case the CDN wasn't causing the derivative images to be built.

rjbrown99’s picture

I took a bit of time and wrote a patch to imagecache.module's imagecache_create_url function today. This is very similar to the Drupal core CDN patch because it is based on that function. I'm just starting to test this, but it works like my other patch where it will not rewrite the URL if the page is HTTPS (because I'm using Cloudfront and they do not support serving static content via HTTPS.)

Here it is. I have done very limited testing but so far it works for me. All of the images are already in the CDN because file conveyor is pushing them there for me. I believe this will also work properly to create the initial cached images since custom_file_url_rewrite will fail and serve the content locally which should trigger the image cache creation process.

function imagecache_create_url($presetname, $filepath, $bypass_browser_cache = FALSE) {
  // Check if the CDN function is available
  if (function_exists('custom_file_url_rewrite')) {
    // If we have CDN, don't rewrite if the page is secure
    if (function_exists('securepages_is_secure') && securepages_is_secure()) {
      // We fail this test with a securepage and go to serving from locally below 
      $rewritten_path = FALSE;
    } else {
      $rewritten_path = custom_file_url_rewrite($filepath);
      if ($rewritten_path != FALSE) {
        // If that function worked, we stop right here and return the new path.
        return $rewritten_path;
      }
    }
  }

  // Otherwise serve the file from Drupal's web server. This point will only
  // be reached when either no custom_file_url_rewrite() function has been
  // defined, or when that function returned FALSE, thereby indicating that it
  // cannot (or doesn't wish to) rewrite the URL. This is typically because
  // the file doesn't match some conditions to be served from a CDN or static
  // file server, or because the file has not yet been synced to the CDN or
  // static file server.

  $path = _imagecache_strip_file_directory($filepath);
  if (module_exists('transliteration')) {
    $path = transliteration_get($path);
  }
  $args = array('absolute' => TRUE, 'query' => empty($bypass_browser_cache) ? NULL : time());
  switch (variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC)) {
    case FILE_DOWNLOADS_PUBLIC:
      return url($GLOBALS['base_url'] . '/' . file_directory_path() .'/imagecache/'. $presetname .'/'. $path, $args);
    case FILE_DOWNLOADS_PRIVATE:
      return url('system/files/imagecache/'. $presetname .'/'. $path, $args);
  }
}
rjbrown99’s picture

Maybe we need to add some kind of admin UI checkbox and if statement inside cdn.module's custom_file_url_rewrite function to disable rewriting of CDN paths for SSL. I'm still not convinced I am doing it in the right place.

rjbrown99’s picture

#3 still not working right - it's returning the path of the original large image, not the imagecached small image.

rjbrown99’s picture

OK, here's one that works to pull out the correct imagecache paths from the CDN.

I would submit this for review in the imagecache module page, but I'd like to hear if anyone else has feedback on the SSL/SecurePages stuff first and the best place to integrate it - either in core patches and imagecache patches or in the function inside of cdn.module.

function imagecache_create_url($presetname, $filepath, $bypass_browser_cache = FALSE) {

  // Check if the CDN function is available
  if (function_exists('custom_file_url_rewrite')) {
    // If we have CDN, don't rewrite if the page is secure
    if (function_exists('securepages_is_secure') && securepages_is_secure()) {
      // We fail this test with a securepage and go to serving from locally below
      $rewritten_path = FALSE;
    } else {
      // First create the correct imagecache preset path
      $path = _imagecache_strip_file_directory($filepath);
      if (module_exists('transliteration')) {
        $path = transliteration_get($path);
      }

      $icpath = ('/' . file_directory_path() .'/imagecache/'. $presetname .'/'. $path);
      $rewritten_path = custom_file_url_rewrite($icpath);
      if ($rewritten_path != FALSE) {
        // If that function worked, we stop right here and return the new path.
        return $rewritten_path;
      }
    }
  }

  // Otherwise serve the file from Drupal's web server. This point will only
  // be reached when either no custom_file_url_rewrite() function has been
  // defined, or when that function returned FALSE, thereby indicating that it
  // cannot (or doesn't wish to) rewrite the URL. This is typically because
  // the file doesn't match some conditions to be served from a CDN or static
  // file server, or because the file has not yet been synced to the CDN or
  // static file server.

  $path = _imagecache_strip_file_directory($filepath);
  if (module_exists('transliteration')) {
    $path = transliteration_get($path);
  }
  $args = array('absolute' => TRUE, 'query' => empty($bypass_browser_cache) ? NULL : time());
  switch (variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC)) {
    case FILE_DOWNLOADS_PUBLIC:
      return url($GLOBALS['base_url'] . '/' . file_directory_path() .'/imagecache/'. $presetname .'/'. $path, $args);
    case FILE_DOWNLOADS_PRIVATE:
      return url('system/files/imagecache/'. $presetname .'/'. $path, $args);
  }
}
Wim Leers’s picture

Please wait with posting that to the imagecache issue queue.

The CDN integration module uses the custom_file_url_rewrite function. But the Drupal core patch uses a hook: hook_file_url_alter(). Initially, they agreed with the special function approach, as the same approach is used for rewriting URLs. But now they're shifting all of the URL rewriting functions (including file URL rewriting) to using hooks, to prevent confusing developers with this special case, and because then you can have a module implementing it, instead of having to add some special code.

So, I will first have to update the CDN integration module to use the same approach as D7 core. Issue: #610322: Upgrade the Drupal 6 core patch to match the committed Drupal 7 core patch.

gilgabar’s picture

It looks like the preceding slash is unnecessary in $icpath. This:

$icpath = ('/' . file_directory_path() .'/imagecache/'. $presetname .'/'. $path);

works better as this:

$icpath = (file_directory_path() .'/imagecache/'. $presetname .'/'. $path);

Otherwise I get double slashes like: http://example.com//files/imagecache/thumb_small/somefile.jpg

Other than that it appears to solve the problem for me. Thank you very much.

torgosPizza’s picture

Subscribing.

Wim Leers’s picture

Assigned: Unassigned » Wim Leers
Status: Active » Fixed
FileSize
1.2 KB

Thanks for posting your approach, rjbrown99!

I did it in a slightly more elegant manner though, which required less code. On the other hand, I did drop support for SecurePages for now, because it won't be necessary when you're using the CDN integration module in advanced mode: then it can be handled automatically already. See my lengthy follow-up #3 in #568954: HTTPS support for details :)

I've attached the included ImageCache patch. I've also added the necessary documentation of course.

Commit: http://drupal.org/cvs?commit=323422.

emcee0’s picture

Is the fix included with the current download or would we need to perform the patch?

Wim Leers’s picture

It's not included in the ImageCache module, you'll have to apply the patch. After 1-2 months of real-world use, I'll submit it for inclusion to ImageCache. I first want to make sure that it works flawlessly for everybody.

Status: Fixed » Closed (fixed)

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

ManyNancy’s picture

Can this module put images on a remote cdn but still use existing paths? My users need to link extensively to images and work with direct image paths all the time.

Thanks!

BenK’s picture

Subscribing...

frankcarey’s picture

Status: Closed (fixed) » Active

@Wim Leers - so is this patch a go? should we cross post it with imagecache?

bcmiller0’s picture

subscribing

Exploratus’s picture

subscribe..

frankcarey’s picture

Project: CDN » ImageCache
Version: 6.x-1.x-dev » 6.x-2.x-dev
Component: Module » Code

Cross posting this to imagecache

Coupon Code Swap’s picture

+ subscribe

rjbrown99’s picture

Status: Active » Needs review

Changing to needs review since it's now in the ImageCache queue.

Can someone who has tested this please chime in with results? It would be nice to get some solid test results and move to Reviewed/Tested.

Exploratus’s picture

I use it and it works great. Url are rewritten properly.

jphil’s picture

Category: feature » support

Hi,

I'm trying to run the latest version of this patch for imagecache.module

patch < imagecache_6--2.patch

and am getting this error:

patching file imagecache.module
Hunk #1 FAILED at 320.
1 out of 1 hunk FAILED -- saving rejects to file imagecache.module.rej

Setup:
- Pressflow 6
- ImageCache 6.x-2.0-beta10
- CDN 6.x-2.0-rc5

Any help very much appreciated!

thanks,
Justin

p.s. I the latest from here too, no joy :
http://drupal.org/node/940096

Wim Leers’s picture

Issue tags: +file_create_url, +CDN, +WPO
FileSize
1.01 KB

@jphil:

Use patches/imagecache.patch in the CDN module instead.the imagecache_6--2.patch is intended to be used on the latest of the 6.2 branch, not on the 2.0 beta 10 release.

This is documented, too:

2) Note: skip this step if you want to rely on the fallback mechanism!
   Apply the ImageCache patch (patches/imagecache.patch), if you want to serve
   images generated by the ImageCache module from a CDN. This is a separate
   patch because it uses its own custom function to generate file URLs.
   There are multiple patches for ImageCache:
   - version 2.0, beta 10: patches/imagecache.patch
   - version 2.0, head of branch: patches/imagecache_6--2.patch

@module maintainers: here is the updated patch. Feedback is welcome.

jphil’s picture

my mistake, thank you :)!!

3dloco’s picture

+1

broncomania’s picture

Hi,

I'm trying to run the latest version of this patch like jphil for imagecache.module

and am getting this error:

$ patch < imagecache.patch
patching file imagecache.module
Hunk #1 FAILED at 318.
1 out of 1 hunk FAILED -- saving rejects to file imagecache.module.rej

Setup:
- Pressflow 6
- ImageCache 6.x-2.0-beta10
- CDN 6.x-2.0

I tried both of the patches. The first like jphils throw his error and this is the result of the other.

Any help very much appreciated!

thanks,
Bronco

obrienmd’s picture

+1, would love to see this patch committed.

Wim Leers’s picture

@broncomania: the patch *does* work for beta 10. Please ensure you're actually using beta 10.

Also, we've now been in this issue for >1 year and there hasn't even been a comment from a maintainer. How are we to proceed, then?

obrienmd’s picture

Pinged maintainer, drewish, via e-mail listed on his site.

Magnus’s picture

I'm not a maintainer of this module. Have just committed translations. There has been little development on the 6.x-branch, but I guess this patch would have better chance of getting committed if someone reviewed it and set the status to "reviewed & tested by the community".

obrienmd’s picture

Status: Needs review » Reviewed & tested by the community

Thanks! Marked tested.

praestigiare’s picture

Category: support » feature
Status: Reviewed & tested by the community » Needs work

Is there a reason that this patch specifically checks for the CDN module? It leaves out anyone who implements a custom hook_file_url_alter(). As far as I can tell, there is no need to check for the CDN module, since there is no downside to having ImageCache call file_create_url even if the hook_file_url_alter patch is not applied.

praestigiare’s picture

FileSize
616 bytes

Here is a patch which basically does the same thing, but without relying on the CDN module.

praestigiare’s picture

That patch is against 6.x-2.0-beta10

obrienmd’s picture

Status: Needs work » Reviewed & tested by the community

Patch in #34 works great for me.

drewish’s picture

Status: Reviewed & tested by the community » Needs review
FileSize
967 bytes

Finally had a chance to look at this and I don't really like calling file_create_url() from inside imagecache_create_url() but I'd be interested in calling the hook from imagecache_create_url(). Thoughts?

Update: Sorry about the patch prefix... and I really do want to kill off that transliteration stuff but it probably shouldn't have been included here.

praestigiare’s picture

FileSize
941 bytes

I had the same thought about calling the hook directly based on the code comments, but wasn't sure if file_create_url was being used for a reason. That said, I am not sure the patch in #37 does the same thing as the previous ones for the following reasons:

1. With this patch, hook_file_url_alter is called on the path after the files directory path has been stripped, while in file_create_url it is called with the path including the files directory path. This means if an implementation of hook_file_url_alter relies on that part of the path, it will fail for ImageCache paths.

2. If a hook_file_url_alter changes the path, imagecache_create_url immediately returns the result (mirroring the implementation in file_create_url), however in this case that path is for the source image. It does not add the segments for derivative.

The following patch addresses these issues.

praestigiare’s picture

FileSize
1.4 KB

Okay, I made a few changes to take into account that a path should be considered final once hook_file_url_alter has run. I also added some comments. I have this running on a test site now.

obrienmd’s picture

Status: Needs review » Reviewed & tested by the community

Latest patch works for me.

praestigiare’s picture

I've had the patch in #39 running in production for two weeks.

obrienmd’s picture

Agreed, #39 has been in production on a number of our sites using CDN for over a month now, with no issues. Can we get this committed to -dev?

drewish’s picture

Status: Reviewed & tested by the community » Needs review
FileSize
1.33 KB

Marked #809184: Add API to modífy imagecache path prefix as a duplicate.

I committed #574204: Wrong integration with Transliteration so that doesn't need to be part of this patch any longer.

Found one small bug in #39 we setting $oldpath but reading $old_path.

drewish’s picture

Why aren't we calling the alter on private files? Looking at PressFlow's file_create_url() which backports hook_file_url_alter() they run it on both. They also have the code for stripping slashes off Windows paths that I'd copied into #37.

drewish’s picture

FileSize
3.17 KB

Here's a rewrite of this based on PressFlow's file_create_url(). I tested it locally in the root of a site using public and private file transfers and it worked correctly. I put it up on one of our sites with CDN on it and it seemed to work fine with public transfers.

Update: I ment to mention that it needs testing in subdirectories and without clean URLs.

obrienmd’s picture

Tested #35 a bit, seems to work fine, with the caveat that I also don't have non-clean and sub-directory environments to work with.

drewish’s picture

obrienmd, did you mean #45?

obrienmd’s picture

Yes, #45, my apologies.

Lars Toomre’s picture

@drewish: I was just reading this patch. I am wondering now (with calls to the right custom url hook) if this revised function can be used to create and store derivative image files for a theme in a subdirectory under the theme directory (assuming it had right write permissions)? If so, this appears to help pave the way for serving different size theme images to a mobile device vis-a-vis large computer screen.

Thoughts?

drewish’s picture

Lars, I think you *could* use the alter to do that but I don't think it's the correct way. A better approach would be to have a mobile theme that uses different presets. Otherwise you'll run into a bunch of issues.

obrienmd’s picture

Status: Needs review » Reviewed & tested by the community

Tested w/ subdirectories and w/o clean URLs on 4 different sites, no problems found.

chrisarusso’s picture

I was still running into issues with derivative images not being created, but CDN taking over and spitting out the alternative URL (e.g. static.example.com/...) even if specified an absolute URL at the imagecache patch level. Since my CDN is just a VHost symlinked to my main directory, unless the main directory (i.e. www.example.com) is accessed from the browser, the derivative image is never built, and a 404 results. Therefore, the solution I went with was to check to see if the file exists at the patched imagecache level, and if not, manually call imagecache_build_derivative(). The file is then still served from the "CDN", and will generate the missing derivative image on any request where the image doesn't exist (like imagecache normally does without CDN).

If others are sharing this problem, and this is the appropriate article to post to, (the focus is a little varied for different users here) then I'll be glad to share the code.

drewish’s picture

Status: Reviewed & tested by the community » Fixed

I went ahead and committed the patch from #45 to 6.x-1.x. We've been using it in production for a few weeks and haven't noticed any issues.

emastyle’s picture

I have the same issue.
drupal 6.20 + Win 2003 + apache 2.2.9 + php 5.2.4
public download
no short url

To work I patched imagecache module to get the file like "index.php?q=files/PATH_TO_IMAGE_CACHE_PRESET...".
Whit this trick my my sites works (image get created) but CDN doesn't do the work (the "?" tell to my CDN to get the image every time it is requested).

torgosPizza’s picture

@emastyle, if you're using a "?q=" in your request (URL) means that Clean URLs are not enabled (possibly because they aren't supported by your server, and/or you have not turned Clean URLs on. Imagecache requires that you have Clean URLs enabled.

emastyle’s picture

Clean URL are disabled ... at the moment I cannot activate clean url ...
The strange think is that on my locally machine (mac + apache) it works well (clean url disabled).
If I call the image without "?q=" for the first time the imagecache creates the image preset correctly.
Not the same on the remote machine ... (on windows + apache).
I check the htaccess files and they seem correct.
Any other suggestions where I can check?
Bye

emastyle’s picture


Clean URL are disabled ... at the moment I cannot activate clean url ...
The strange think is that on my locally machine (mac + apache) it works well (clean url disabled).
If I call the image without "?q=" for the first time the imagecache creates the image preset correctly.
Not the same on the remote machine ... (on windows + apache).
I check the htaccess files and they seem correct.
Any other suggestions where I can check?
Bye

Finally I enabled short url (activate mod_url_rewrite), updated to imagecache 6.x-2.0-beta12 and now all seems working fine. CDN also works well.
Bye
Emanuele

ambreen’s picture

FileSize
1.2 KB

Drewish and I discovered that image cache presets bust for multi-lingual platforms. On my local server, the imagelinks would include a language prefix. Attached is a patch that resolves this error.

drewish’s picture

Status: Fixed » Needs review
NicolasH’s picture

subscribe

drewish’s picture

Committed to 6.x-2.x.

drewish’s picture

Status: Needs review » Fixed
NicolasH’s picture

Does this mean a patch is not required anymore for imagecache to work with CDN module?

torgosPizza’s picture

Yes, but it means you'll need to download the latest -dev version of the module until a new stable release is created.

Footeuz’s picture

Does a patch exist for the new version of Image cache Module 6.x-2.0-beta12 ?

Because I tried to patch it with no success.
I use Cdn in Origin Pull mode with nginx

drewish’s picture

Footeuz, can you provide more detail on what you mean by not working? Are you using Pressflow or the core patch to Drupal?

webfunkin’s picture

Even I tried patching. Seems like the original patch is not applicable to beta12. I read somewhere else that beta12 actually integrates the patch, but then CDN reports that my core files have not been patched or updated, which is not true.

drewish’s picture

cbrantley’s picture

I've got the same problem. URLs are being re-written to where the derivative SHOULD exist, but the derivatives are never being written. Care to share your solution?

drewish’s picture

cbrantley, are you using Pressflow or patched Drupal? Are the images served even though they're not written? Or are they just broken links?

drewish’s picture

Also grab the -dev release since it has the fix for the language code rewriting.

cbrantley’s picture

Drewish: Yes, I'm using Pressflow 6.20 and the dev versions of CDN and Imagecache. I'm also using cloudfront.

With CDN disabled everything works fine. When I enable CDN again the images that imagecache has already processed still work (with the rewritten URL pointing to the CDN) but no new images are processed by imagecache and the result are a bunch of broken (rewritten) links.

The simplest test was to edit one of my imagecache profiles where it generates an un-cached preview. With CDN enabled the preview returns a broken link to where the file SHOULD be on the CDN.

There's no errors anywhere, just broken links. It's as if imagecache never gets told it needs to generate the images, yet the URLS get rewritten.

For now I've just added "*/imagecache/*" to my blacklist so they aren't rewritten.

Thanks for your help!

btopro’s picture

sub

Status: Fixed » Closed (fixed)

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

spazfox’s picture

Status: Closed (fixed) » Active

I'm using the latest dev versions of CDN and ImageCache and am having problems similar to cbrantley in #72. I've also had to add */imagecache/* to my CDN blacklist to ensure that images show up appropriately on my site.

spazfox’s picture

I don't know if this is actually fixed or not in the latest dev releases (so I'm leaving it open for now), but I can confirm that my problem seems to have been caused by some malformed rewrite rules in my htaccess file to prevent hotlinking. Correcting those rules appears to have corrected the CDN/imagecache problem for me.

torgosPizza’s picture

Since your issue was unrelated to imagecache, and turned out to be an .htaccess issue, I'd suggest closing this issue again.

spazfox’s picture

Status: Active » Closed (fixed)

Done.

ywarnier’s picture

I'm having the same issue as in #52 and #72. On the same server with just vhosts serving as CDN, derivative images are not created by ImageCache, although the URL points to the CDN'ed version of where the derivative should have been written.

I'd love to have the code update suggested in #52 and an example of what rewrite conditions were causing #72 to fail.

ywarnier’s picture

I've added code in http://drupal.org/node/862880#comment-4888404 which effectively applies the patch suggested by illmasterc in comment #52 to fix the problem of ImageCache not generating the images when using CDN (maybe only when combined with Varnish?)

sandrewj’s picture

I think if you have access, you can add a rewrite directive on the vhost / CDN such as

  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_URI} !=/favicon.ico
  RewriteRule ^(.*)$ DRUPAL PATH/index.php?q=$1 [L,QSA]

This is the same code in the standard drupal htaccess file, but you will need to include whatever relevant path to get to your drupal index.php file.

If that does not work, you could try the solution outlines in this issue: #1250156: Enable Imagecache without Clean Urls and/or with alternate image server setup