The imagecache module allows defining image presets such as Small or Large which creates thumbnails or versions of the original image that is being uploaded.

When using imagecache module together with insert module to upload an image and insert it to the wysiwyg, it is possible to insert to the wysiwyg an image with the pre-defined preset so that an img element is created with a source attribute such as:
<img src="/system/files/imagecache/Large/test_image_1.png" />
or
<img src="/system/files/imagecache/Small/test_image_1.png" />

When mimemail parses the HTML to grab all these links and turn them into attachments for the email notification it is counting on the file name to create the attachments (in this case: test_image_1.png) instead of the actual file URL.
This results in a bug if the same file is created in the same node's body with different image presets (and generally this introduces a bug where-as two files with the same file name (basename) will always just use the first occurrence only).

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

lirantal’s picture

Status: Needs work » Needs review
FileSize
639 bytes

Patch for fixing this and relying on the filename for the static array as well as the md5.

sgabe’s picture

Status: Needs review » Needs work

You forgot to modify the $filenames array.

  if (isset($file) && (@is_file($file) || $content)) {

    if (!$name) $name = (@is_file($file)) ? basename($file) : 'attachment.dat';
    if (!$type) $type = ($name) ? file_get_mimetype($name) : file_get_mimetype($file);

    // Prevent duplicate items.
    if (isset($filenames[$file])) return 'cid:' . $filenames[$file];
    $content_id = md5($file) . '@' . $_SERVER['HTTP_HOST'];

    $new_file = array(
      'name' => $name,
      'file' => $file,
      'Content-ID' => $content_id,
      'Content-Disposition' => $disposition,
      'Content-Type' => $type,
    );

    $files[] = $new_file;
    $filenames[$file] = $content_id; // This needs to be changed too!

    return 'cid:' . $content_id;

But the most important is that we should only use $file if it is not the actual file content.

lirantal’s picture

Status: Needs work » Needs review
FileSize
893 bytes

You're right, thanks.
Here's an updated version.

Regards,
Liran Tal.

sgabe’s picture

Priority: Major » Normal
Status: Needs review » Needs work

Now you forgot the most important part. :) We need to check if we are dealing with the file content, in that case we can't use $file and we have to use the $name.

Furthermore as a response to the name of your patch, we have to handle duplicate file names, see #358439: Images are only in the first message.

lirantal’s picture

The patch handles the case of using duplicate file names by working on the full file path instead of just the basename.
Can you please explain what is the issue with checking file content?

sgabe’s picture

If you take a better look at the code you will notice that sometimes $file will be the content:

  }
  // We have the actual content.
  elseif ($content) {
    $file = $content;
  }

  if (isset($file) && (@is_file($file) || $content)) {
lirantal’s picture

Just to add, I've personally tested duplicate file names and it works just fine.
I've used 2 different images with the same file name (put in different folders locally), then created a new node, used the imagefield to upload and insert both of them into the node's body.

End result is that I get the 2 distinct images in the email notification as well as they both appear just fine in the node view.

sgabe’s picture

We have posted at the same time, see #6.

lirantal’s picture

Right, but looking at the $new_file array it seems that anyway because if $content is passed, then $file = $content (earlier) then $new_file['file'] = $content which I think is somewhat bad, isn't it?

Anyway, I think you are referring to the problem where if $content is passed then it's being set in it's entirety into the $filesnames array, right?

sgabe’s picture

Right, but looking at the $new_file array it seems that anyway because if $content is passed, then $file = $content (earlier) then $new_file['file'] = $content which I think is somewhat bad, isn't it?

No, mimemail_multipart_body takes care of the rest.

      if (isset($part['file'])) {
        $file = (is_file($part['file'])) ? file_get_contents($part['file']) : $part['file'];
        $part_body = chunk_split(base64_encode($file), 76, variable_get('mimemail_crlf', "\n"));
      }
Anyway, I think you are referring to the problem where if $content is passed then it's being set in it's entirety into the $filesnames array, right?

Yes!

lirantal’s picture

Alright then, how about instead of keeping a string'ed array value of the file name we simply keep a hash of it (md5 or crc32 should do)?

lirantal’s picture

Actually, instead of another hash we can use $content_id. what do you think?

lirantal’s picture

@sgabe ping?

lirantal’s picture

Status: Needs work » Needs review
FileSize
911 bytes

Updated patch with use of $content_id for files array.
Can you please review and comment?

sgabe’s picture

Status: Needs review » Needs work

Just a minor thing, since we do not use the actual file names, we should rename $filenames to $ids which would be more accurate. I would also change $content_id to just $id.

sgabe’s picture

Version: 6.x-1.x-dev » 7.x-1.x-dev
Status: Needs work » Needs review
FileSize
1.67 KB
1.6 KB

Rerolled patches for both branches. Let me know if this will work for you.

sgabe’s picture

Title: Mimemail fails to handle different files with the same file name » Handle different files with the same file name
Status: Needs review » Fixed

Committed to both branches!

Status: Fixed » Closed (fixed)

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