I am working on my first Symfony 5 project and struggle to send mail using the build in MailerInterface. I have worked with Swift Mailer in Symfony 3 before and never had similar issues before.
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Mailer\MailerInterface;
...
class SomeController extends AbstractController {
public someAction(Request $request, MailerInterface $mailer) {
...
$email = (new TemplatedEmail())
->from(new Address('address#example.com', 'My Symfony Mail'))
//->to($user->getEmail())
->to('receiver#example.com')
->subject('Subject')
->htmlTemplate('email.html.twig');
$mailer->send($email);
}
}
// .env
#MAILER_DSN=smtp://user:pass#smtp.example.com:25
MAILER_DSN=sendmail://default
If MAILER_DSN has some malformed format an exception is thrown and shown on the Symfony debugger page, e.g. The "invaliddsn" mailer DSN must contain a scheme... Thus it seems that the configured DSN smtp://user:pass#smtp.example.com:25 is correct. Using the same credentials, host and port in other mail applications is no problem.
However, when using this code no error/exception is shown and I receive no mail at all. Of course I have double checked the logs (no errors), the receivers spam folder (nothing). Specifying an SMTP server or sendmail does not make any difference.
The Symfony docs only explain how to handle exceptions but in my case no exceptions are thrown.
While there are a lot of other questions about mailing issues in Symfony, most of them deal with the older Swift Mailer or other, specific problems.
How can I figure out if a mail is send and not received or not send at all?
If it's not throwing an exception, you can assume the transport did not raise an error condition.
From the docs:
Handling Sending Failures
Symfony Mailer considers that sending was successful when your transport (SMTP server or third-party provider) accepts the mail for further delivery. The message can later be lost or not delivered because of some problem in your provider, but that’s out of reach for your Symfony application.
If there’s an error when handing over the email to your transport, Symfony throws a Symfony\Component\Mailer\Exception\TransportExceptionInterface. Catch that exception to recover from the error or to display some message
You can also check the object that send() returns:
The Symfony\Component\Mailer\SentMessage object returned by the send() method of the Symfony\Component\Mailer\Transport\TransportInterface provides access to the original message (getOriginalMessage()) and to some debug information (getDebug()) such as the HTTP calls done by the HTTP transports, which is useful to debug errors.
Finally, if you have the Symfony Web Profiler, since you are doing the sending during a Web Request, you can check the profiler's output for information about the mail sending attempt.
MailerInterface use Messenger, the asynchrone functionality.
If you comment the default configuration in config/packages/messenger.yaml
#Symfony\Component\Mailer\Messenger\SendEmailMessage: async
Yours emails will be sent immediatly.
Related
PHPMailer 5.2.28
Running inside Zen Cart PHP based ecommerce system.
I may be misunderstanding things but I'm stepping through PHPMailer when I accidentally mistype the host or port number and the useful error message that is created gets discarded before PHPMailer returns from Send().
The sequence of events is:
Create PHPMailer instance with Host = 'mistaken-smtp.gmail.com', everything else normal and try to send an email.
smtpConnect() calls $this->smtp->connect
in class.smtp.php the connect() function sets a custom errorHandler: set_error_handler(array($this, 'errorHandler'));
The call to fsockopen() fails because of the mistyped hostname
errorHandler is invoked, calls $this->setError($notice, $errno, $errmsg) with a useful message like 'cannot connect to host mistaken-smtp.gmail.com'
Because the connection failed, connect() then calls setError itself (line 319), overwriting the error object set by the errorHandler but still has some useful information about what caused the connection failure, and returns false.
Because $this->smtp->connect returned false, PHPMailer.smtpConnect skips the workhorse body of the function and skips to line 1727 where it calls $this->smtp->close() and will return false.
The call to $this->smtp->close causes the smtp class to complete wipe out its error object with $this->setError(''); .. it's here that any useful error messages get completely lost.
Because smtpConnect() returned false, PHPMailer.smtpSend throws a phpmailerException on line 1558 which is caught in postSend() on line 1352 and PHPMailer.setError is called with the exception's message, which by now is a rather unuseful "SMTP connect() failed. https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting"
PHPMail.setError does try to inspect $this->smtp->getError() on line 3273 instead of using the plain $msg passed in, but because the close() earlier wiped out the error details in the smtp object, PHPMailer.setError simply sets ErrorInfo to the unhelpful error string from the exception.
This behaviour seems to have been around for ages so I imagine no-one has cared enough to address it in detail. I can certainly work around this but it seems buggy. Is there another way to get error info out of PHPMailer in this case?
This came to my attention because we hit some kind of quota limit with gmail, trying to mailshot via smtp.gmail.com sent 100 emails OK but then repeatedly failed to connect, the only error message coming to our code being 'SMTP connect() failed'. In our case the hostname, port etc were fine (unlike the fictional case above) but the gmail server refused the connection and the error handling I mentioned above was invoked, it's just hard to reproduce easily. It would have been very valuable to get the actual SMTP error message returned that was lost due to the dodgy error handling I outline above. (For anyone else hitting this, I spent an hour on live chat with google support to be told to use smtp-relay.gmail.com instead of smtp.gmail.com and this does appear to get around the quota problem.)
I'm aware there's a version 6 which may not contain this behaviour, but as it's a major breaking release and we're dependent on the integration of 5.x in our ecommerce system and upgrade is not possible right now.
I am currently in the process of doing a project in magento.
I have a problem with my contact form: emails are not sent to me.
I did a test and I still get this message:
Unable to submit your request . Please, try again later
It's probably because an exception is thrown as you can see in the file
app/code/core/Mage/Contacts/controllers/IndexController.php in the postAction() function, you should try to debug from here.
Maybe the contact email failled to be sent (if you are in localhost and have no mail server?), that could cause the exception that shows this error.
I've been struggling with this for a day as nobody gives a clear answer on the topic.
In order to get it working there are 2 options:
Configure smtp server for email sending using smtp pro extension from Magento connect
Make Magento use the SendMail function of the webserver
As the first option didn't work for me, as my hosting provider somehow block the smtp outgoing connection, I needed to use the SendMail function.
The quick and dirty trick I used, was to change /app/code/core/Mage/Core/Model/Email/Template.php line 116:
Zend_Mail::setDefaultTransport($transport); → //Zend_Mail::setDefaultTransport($transport);
After this my error message at the contact form was gone and I received
the email correctly.
Be carefull: This is not a good solution as it will be undone at a Magento update. Also it was not tested for the other email functions of Magento.
I am using the FOSUser bundle within my Symfony2 application. I am trying to get the email functionality working but can't get any emails to send successfully.
My development environment is a Ubuntu virtual machine. I tried to use my Gmail account details as described here. I also checked the error logs but nothing regarding the email sending is logged.
I attempted to send a test email using a test controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class TestEmailController extends Controller
{
public function sendEmailAction()
{
$message = \Swift_Message::newInstance()
->setSubject('Hello Email')
->setFrom('send#example.com')
->setTo('me#myemailaddress.com') // use a valid email in actual code...
->setBody('yo, wassup!');
$this->get('mailer')->send($message);
return $this->render('SysDevPunctualityBundle:TestEmail:sendEmail.html.twig', array(
// ...
));
}
}
However this triggers an error with Symfony's web profiler toolbar and I get the following message; "Token "3c494e" was not found in the database."
After some digging around I found this question I followed the suggestion of removing the spool option and also added a 'from_email' option. This made a difference, I am now getting a timeout error:
Connection could not be established with host smtp.gmail.com [Connection timed out #110]
My guess is that the firewall is blocking the request, I don't know how to find out for sure.
Appreciate if anyone can point me in the right direction.
I discovered that the source of the problem was that my work firewall was blocking access to the Gmail SMTP server. I switched to another SMTP server (set up by our IT department) and email sending now works fine.
Check these two links from the cookbook, to find out how to handle emails while developing: http://symfony.com/doc/current/cookbook/email/dev_environment.html & http://symfony.com/doc/current/cookbook/email/spool.html
SwiftMailer is the default way of sending email from a Symfony 2 project, and I'd like to use it in an application. I've pointed it towards the SMTP server provided by my internet provider (Virgin Media, in the UK), but my emails are not successfully sent. The exception thrown says
Expected response code 250 but got code "501", with message "501 HELO requires valid address
in response to the SMTP command
HELO [::1]
[::1] corresponds to localhost in IPv6, and it's not that surprising that the SMTP server would reject that if it's expecting a proper domain name. Tracing execution through the Swiftmailer source, I find that this value comes from _domain on AbstractSmtpTransport; altering the value during the debug session allows the email to be sent. Although it can be set using the public setLocalDomain() method, it isn't anywhere in the Symfony 2 framework, so it seems that there is no way (obvious to me, at least) of easily configuring this value simply by, for example, changing a Symfony config file.
So my question is this: is there some other way of changing this value, ideally using config, without my diving into the Symfony code and changing bits that aren't meant to be changed? And if so, what?
From inside a Symfony controller, you can configure the HELO/EHLO name like that:
$this->get('swiftmailer.transport')->setLocalDomain('your.domain');
Unfortunately no.
The code for get the local domain in SwiftMailer is:
/** Try to determine the hostname of the server this is run on */
private function _lookupHostname()
{
if (!empty($_SERVER['SERVER_NAME'])
&& $this->_isFqdn($_SERVER['SERVER_NAME']))
{
$this->_domain = $_SERVER['SERVER_NAME'];
} elseif (!empty($_SERVER['SERVER_ADDR'])) {
$this->_domain = sprintf('[%s]', $_SERVER['SERVER_ADDR']);
}
}
So, is guessed and it's server configuration.
I opened an issue for SwiftMailer to do this:
https://github.com/swiftmailer/swiftmailer/issues/453
UPDATE: The issue has been resolved on Feb 27th 2018.
I am using the Zend framework to send mail. Once the config is done and the code written it all boils down to one call:
$Mail->send($Transport)
How can i check that this mail has been sent correctly? I read somewhere that Zend Mail throws an exception but other people have said this is sometimes not the case.
What's the bulletproof programmatic way to ensure mail has been sent properly when using Zend_Mail?
EDIT: When i mean sent, i mean sent to the SMTP server.
Generally Zend_Mail will throw an exception if there is something wrong going on on the send-process - but this strongly depends on the Zend_Mail_Transport_* being used.
You have two options here:
Zend_Mail_Transport_Sendmail (the default transport) relies on mail(). If mail() returns false, Zend_Mail_Transport_Sendmail throws a Zend_Mail_Transport_Exception (Unable to send mail). The return value itself is not very reliable. This is what the manual says about the return value:
Returns TRUE if the mail was successfully accepted for delivery, FALSE otherwise.
It is important to note that just because the mail was accepted for delivery, it does NOT mean the mail will actually reach the intended destination.
Zend_Mail_Transport_Smtp sends the email using the SMTP protocol that's encapsulated in Zend_Mail_Protocol_Smtp. In this case you'll get a Zend_Mail_Protocol_Exception whenever something either violates the SMTP protocol (sending mail without giving a sender's address e.g.) or the STMP server reports an error or the connection times out.
So if no exception is thrown when talking to the STMP server, you can be sure that the remote server at least accepted your email.
I guess it's not. If "sending" failed you get an exception. But that's only a check, that the send() function worked properly. It doesn't mean the mail got send.
I guess the only way to ensude the mail was delivered is to insert a confirmation code link inte the mail and make user click it.