Read code!
It might sound obvious, but reading code is extremely helpful. And sometimes it is necessary! But first things first. Here’s a little story …
How it started
I recently set up Content Moderation Notifications for Drupal. The purpose of this module is to send mail notifications when a workflow status of a page changes. This is very helpful when you want to set up some kind of information or approval process. Relevant for this blog post are two options. You can send a mail to the author of the page as well as you can add other mail addresses (so called “Adhoc Emails”) manually. While the last ones are static values, the author will be found dynamically by Drupal. That’s neat. Both settings are optional.
I had two different workflows for two different page types – news and pages.
News
The workflow for news is pretty simple. Authors start with creating an unpublished draft and when everything is ready they release it by themselves by changing the status to published. This change triggers a mail to a shared mailbox to inform other people involved. Since authors handle all status changes on their own, it is not necessary to send them an email, too.
| Status | Email Author? | Adhoc Emails |
|---|---|---|
| Draft | No | – |
| Published | No | shared@mailbox.local |
Page
The workflow for global pages is slightly different. In addition to draft and published, there’s an additional review step in between. The idea is to let a second person check the content and release the page afterwards. Therefore an email should be sent to the author when the page has been published, but not again to the shared mailbox.
| Status | Email Author? | Adhoc Emails |
|---|---|---|
| Draft | No | – |
| Review | No | shared@mailbox.local |
| Published | Yes | – |
While the adhoc email of the news workflow worked like expected, the one for the page workflow didn’t and I couldn’t get my head around it. I was pretty sure the only difference was the status name!? But I was wrong. Of course.
Debugging
First, I double-checked all the configurations (there are more than shown in the tables above). No differences. I started to change things here and there in a more or less structured way. In the end, I added the adhoc email address to the published status for testing purpose and then it worked. Now there were no differences anymore.
But I still had the problem that the mails for the review status didn’t work. I added an additional review status to the first (news) workflow, too. And this mail didn't work either. Alright, but why can adhoc emails only be sent for the last status? That’s a bug!
Finding the bug that wasn’t one
I had a look at the known issues for this module and found a few that were about emails. But these issues didn’t fit. So I had a look at the code. And I should have done this much earlier!
$anonymous_access = $entity->access('view', User::getAnonymousUser());
foreach ($adhoc_emails as $email) {
// Attempt to find a user matching this email.
$email_accounts = $this->entityTypeManager->getStorage('user')->loadByProperties(
['status' => 1, 'mail' => $email]
);
$email_account = reset($email_accounts);
if ($email_account && $entity->access('view', $email_account)) {
$data['to'][] = $email;
}
elseif ($anonymous_access) {
// Send adhoc emails if anonymous users can view the entity.
$data['to'][] = $email;
}
}
The module tries to check if the owner of the adhoc email has access to the page for the current status. If there’s no Drupal user account associated with the mail address, it assumes that it’s an anonymous user. That was the case for the shared mail account. There is even an explicit comment in the code:
// Send adhoc emails if anonymous users can view the entity.
Since the last status in both workflows included the publication of the content, the pages were accessible for anonymous. But that was not the case for all previous steps. This is why the module did not send the email notifications.
It’s not a bug, it’s a feature! 🎉
From my point of view it should be the user's choice if an email is sent or not. But regardless of whether I think that's a useful feature, it should definitely be documented for editors somewhere (and not only in the code). Maybe adding a hint to the input field of the configuration? “Make sure the owner of this email address has access to the content otherwise no email will be sent!”
Reading code helps
It’s not only about finding bugs or solving problems. It’s very helpful to dig into other peoples code to learn new things. I am sure that just like reading a lot of different books (or blog posts) makes you a better writer, reading code makes you a better developer.
General Drupal PHP CMS
What do you think?
Let's discuss on Mastodon