The D7 version of MIME Mail doesn't yet work with attachments. While this is probably a known problem, I figured I'd open an issue to keep track of progress in correcting this behavior.
The obvious source of this problem is that the mimemail_html_body() function loops through the $attachments parameter and checks each attachment for $a->filename. In Drupal 7, files no longer have a filename, instead they have $file->uri. Common URIs would be public://myfile.png, private://myfile.png, or s3://myfile.png.
Reading through the source of MIME Mail it looks like there are also assumptions that if a file URL contains "://" it is an absolute HTTP path. This assumption is now completely inaccurate since all file paths are specified as URIs, which all contain "://".
| Comment | File | Size | Author |
|---|---|---|---|
| #23 | mimemail_1066438_08.patch | 1.73 KB | sgabe |
| #18 | mimemail_1066438_06.patch | 797 bytes | ibes |
| #12 | mimemail_1066438_05.patch | 2.06 KB | sgabe |
| #10 | mimemail_1066438_04.patch | 1.88 KB | oadaeh |
| #6 | mimemail_attachment_errors-1066438-6.patch | 2.18 KB | guillaumev |
Comments
Comment #1
quicksketchThis patch seems to do the trick. It makes the obvious change of changing $a->filepath to $a->uri, and tidies up the URL logic a bit to work with local or remote files.
Comment #2
sgabe commentedWe operate on the local file system to embed images, so we need to use drupal_realpath() here.
Comment #3
quicksketchAh, in which case we should probably keep using drupal_realpath() but use file_create_url() if it fails. drupal_realpath() will return FALSE in the event that the file is not stored locally, since entries in the "file" table are no longer guaranteed to be either local or writable (say if you're referencing a file on flickr with the flickr:// stream wrapper). file_create_url() will work for all stream wrappers.
Comment #4
sgabe commentedI'm attaching a revised patch.
Comment #5
guillaumev commentedHi,
Maybe I'm missing something, but I don't understand this patch, which actually breaks on my system. When I look at the code in mimemail.rules.inc, the attachments are sent as:
So, I don't understand why you would replace $a->filepath by $a->uri, which actually does not exist in $a... But again, I might be missing something...
Comment #6
guillaumev commentedHere is the patch I would propose, which also fixes a few notification errors...
Comment #7
quicksketchIf you use file_load() in Drupal 7 or look in the managed_file database table, you'll see that "filepath" no longer exists. This is because Drupal now uses stream wrappers like public://example_directory/example.png instead of a path like sites/default/files/example_directory/example.png. This makes it so that you can move your file directory around wherever you like, makes it so Drupal core can simultaneously support private and public files (as well as other storage mechanisms), and a lot of other benefits. Unfortunately it's also confusing to users who have never used stream wrappers before (they're a feature of PHP, not specifically Drupal).
I'm guessing the Rules integration hasn't been updated yet either, so this problem needs to be corrected in more places than just the ones the patch current fixes.
Comment #8
pmcgilvray commented#6 fixed this issue for me. Thanks guillaumev!
Comment #9
Isostar commentedCan someone post an example of the code for sending an attachment with mailsystem/mimemail.
There are also other people struggling with the same issue: http://drupal.org/node/1214098
I tried following code, with and without patch. The mail is sent, but without attach. The file object is loaded correctly.
Thanks in advance!
Comment #10
oadaeh commentedIn having to figure this out (again! -- because there's no documentation (again!)) I see the points both @quicksketch and @guillaumev are making.
In using new Drupal 7 functions that change the way things are done, you need to update your variables and change the way you write your code.
In using old/existing PHP functionality, you don't /need/ to change anything, but can -- if you know you how/what to change. Really, we should all be moving toward the way things are done w/D7, but it's unnecessary to break existing code, just because we can.
@guillaumev's patch takes into account both methods.
In changing the way Mime Mail operates w/o documenting it, no one knows what is going on, and we're all just stabbing in the dark guessing until we figure it out or give up, which I think is part of @guillaumev's frustration, and certainly, my frustration, especially after having gone through this once before.
I've attached a patch that updates @guillaumev's patch with the current state of Mime Mail. I also changed the variable assignment order so that they match the function parameter order. I think everything else is as it is in the three previous patch submissions.
Comment #11
jschrab commented(Nevermind - comment posted in error)
Comment #12
sgabe commentedI have committed the following patch for a start. Let's continue in separate issues.
Comment #13
ibes commentedDon't work for me,
I try to use mimemail via mail_alter like:
it works just fine to alter other params like the subject.
get the PHP notice:
Notice: Undefined property: stdClass::$uri in mimemail_html_body() (Zeile 359 von /var/www/vhosts/xxx/httpdocs/sites/all/modules/mimemail/mimemail.inc).
I want to send an attachment built from a files source code (i will generate a PDF and send it per mail).
==
in file mimemail.inc on line 356, function mimemail_html_body, there is:
$content = isset($a->filecontent) ? $a->content : NULL;guess it must be:
$content = isset($a->filecontent) ? $a->filecontent : NULL;==
in file mimemail.inc on line 144, function _mimemail_file, there is:
if (isset($file) && @is_file($file)) {I compared it with the version for drupal 6:
if (isset($file) && (@is_file($file) || $content)) {I guess the Drupal7 version kills the support for "filecontent" and will lead to the notice (see above)
Sorry for my bad style - first bug report...
Comment #14
sgabe commentedLets mark this as D7 release blocker.
Comment #15
sgabe commentedYes, the port of #932962: Allow attachments to be added by contents was wrong for D7. The fix is committed. Thanks for pointing this out!
Comment #16
sgabe commented#1290836: Better documentation for attachment needed is marked as a duplicate of this, we need to update the documentation according to the changes.
Comment #17
ibes commentedGet a file attachment out of a string seems to work, but I get a PHP notice:
this is line 359:
yeah - as there is no "uri" (because it makes no sense to set uri AND content) - so that's the reason for the notice.
there has to be something, to prove whether there is a uri
what about do it this way: (mimemail.inc - line 353)
Also if I try to attach an existing file the module wants to have "uri" and not the older "filepath" argument.
Why was the name changed from "filepath" to "uri" - guess that makes more trouble by upgrade from 6.x to 7.x and I don't see a great improvement in this.
My code:
two arrays, because there may be more attachments - second array to get the values of the attachment.
To send a existing file you must use 'uri' with an relative(!) path like the readme.txt says - that works for me:
Code, that works for me:
Comment #18
ibes commenteda patch for the issues in #17
Comment #19
ibes commentedComment #20
sgabe commentedWe need to update the documentation according to the modifications. Furthermore I think maybe we should preserve filepath in the array and just add support for uri.
Comment #21
ibes commentedI am not sure if I got you right:
So "filepath" should be best practise for the path to the file and "uri" should also be supported?
Like:
$url = isset($a->filepath) ? $a->filepath : (isset($a->uri) : $a->uri : NULL);Where are pieces of documentation:
- in the readme file
- inline documentation
- elsewhere?
I guess we should check if the existing naming still fits and I guess it would make things much easier to have more info about the attachment array. For example, that there are two array: an array of attachment array and the array of each attachment. This information is worth 1 - 2 days :)
What modules should work together with mimemail?
- Simplenews
- Webform
- Rules
Comment #22
ibes commentedPatch #18 works without errors and notices in
- webform
- hook_mail_alter
- drupal_mail
I did not found a rules integration (see other issue) and no way to test it with an attachment in simplenews.
Works without adding a mimetype, filename.
Works with uri (not the old filepath), filecontent
Path can be
- absolute server path
- relative to drupal root
URLs to external pages (http://) seems to do not work - as the readme also says that I guess this is like designed
Readme file is quite good and still up to date, but would specify this part:
won't solve this now, but this could be a nice start:
this is the existing inline documetation (file: mimemail.module - function mimemail_prepare_message):
"filepath" have to be updated, if "uri" is the new wording for it - can include this in my patch.
I don't know what is the new standard. I guess in some places in the mimemail.module it is already "uri" and I haven't seen "filepath" beside the documentation
Comment #23
sgabe commentedYeah, I think that's enough. In this case the documentation is good as it is. The rest of the issues here were covered by earlier commits.
Comment #24
ibes commentedtested with a similar testset as in #18 + rules
works nice. I think we have it!
Comment #25
sgabe commented@ibes: Did you try to send attachment via Rules with tokens? I believe if you have a file field set for the entity, there is a token for the file path which should work in the rule, but I didn't test it yet.
Comment #26
ibes commentedno, haven't tested that.
Only by defining attachments in the Rules UI.
I wondered if there is a way to let users (optionally) also specify the filename of the attachment.
Should not be that much extra code, but looks better - but this is another issue. Should I open another or extend an existing issue?
I will try to do that token to attachment thing!
Comment #27
sgabe commentedI mean defining attachment in the Rules UI but with tokens. For example this
[node:field_file-filefield-filemime]:[node:field_file-filefield-filepath]works in D6 to set an attachment when a node (which has a file field) is viewed but I didn't try this in D7 yet.Comment #28
ibes commentedtest to get an attachment by using tokens of a file field (cck)
Wasn't able to test it because I wasn't able to get any content by use the field token.
I don't know why the token gives me no content - but with a token output I planned to test it like this:
Here is how I wanted to do my test:
- activate module token
- create an node type with file
- set an file token in "manage displays" -> "tokens"
- set an rule to send html mail on creating or updating that node type
- put in the file token in attachments
I guess something like this should be put in the attachment input field:
[node:field-datei:file:mime]:[node:field-datei:file:url]Comment #29
ibes commentedgot attachment running with tokens if:
- token display is set to url
- mimetype is defined manually and only the filepath is set by token
attachment is sent - but filename is "attachment.dat" - that is not quite nice
Wasn't able to get the mimetype via token.
Tried [node:field-datei:file:mime]:[node:field-datei] (the token display is set on url)
as rules or mimemail didn't know the first token it makes "[node" to mimetype and "field-datei:file:mime] to filepath (as there is a ":" after "node")
Comment #30
sgabe commentedAccording to the File interface this should work as expected, the file object has a filename field.
Comment #31
ibes commentedthe mimemail rules action has no input option for a file name - only filepath and mimetype...
Comment #32
butler360 commentedSubscribing. Trying to send attachment as a Rule fired after Webform submission. Works perfectly so far, except I, too, get attachment.dat instead of myfile.pdf.
Comment #33
ibes commented@butler360 in #32:
You can't specific a file name via rules, so mimemail use its default "attachment.dat".
I don't like this either - i will open a new issue.
This is nothing that will crash the hole thing, but should be done.
Comment #34
ibes commentedWhat is left to review in this issue?
- the last patch works
- It is possible to send attachments via rules. There are about two issues with mimemail and rules but it is possible to send attachments with it.
- Also Webform is tested
- mail_alter is tested.
Anything else to test or other issues on this?
Comment #35
butler360 commentedI don't understand the point, then. Are you saying it's intentional that every attachment is sent as attachment.dat?
Comment #36
sgabe commented@butler360: In case of attachments sent via Rules, that's a bug, see #1305830: Set default filename and mimetype to enforce auto detection.
Comment #37
ibes commented@butler360: what do you think about this change - see: #1305824: Leave MIME type and use only path to specify an attachment
@sgabe: What do you think - are we ready to close this issue? As there are some issues on the rules integration mimemail don't seem to be ready for RC, but by fixing this issue I think it will work for most projects that don't use mimemail via rules + attachments.
So would be good to have this patch in the dev version.
Comment #38
sgabe commentedCommitted. Thanks everyone.