Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
it would be nice if a module implementing hook_mail_alter could actually cancel sending a mail (now one has to change the To: to a "dummy" mail address)
Comment | File | Size | Author |
---|---|---|---|
#113 | hook_mail_send_alter-800434-113.patch | 631 bytes | artkon |
#112 | hook_mail_alter-cancel-800434-112.patch | 3.42 KB | dalin |
#109 | hook_mail_alter-cancel-800434-109.patch | 3.49 KB | Albert Volkman |
#104 | hook_mail_alter_cancel-800434-d6-104.patch | 3.49 KB | Albert Volkman |
#97 | hook_mail_alter_cancel-800434-d6-97.patch | 3.49 KB | Albert Volkman |
Comments
Comment #1
goldhat CreditAttribution: goldhat commentedI agree with this! Faced this issue today when aiming to prevent Register Welcome emails being sent and found there is no easy way, had to use this send to nowhere option in hook_mail_alter which is not at all elegant. Definitely I think an "alter" option for email should be to not send that email at all. If there is a reason why it cannot be done this way (too much power for an alter function) then how about a new function such as hook_mail_nosend() ?
Comment #2
bfroehle CreditAttribution: bfroehle commentedComment #4
bart.hanssens CreditAttribution: bart.hanssens commentedpatch against 8.x, just adds a "send" parameter in the message array, so it can be changed by drupal_alter
Comment #5
bart.hanssens CreditAttribution: bart.hanssens commentedgrmbl, Mondays... patched wrong file, giving it another try
Comment #6
bart.hanssens CreditAttribution: bart.hanssens commentedComment #7
sunThe idea and principle is good, but the key 'send' sounds a bit poorly named.
Comment #8
bart.hanssens CreditAttribution: bart.hanssens commentedmm, suggestions ? "submit" ? "process" ? I don't mind if it gets another name, but I can't think of a better name at the moment :-)
Comment #9
larowlanhow about we rephrase the key as 'cancel' and reverse the logic?
Comment #10
pillarsdotnet CreditAttribution: pillarsdotnet commentedRe-rolled according to suggestions from @sun and @larowlan.
Comment #11
pillarsdotnet CreditAttribution: pillarsdotnet commentedComment #12
larowlanPatch looks good but I think we need tests as well as updates to the documentation. There is an extensive example in the documentation for drupal_mail and also for the hook_mail_alter function in system.api.php.
We need to update the documentation so those writing hook_mail_alter implementations know that they can set the cancel key.
Not sure about the backport to D6/D7 - is it too late for that?
Tagging appropriately for the tests/documentation.
Comment #13
pillarsdotnet CreditAttribution: pillarsdotnet commentedAdded tests and documentation as requested.
Comment #14
larowlanNot sure what this does?
Powered by Dreditor.
Comment #15
larowlanComment #16
pillarsdotnet CreditAttribution: pillarsdotnet commentedOops. Corrected the example code and added comments.
Comment #17
larowlanLooks good to me.
Comment #18
pillarsdotnet CreditAttribution: pillarsdotnet commentedd7 and d6 backports.
The d6 patch is necessarily in two parts, one against code and one against documentation.
Comment #19
sunThanks for adding docs and tests. And - ouch - given that, only now it's apparent that the function argument to drupal_mail() is already named "send"... although it still sounds a bit fuzzy (within the context of a mail sending function), it's better to keep the argument and property identically named.
Additionally, as a side-note, a property with negated meaning and logic ("cancel") should always ring alarm bells - never do that; it almost always leads to implementation and/or understanding problems in the long run. In some other places, Drupal core still uses properties with negated meaning (e.g., "hidden") -- almost no one understands their meaning, and even if you understand them, it's extremely weird to code against these values.
Furthermore:
1) If a module knows upfront that it's not going to send a mail, then I don't think it should attempt to send it in the first place. Therefore, the added example for hook_mail() doesn't make sense to me. In turn, this means we should clarify this in drupal_mail() docs... whereas I believe the current $send function argument has a different point in that the calling module wants to prepare a mail for sending, but take over the sending on its own, or do something in between formatting and sending, or whatever... In turn, it might be wrong to presume that the $send function argument and the 'send' message property are functionality-wise and logically the same. A module that tries to do the aforementioned thing will set $send to FALSE upfront, but will have to check whether $message['send'] has been set to FALSE after invoking drupal_mail(), so it doesn't send a mail that's not supposed to be sent.
2) The example snippet in hook_mail_alter() looks slightly more understandable to me than the one in the hook_mail() phpDoc (optout vs. optin, etc)
No double spaces between sentences in phpDoc.
Replace the '=' with spaces?
Any reason for not using $this instead of self:: here?
All mails in tests need to be addressed to @example.com. drupal.org is a real domain name and has a mail server.
Exporting a variable into an assertion message, which is supposed to be NULL doesn't make much sense to me.
Powered by Dreditor.
Comment #20
larowlanThanks Sun for such a comprehensive review. It is this level of attention to detail that makes Drupal what it is today.
Comment #21
pillarsdotnet CreditAttribution: pillarsdotnet commentedI thought so too, but decided (just this once!) to simply make the requested changes rather than argue with a senior developer.
Corrected.
Like many examples, it is a bit contrived. Realistically, the module implementing
hook_mail_alter()
would be different from the one sending. I have updated the example insystem.api.php
to make this clear. Unfortunately, this also highlights a problem. If the sending module only usesdrupal_mail()
for formatting, not for sending, then the$message['to']
value may not be reliable. I would welcome suggestions for more appropriate examples.Corrected.
Corrected.
Yes. The variable is static. Using
$this
instead ofself::
should trigger an error, just as usingself::
to refer to a non-static method would trigger an error.Corrected.
Corrected. It was helpful during troubleshooting, i.e., when I was trying to figure out why the variable was not
NULL
.Updated 8.x patch passes tests.
Comment #22
star-szrSubscribing, don't mind me…
Comment #23
pillarsdotnet CreditAttribution: pillarsdotnet commented#21: drupal_mail-800434-21.patch queued for re-testing.
Comment #25
pillarsdotnet CreditAttribution: pillarsdotnet commentedRe-rolled for current 8.x checkout.
Comment #27
pillarsdotnet CreditAttribution: pillarsdotnet commentedFixed and re-rolled.
Comment #28
sun1) Trailing dot should be a period here.
2) Let's remove the function declaration and also the $language line - both unrelated to the example. In turn, the indentation can be decreased.
The $send argument cannot be assigned to 'send' by default. As visible in the example code snippet, the code would pass FALSE, so 'send' would always be FALSE; in turn, the calling code intending to send the mail on its own would never send the mail.
This means the inner logic of drupal_mail() concerning $send and 'send' needs to take both values separately into account. Both $send and 'send' default to TRUE, but drupal_mail() only sends the mail, if both are still TRUE. The example for manual sending stays the same; i.e., checking for 'send'.
Lastly, in the example code itself:
- The code should pass a proper e-mail $to address.
- The comment should read "Only send the mail if sending was not canceled."
I think we should assign NULL instead of FALSE here. Not a huge improvement, but in the sending code path, FALSE denotes an mail sending engine error... so FALSE would and should also technically indicate an error here.
Overall, drupal_mail() implements poor error handling though, something we should look into for D8.
Missing t() in assertion message, which should also be "Message was cancelled."
I don't think the logic + comment is a proper and valid example. hook_mail_alter() implementations will have to unconditionally override 'send', regardless of whether 'send' is already FALSE or not.
Powered by Dreditor.
Comment #29
pillarsdotnet CreditAttribution: pillarsdotnet commentedI'm sorry, but I don't understand the distinction between a "trailing dot" and a "period".
Done.
Had to build a logic table to understand what you were saying, but on reflection I agree.
Done.
You're right;
'<>'
is valid as a$from
address, but not as a$to
address. On the other hand, the point of this example is that a message is being formatted once, then sent to multiple recipients.Replaced by
'user@example.com'
, but a real-world example is more likely to useNULL
or an empty string here.Agreed; that sounds better. Fixed.
Agreed; fixed.
I've stopped using
t()
in assertion messages since reading #500866: [META] remove t() from assert messageNo argument; changed as requested.
Yes, if we initialize
$message['send'] = TRUE
, then the example logic becomes faulty. Fixed.Comment #30
sunSorry I meant: colon, not period.
Please revert to a single line.
Additionally, $params is supposed to be a string-keyed array containing contextual information, so it should be array('accounts' => $accounts) here.
That said, however, it looks like the example is trying to formulate a concept of mass-mailing via drupal_mail(), which is 1) not the topic of this issue, and 2) not really supported by drupal_mail() currently. That is, because implementors still most likely want to have personalized mails in a mass-mail construct.
But again, that's a completely different and separate issue. To get this patch done, we need to focus and limit changes on the currently supported API; i.e., support both $send and 'send', but not a single word related to mass-mailing in the docs.
When looking at this without contextual background information from this issue, people will ask themselves "WTF?" -- the correlation and intended meaning of $send and 'send' could use one or two inline comments, clarifying that one was set by the caller, the other one potentially overridden by others.
Thanks!
Powered by Dreditor.
Comment #31
pillarsdotnet CreditAttribution: pillarsdotnet commentedOkay; done.
Doesn't fit on a single line. Changed to two, but I don't like it, because the opening and closing parentheses don't match.
EDIT: Revised example in #34 should meet both our standards.
Well, then the documentation for the
$params
argument should say so. Changed in both places.Can you suggest another example in which it would make sense to call
drupal_mail()
with the$send
argument set toFALSE
?Comments added.
Comment #32
pillarsdotnet CreditAttribution: pillarsdotnet commentedComment #33
pillarsdotnet CreditAttribution: pillarsdotnet commentedNever mind; I thought of one. You might want to format a message, then add it to a spool for batch-sending later.
Revised example code to fit this new scenario; no other changes.
Comment #34
pillarsdotnet CreditAttribution: pillarsdotnet commentedSlightly better example code.
Comment #35
sunThanks, I think this is good to go now.
Comment #36
pillarsdotnet CreditAttribution: pillarsdotnet commentedClosed duplicate: #854304-3: Allow hook_mail_alter to affect sending of mails
Comment #37
johnny-j-hernandez CreditAttribution: johnny-j-hernandez commentedWhile this patch continues development is there a way to implement this functionality now in D6.x? I need to disable the default mail sent by the invite.module so that I can send a custom message through my Campaign Intelligence API call.
-johnny;j
Comment #38
pillarsdotnet CreditAttribution: pillarsdotnet commented@#37: Sure. Just backport the patch like I did in #15.
Comment #39
pillarsdotnet CreditAttribution: pillarsdotnet commented#34: drupal_mail-allow_mail_alter_to_cancel-800434-34.patch queued for re-testing.
Comment #41
pillarsdotnet CreditAttribution: pillarsdotnet commented#34: drupal_mail-allow_mail_alter_to_cancel-800434-34.patch queued for re-testing.
Comment #42
larowlanUnless I've missed something, I think this was set to RTBC at #35 - so if the bot's happy too...
Comment #43
pillarsdotnet CreditAttribution: pillarsdotnet commented#34: drupal_mail-allow_mail_alter_to_cancel-800434-34.patch queued for re-testing.
Comment #44
eme CreditAttribution: eme commented#4: allownomail-800434-2.diff queued for re-testing.
Comment #45
xjm#34: drupal_mail-allow_mail_alter_to_cancel-800434-34.patch queued for re-testing.
Comment #47
oadaeh CreditAttribution: oadaeh commentedThe patch in comment #34 fails because the 8th line of the 5th chunk (the watchdog line) uses the wrong severity. It should be WATCHDOG_ERROR.
Comment #48
pillarsdotnet CreditAttribution: pillarsdotnet commentedRe-rolled.
Comment #49
plach#48: hook_mail_alter-cancel-800434-48.patch queued for re-testing.
Comment #50
plachLooks like this addresses sun's concerns. So apart from the minor thing below I'd say this is RTBC, provided that the bot is still happy.
Attaching a D6 backport for people needing it, I ain't sure this API addition can actually be backported.
Missing trailing dot.
Comment #51
pillarsdotnet CreditAttribution: pillarsdotnet commentedRe-rolled, and change notice written.
Comment #52
plachWonderful :)
Comment #53
sunhook_mail() or actually MODULE_mail()
drupal_mail()
--
Otherwise, this looks fine to me. Not sure whether this is backportable though ('cos of the NULL 'result' value), but let's make sure to try.
Comment #54
pillarsdotnet CreditAttribution: pillarsdotnet commented@sun:
The particular
hook_mail()
function implemented by the$module
module. To quote:Comment #55
pillarsdotnet CreditAttribution: pillarsdotnet commentedRe-rolled.
Comment #56
pillarsdotnet CreditAttribution: pillarsdotnet commentedSorry; missed one.
Comment #57
sunRight, no need to quote.
{$module}_mail()
is an unknown documentation pattern to me.hook_mail()
is API-documentation-wise correct, andMODULE_mail()
would technically be even more correct, since hook_mail() is actually a callback, not a hook.Since it's documented as
hook_mail()
currently, I guess it's fine to go with that for now.That said, those contextual parameters are also passed to hook_mail_alter(), if you want to be nitty gritty nitpicky.
Comment #58
pillarsdotnet CreditAttribution: pillarsdotnet commented@sun:
Whatever. My point is that
$params
is not passed to everyhook_mail()
implementation, and it is certainly not passed to a function calledMODULE_mail()
. It is passed to the particular function whose name is exactly$module . '_mail'
, where$module
is the first parameter to thedrupal_mail()
function.Only if they are copied into the
$message
array by the$module . '_mail'
function. This is typical behavior, but not required byhook_mail()
documentation.Comment #59
pillarsdotnet CreditAttribution: pillarsdotnet commentedAn exhaustive search of Drupal 8.x source code reveals no instance where MODULE was used as a placeholder for a named parameter to the function being documented.
Searching for examples of your other cited standard, where
hook_FOO()
refers to a function whosehook
name comes from a passed parameter, yields one concrete example:_theme_process_registry()
...
The doc header does not conform to current coding standards, but I'll follow its example anyway, as I can't find another.
Re-rolled, with interdiff from #51.
Comment #60
pillarsdotnet CreditAttribution: pillarsdotnet commentedSlightly clearer wording on the
$send
parameter.I do. That, combined with stubborn determination, is what we have in common. ;-)
Comment #61
plachI hope this is ok now.
Comment #62
chx CreditAttribution: chx commentedI see a lot of revisions spent on existing doxygen wordsmithing which, while awesome is another issue. I would love to see them separated but that's a minor problem.
The important issue here is, where did we accept to have a $send and a send key? Where did we get over the horrible confusion this causes? I did try to skim the whole issue but this simply stopped being a problem apparently?
Comment #63
plachWell, personally the reason why it was introduced looked sensible to me: this way one can decide to cancel a mail that was intended to be sent, but not send a mail that was intended to be just previewed/built. OTOH this might be too restricitve, no strong preference on this.
Comment #64
chx CreditAttribution: chx commentedOf course the goal of the patch is great! The functionality is good. But the key choice is poor.
Comment #65
pillarsdotnet CreditAttribution: pillarsdotnet commentedSo if you don't like the choice of
$message['send']
as a flag thathook_mail_alter()
implementations can change to abort sending, what choice would you approve?Saying "I don't like that" without suggesting an alternative is ... less than helpful.
Skimming the comments, I see:
Additionally, as a side-note, a property with negated meaning and logic ("cancel") should always ring alarm bells - never do that; it almost always leads to implementation and/or understanding problems in the long run
Question answered; back to RTBC.
Comment #66
catchPlease don't RTBC your own patch.
Comment #67
plach#60: hook_mail_alter-cancel-800434-60.patch queued for re-testing.
Comment #69
plachWe have a change record for a non-committed patch here. I don't think this situation is sane. I hope that @catch can shed some light on this and possibily give his feedback about the issue raised by @chx in #62. IMHO the key name is not so confusing, if I'm not missing something we have other examples of this pattern in core, e.g. http://api.drupal.org/api/drupal/modules--field--field.attach.inc/functi....
Comment #70
plachComment #71
plachRerolled #60 after the /core migration. Since we are getting no feedback here I'll RTBC this again, provided that the tests pass.
Comment #72
plachComment #73
plachSee #69.
Comment #74
chx CreditAttribution: chx commentedI had my say in #62 catch will decide.
Comment #75
plach@chx:
I understand your point, although a suggestion would help, but IMO #69 should be took into consideration.
Edit: I mean, this might be RTBC after all. As you say, let committers decide.
Comment #76
catchAdding anything to drupal_mail() makes me wince since hook_mail() is one of the worst hooks in all of core, so I opened #1346036: Add an alternative to hook_mail() and deprecate it to see if we can kill it.
Shouldn't it be cancelled? Or is this US vs. UK spelling?
None of this is to do with the patch, and it should just go in a separate docs clean-up issue I think.
Same with things like this.
Should be 'ID', not 'id'.
If we're adding a feature, we don't need to talk about possible approaches to implementing that feature from before it was committed that are now being replaced.
11 days to next Drupal core point release.
Comment #77
plach@catch:
Since IMO this is a good candidate for backport, can we move it to Drupal 7 and figure out how to propery address this for D8 in the other issue? This is a badly needed feature, and one that can be implemented only by patching core at the moment.
Comment #78
catch@plach I'm fine with committing the $send stuff here to Drupal 8 if we can just trim the patch a bit to remove the comment cleanup. webchick would likely want that removed if it is backported anyway - the mass comment cleanup issues are not being backported.
The $send key does not really make things any worse it just doesn't make it better either, which just reminded me how much I don't like it, but I don't think this patch should suffer for that - seems like a useful API addition.
Comment #79
plachImplemented suggestions from #76.
Yes, I think "canceled" is legal. I've done a quick core search and got 47 occurrences of "canceled" vs 17 of "cancelled", moreover http://en.wikipedia.org/wiki/Canceled_Apollo_missions :) However I at least ensured that the patch uses the more common form consistently.
Since I only removed comment lines I think it should be safe to mark this back to RTBC. Let's wait for the bot however.
Comment #80
plachWrong comment wrapping.
12 days to next Drupal core point release.
Comment #81
oadaeh CreditAttribution: oadaeh commented@plach: please review #66.
Comment #82
plachThe patch addresses the concerns of a committer. In this case it's fine to RTBC one's own patch, since otherwise the committer might not notice it for a long time. Also note that I did not write any line of it, just rerolled it and removed some hunks as per catch's request.
Let's skip the status ping-pong and get this in, catch already said he's fine with it.
Comment #83
sunCan we append the inner comment to the outer, please? At this point in the function it's really not trivial to follow the flow of the logic, and I got heavily confused why the comment states that the original caller requested sending while the condition checks for FALSE, while it defaults to TRUE.
Appending the inner comment to the outer clarifies the flow.
Likewise and to stay consistent, move this inner comment also out, right above the else.
5 days to next Drupal core point release.
Comment #84
plachet voila
Comment #85
plach@sun:
Anything holding this back left?
Comment #86
sunDon't think so. Thanks!
Comment #87
catchLooks good to me, and there is even a patch in progress at #1346036: Add an alternative to hook_mail() and deprecate it. Committed/pushed to 8.x, moving to 7.x for webchick to consider.
Comment #88
plachHere it is the D7 version.
Just applied the patch with -p2 and rerolled, hence setting back to RTBC.
Comment #89
webchickThis functionality actually looks really cool, and would allow for a centralized "Opt-out" contrib module to cancel *all* email coming from Drupal, which seems super handy. Thanks for implementing it in a backwards-compatible way, and for the extra added tests.
We are currently under issue thresholds, and this is the last issue in the D7 RTBC queue, so I'd like to sneak this in. :) However, it no longer applies to D7. :( Could I get a quick re-roll?
Comment #90
plachRerolled. It was just a stupid documentation typo fix committed after #88 was rolled, thus back to RTBC.
Comment #91
plach#90: hook_mail_alter-cancel-800434-90.patch queued for re-testing.
Comment #92
xjmSo this is supposed to have a silly s. Since this already went into D8 and got stuck on rerolls for D7, I'm not going to screw with the patch here. Besides,
simpletest.module
still hasn't been claimed for #1310084: [meta] API documentation cleanup sprint, so I guess we can count on it getting fixed there rather than opening a one-letter followup patch. :PComment #93
webchickCommitted and pushed to 7.x. Thanks!
(I left the S the way it was to keep the two in sync)
Comment #94
webchickOops. I got this patch and another one confused! Sorry. I had to roll back because we're not under thresholds yet. ;(
Comment #95
David_Rothstein CreditAttribution: David_Rothstein commentedLooks to me like this wasn't actually rolled back? Setting to "fixed" for the time being.
Comment #96
plachThis can easily be backported to D6 too.
Comment #97
Albert Volkman CreditAttribution: Albert Volkman commentedD6 backport and documentation backport.
Comment #99
plach@Albert Volkman:
Thanks!
Would you please roll a single patch containing all the changes and name it something like "hook_mail_alter-cancel-800434-100.D6.patch" this way the bot won't try to automatically test it (see also the attachment notes below).
Comment #100
Albert Volkman CreditAttribution: Albert Volkman commentedThe first patch is for core, the second is for the documentation project.
Comment #101
xjmIndeed, but ending the filename in
-d6.patch
is helpful to keep testbot from trying to test it. :)Comment #102
Albert Volkman CreditAttribution: Albert Volkman commentedAh, very true. Do I need to repost them then? The first as it is for testing, and the second with -d6?
Comment #103
xjmI'd suggest maybe attaching only the core patch here, and opening a separate issue against the API project with the docs patch.
Comment #104
Albert Volkman CreditAttribution: Albert Volkman commentedYou got it.
Comment #106
Albert Volkman CreditAttribution: Albert Volkman commentedhttp://drupal.org/node/1443112 for documentation patch.
Comment #107
Albert Volkman CreditAttribution: Albert Volkman commented#104: hook_mail_alter_cancel-800434-d6-104.patch queued for re-testing.
Comment #109
Albert Volkman CreditAttribution: Albert Volkman commented/me puts on dunce hat.
Comment #110
plachLooks good, thanks.
Comment #111
Albert Volkman CreditAttribution: Albert Volkman commented#109: hook_mail_alter-cancel-800434-109.patch queued for re-testing.
Comment #112
dalinNeeded a very minor re-roll to apply to HEAD.
P.S. I am completely confused about how to attach a patch to an issue after the D7 upgrade. Apologies if I break things.
Comment #113
artkon CreditAttribution: artkon commented