I have managed to mostly successfully migrate my site from one host to another. However I get a 500 server error when attempting to use modx->mail. I noticed it at first when my FormIt calls with email didn’t work, but deeper testing shows that it’s specific to mail. Using a resource with only a call to QuickEmail I get the 500 error.
Step to reproduce
Create a new resource with just a call to QuickEmail, and visit the page in the browser.
Observed behavior
500 Server error with the following server log:
[23-May-2025 11:33:12 Europe/London] PHP Fatal error: Uncaught Error: Call to a member function set() on null in ***/public_html/core/cache/includes/elements/modx/revolution/modsnippet/83.include.cache.php:135
Stack trace:
#0 ***/public_html/core/src/Revolution/modScript.php(88): include()
#1 ***/public_html/core/src/Revolution/modParser.php(508): MODX\Revolution\modScript->process(NULL)
#2 ***/public_html/core/src/Revolution/modParser.php(221): MODX\Revolution\modParser->processTag(Array, true)
#3 ***/public_html/core/src/Revolution/modResource.php(520): MODX\Revolution\modParser->processElementTags('', '<!doctype html>...', true, false, '[[', ']]', Array, 9)
#4 ***/public_html/core/src/Revolution/modResource.php(468): MODX\Revolution\modResource->parseContent()
#5 ***/public_html/core/src/Revolution/modResponse.php(72): MODX\R in ***/public_html/core/cache/includes/elements/modx/revolution/modsnippet/83.include.cache.php on line 135
Expected behavior
I expect to get information about the mail server configuration and not the 500 error.
Is my issue as a result of something I’ve done in migrating the site? I’ve tried reinstalling MODX, but still get the same response. I’ve emptied cache’s etc. It looks like something isn’t getting initialised such that a NULL is being passed to the MODX->mail method.
By that, do you mean the snippet QuickEmail (from the extra with the same name)?
$modx->mail should get set on line 58 of that snippet by calling getService():
I have no idea why $modx->mail doesn’t get set.
One reason could be that another extra (that runs earlier) uses $this->services->add('mail', ...) to add the mail service without using $modx->getService('mail', ...) for that.
Are there any other extras on your system that send mails and may interfere?
Another reason could be that the class mail.modPHPMailer can’t be found.
Does it work if you change the line to $modx->getService('mail', 'MODX\Revolution\Mail\modPHPMailer');? Does the file core/src/Revolution/Mail/modPHPMailer.php exist?
Sorry, yes it is Bob Ray’s QuickEmail. I’ve amended the original post for clarity.
core/src/Revolution/Mail/modPHPMailer.php does exist, I’ve just checked.
There is no change if I amend the line as you suggest.
As far as I am aware there isn’t anything else that sends emails in any other extras. It was working previously on the old hosting service, which makes me wonder if it’s something I’ve done in relocating to the new host.
I have another domain at this host, with the same settings and a default install of MODX, which works with the QuickEmail extra. So it would suggest it’s something I’ve got messed up in the move. Just not sure where or how.
It probably tells us, that one of the installed extras uses $this->services->add('mail', ...) directly to add the mail-service (to the Dependency Injection Container), without setting the variable $modx->mail.
Although this doesn’t explain why sending mails with FormIt doesn’t work, as FormIt uses the response from getService('mail', ...) directly and doesn’t rely on $modx->mail (as QuickEmail does).
Right, so I worked out what was happening with FormIt. I had a hook that I’m using to attach a signature to the email that FormIt creates. Using the following code (which worked at my previous host) I get the 500 error:
I would appreciate understanding exactly what the difference between the 2 methods is, because I’m not sure why one works and the other doesn’t.
The email is sent but takes a long time to actually arrive (the time is variable, but is at least 6 minutes, but I have had it take 30). Is there anything that can be done about the speed of delivery. In MODX? At the server?
For modx->getService(...), it’s best to look at the code of the function:
Here the Dependency Injection Container is also used to see if a service already exists (L1252, L1267). If it doesn’t exist yet, a new instance of the supplied class is created (L1260), the service gets added to the Injection Container (L1262) and a dynamic property (with the name of the service) is generated (L1263). Which in your case is $modx->mail.
I don’t think it’s good practice to fix the code like this. This will only work if another part of the code added the service beforehand (which is usually not the case). Otherwise you get a fatal runtime error.
I would suggest you still use $modx->getService(), but then you use the response directly and don’t use$modx->mail. (These dynamic properties are a bad idea anyway.)
So I would do something like this:
<?php
// set local variable $mail to the service
$mail = $modx->getService('mail', 'MODX\Revolution\Mail\modPHPMailer');
// use the service via the local variable $mail
$mail->mailer->AddAttachment($attachment_path);
By default, email is sent using PHPs mail() feature. This uses server-level settings, but is typically not recommended due to poor deliverability. Instead, configure sending via SMTP.