Been testing the latest 4.7 imagecache with 4.7.6, clean url's. Imagecache working fine everywhere except for filenames with special characters, especially the # and & chars. The problem is that there are many other modules for uploading images (like upload etc.) which don't choke on these paths and the images are perfectlly viewable. With a gallery site, many users like to name files things like image #1, image #23 etc. I think the code is failing in the file_copy or file_move are, but I'm not sure. I thought I'd see if there is a simple workaround before I started looking in-depth. I've tried the usual variants of urldecode/encode, but the problem is that the cache file is not event getting created.

Thanks for any help.

Comments

chrisschaub’s picture

Sorry, should be "the files are not EVEN getting created. Too early, not enough coffee.

quicksketch’s picture

Category: bug » support

Have you tried passing the image through the imagecache theme function? You shouldn't ever be calling the image directly anyway because of this sort of problem, the theme function encodes it for you and saves a lot of typing:

Bad:

<img src="<?php print file_directory_path() .'/imagecache/thumbnail/'. $path; ?>"  />

Good:

print theme('imagecache', 'thumbnail', $path);
jeffsimm’s picture

Hey Guys,

I can verify that this is happening in the 5.x-1.2 version as well. Give you an example I tried uploading a photo with the filename of JacksonHole_golf_G&T.jpg. It would show a broken image every time. Looking at the directory where the thumbnail and full-size images are saved, the file was not there. The file is not being created. I tested this in Firefox 1.5, 2 and IE 7 on WinXP.

Removing the "&" from the filename fixed the problem. The image was created and uploaded to the correct directory.

Not a huge deal, but it will make our editors job a little more difficult, having to remove these type of characters from every file name. Let me know if there is anything I can do to help. I appreciate it.

Thanks.

Jeff Simmonds.

Zach Harkey’s picture

You shouldn't ever be calling the image directly anyway because of this sort of problem

What if you need to know the size of the image outside of the image tag? (Something I find I need on a regular basis).

For example, What if I would like to contain the image in a div that is the exact width of the image, so that I can include a caption beneath it? How do you recommend achieving this kind of output:

<div style="width: 275px">
  <img src="path/to/imagecache/medium/example.jpg" width="275" height="200" alt="" />
  <p class="caption">Caption here</p>
</div>

This way the caption never exceeds the width of the image before wrapping. And the whole DIV can be floated inside another body of text.

Or what if you wanted to visibly display the image size, as you might on a photo download site?

For example:

<img src="path/to/imagecache/medium/example.jpg" width="275" height="200" alt="" />
<p>Download: <a href="path/to/imagecache/medium/example.jpg">275 x 200</a></p>

As far as I know, the only way to make this information available to a template, outside of the image tag, is to do something like this (for second example above):

<?php
  $namespace = 'foo';
  $path = 'bar';
  $imagecache_path =  file_create_url(file_directory_path() .'/imagecache/'. $namespace .'/'. $path);
  // Encode spaces so that getimagesize() will work.
  $imagecache_path = str_replace(' ', '%20', $imagecache_path);
  $imagesize = getimagesize($imagecache_path);
?>

<?php print theme('imagecache', $namespace, $path) ?>
<p>Download: <a href="<?php print $path ?>"><?php print $imagesize[0] ?> x <?php print $imagesize[1] ?></a></p>

Is there a better way that I'm not aware of to achieve this?

Zach Harkey’s picture

Also, what if you just need the path and not the image? Like you would for a link, or background image?

For example:

<div style="background-image: url(path/to/imagecache/large/example.jpg)">
<!-- content here -->
</div>

Is there a better way than this:

<div style="background-image: url(<?php print file_directory_path() .'/imagecache/large/'. $path; ?>)">
<!-- content here -->
</div>

And what about when you want to make a link directly to an image, as you might for a popup or lighbox?

<a href="path/to/imagecache/large/example.jpg" class="thickbox">View large version of this image</a>

The only way I know to achieve this (aside from using Drupal's l() function, which amounts to the same thing in this case) would be:

<a href="<?php print file_directory_path() .'/imagecache/large/'. $path; ?>" class="thickbox">View large version of this image</a>
quicksketch’s picture

Yeah, imagecache doesn't provide a mechanism that just returns the path, that's a good point. It also seems that images are not created when the file contains an ampersand (I've not extensively tested). If you submit a patch to provide the path via an imagecache_ function I'll make sure it gets in. Confirming that it works with special characters put this to rest.

trevortwining’s picture

I just wanted to ask if anyone had done anything further? If I could get a bit more detail about how the encoding is breaking the paths, I could take a stab at writing a patch if one doesn't exist yet.

Junyor’s picture

According to http://drupal.org/node/134201, imagecache fails if the filename contains a +, too.

izaak’s picture

Subscribing. I am actually not sure if my problem is the same, it seems like either filenames with spaces are failing or files with pluses (or both).

themselves’s picture

I'm having the same problem. While this isn't a site-destroying issue for me at the moment (if I notice a broken image, I just rename and reupload it for the user), it'd certainly be nice to get a fix for it. I think so long as we can support the characters that Windows allows in filenames, that should cover most of the Internet-using population. I guess full UTF-8 support is a bit much to ask ;)

Zach Harkey’s picture

After much in-depth experimentation I finally found a solution that doesn't trip up on special characters like ampersands and spaces and can be implemented at the theme level.

In the second line of the function I changed $path to drupal_urlencode($path)

In template.tpl add the following function

function phptemplate_imagecache($namespace, $path, $alt = '', $title = '', $attributes = NULL) {
  $attributes = drupal_attributes($attributes);
  $imagecache_path = file_create_url(file_directory_path() .'/imagecache/'. $namespace .'/'. drupal_urlencode($path));
  return '<img src="'. $imagecache_path .'" alt="'. check_plain($alt) .'" title="'. check_plain($title) .'" '. $attributes .' />';
}
themselves’s picture

I tried this out, and it allows the file with spaces/whatever to upload ok, but it didn't generate any thumbnails for it. I could see the image if I went to the edit tab of the node, but yeah... nowhere else. I only changed the imagecache.module in one place;

function theme_imagecache($namespace, $path, $alt = '', $title = '', $attributes = NULL) {
  $attributes = drupal_attributes($attributes);
  $imagecache_path =  file_create_url(file_directory_path() .'/imagecache/'. $namespace .'/'. drupal_urlencode($path));
  return '<img src="'. $imagecache_path .'" alt="'. check_plain($alt) .'" title="'. check_plain($title) .'" '. $attributes .' />';
}

Perhaps there's more places we need to add the url encoding? This is in 5.1 btw, i'm not sure if that makes a huge difference.

introfini’s picture

It also happens with the characters ( and ). I'm using 5.1

Regards,
introfini

introfini’s picture

I'm sorry, i tested it better and it's ok with the '(' and ')'.

Thanks.
introfini

sun’s picture

FYI: Regarding character encoding of uploaded files: Imagefield suffers from this, too.

sun’s picture

This is a Drupal core issue. You definitely should test Transliterate filenames module. Please report back if that module works for you (and mark this issue fixed if it does).

Junyor’s picture

If it's a core issue, it needs to be fixed in core, not with another third-party module.

sun’s picture

Sure, you can try to convince core developers to implement a similar fix in Drupal. However, there have been many complaints about missing transliteration in core in the past. Furthermore, there are several transliteration projects and it is not yet clear which one works out best. Thus, this whole thing will need quite some time to hit core and like with any other core feature, it is initiated in contrib best.

There is quite much code needed for proper transliteration. Thus, if any file-related module would implement its own transliteration, the overall codebase would be bloated. file_translit intentionally includes that code bubble only if it is indeed required, so there should not be any performance issues. Additionally, this issue is about Drupal 4.7. Chances that any transliteration in D7 or D8 will be back-ported to 4.7 are nearly zero.

ms2011’s picture

Files/URLs are not accessible if they contain reserved or non-ascii characters.
See url_generation.patch here http://drupal.org/node/43505#comment-316523

gollyg’s picture

subscribe

dopry’s picture

Status: Active » Closed (won't fix)

This is a core issue. please install the transliteration module.

vgodard’s picture

Version: 4.7.x-1.1 » 6.x-2.0-beta8

For drupal 6 just replace this
$imagecache_url = imagecache_create_url($namespace, $path);
with
$imagecache_url = imagecache_create_url($namespace, drupal_urlencode($path));
works really well !

peterparker’s picture

I have tried all of these suggestions, and while using beta 10 images with a + symbol do not display. Has there been any more progress on this front? I am using the transliteration module.

peterparker’s picture

Yipeeeee.

I have finally found a solution to this problem, since none of the previous solutions were working for me.

Taking a cue from #22, in the imagecache.module I replaced

function imagecache_create_url($presetname, $filepath, $bypass_browser_cache = FALSE) {
  $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);
  }
}

with

function imagecache_create_url($presetname, $filepath, $bypass_browser_cache = FALSE) {
  $path = _imagecache_strip_file_directory($filepath);
  if (module_exists('transliteration')) {
    $path = drupal_urlencode($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);
  }
}

The difference is on line 4, where I substituted transliteration_get with drupal_urlencode.

While I am not altogether certain why #22 alone did not solve the problem, I am glad to have at least a temporary solution. Hope it can be of help to others.

mcurry’s picture

subscribe

rv0’s picture

subscribe

beauz’s picture

subscribing, have a site where client has uploaded images with a & character and this has resulted in a broken link when viewing. I have used a workaround for now.

rv0’s picture

@ beauz

try installing transliteration module..