Swiftmailer doesn't send email (only store in spool) - php

I have a web application made with Symfony 2.4 and I use SwiftMailer to send emails.
I use like mailer transport sendmail.
When user send an email, I don't receive this email. But If I do in command line:
$php app/console swiftmailer:spool:send --env=prod
I receive all emails.
¿What can I do?
Thanks a lot!
----Edit----
I have removed all references to spool in my config file, but the problem persist.
----Edit 2----
Config.yml
mailer_transport: sendmail
mailer_host: ****
mailer_user: *****
mailer_password: ****

Delete the spool line from your configuration (parameters.yml i believe? I've never used symfony so i'm interpreting the docs).
Once you've deleted any mention of the spool from your config, it should stop spooling and send immediately.
Having said that, the reason for spooling is so that it sends the email at the end of the execution of the request so that you don't have the performance hit (slowed down requests), probably via a shutdown function... the only reason this function wouldn't execute and therefore your email's not send, is if the script is ending early (i.e. a die/exit or uncatched exception), so you may want to look at addressing the root cause rather than patching around it.
Edit: manual flush (fund this on a command line script example, i've edited it to what i think should make it work for you....)
// now manually flush the queue
$container = $this->getContainer();
$mailer = $this->get('mailer');
$spool = $mailer->getTransport()->getSpool();
$transport = $container->get('swiftmailer.transport.real');
$spool->flushQueue($transport);
http://symfony.com/doc/current/cookbook/console/sending_emails.html

Related

Symfony swiftmail won't send from code

Been struggling with swiftmail for a while now.
I have a linux server and properly working sendmail. Sending mail from command line works.
And sending with swiftmail via command line works as well so the configuration must be OK.
But from code it doesn't. Must have read all the issues of this and I'm totally confused what's going on.
The token is created OK and everything seems to work. No errors in logs. But the mail just doesn't come. I have tried to send to different domains as well. And as I said, it works from command line with mail and swiftmail commands like this:
bin/console swiftmailer:email:send --subject="Test" --body="test" --from="info#domain.com" --to="test#anotherdomain.com"
Here is the current code:
$mailer = $this->get('mailer');
$message = $mailer->createMessage()
->setSubject('You forgot password')
->setFrom('info#domain.com')
->setTo($username)
->setBody('You forgot your password. Go and change it from http://url.com/change-password/'.$user->getConfirmationToken());
$mailer->send($message);
Here is config.yml:
swiftmailer:
transport: sendmail
host: /usr/sbin/sendmail -bs
I had the same issue and fixed it by disabling spool on swift mailer.
You didn't specify the Symfony version you are using. If you are using Symfony 4, there should be a config file in /config/packages/swiftmailer.yaml
Here is mine:
swiftmailer:
url: '%env(MAILER_URL)%'
#spool:
#type: 'memory'
#type: file
#path: '%kernel.project_dir%/var/spool'

How to configure MAILER_URL in .env file of Symfony 4 to send e-mails via sendmail with Swift_Mailer?

I am working on a Symfony 4 app using Swift_Mailer to send e-mails with.
Since there is no possibility in my case to use SMTP (don't ask why…) I have to use something like sendmail.
By default the config of Swift Mailer is done in Symfony's .env file in URL notation in an option named MAILER_URL. The default value is "null://localhost" which doesn't send mails at all.
All I could find for what the value has to be is an example for Gmail or for SMTP in general as documented in the Symfony docs as well as in the sample .env as generated by Composer.
Default content of .env:
# …
###> symfony/swiftmailer-bundle ###
# For Gmail as a transport, use: "gmail://username:password#localhost"
# For a generic SMTP server, use: "smtp://localhost:25?encryption=&auth_mode="
# Delivery is disabled by default via "null://localhost"
MAILER_URL=null://localhost
###< symfony/swiftmailer-bundle ###
# …
What I don't know and therefore what my question is:
What do I need to do to make sendmail work with this?
I already tried something like:
MAILER_URL=sendmail://localhost
and
MAILER_URL=sendmail://my-domain.com
but without success so far.
When using the console command
bin/console swiftmailer:email:send
I even get an "[OK] 1 emails were successfully sent." as result, but in fact no e-mail is sent.
(… No spooling, by the way. bin/console swiftmailer:spool:send returns "0 emails sent".)
Mail delivery seems to be interupted or so, since the mails won't arraive at my mail account, also my SPAM is empty.
Directly invoking the sendmail command on the other hand does work. (My test mails arrive at my SPAM though, but still: The mails are sent.)
Again, how do I have to configure the MAILER_URL for Swift_Mailer in my .env in Symfony 4 to use sendmail?
Is it possible at all?
Alright, the notation already was correct. So this one is valid for using sendmail:
MAILER_URL=sendmail://my-domain.com
My actual problem was that spooling of mails was active. I commented out the spool entry from my swiftmailer.yaml config.
Having a look into the Symfony Profiler helped me a lot here, by the way.
… My mails are still not arriving, but I am sure this has nothing to do with the MAILER_URL. So, my question is answered.
commenting spool in yaml fixed issue for me
Try this config:
swiftmailer:
url: '%env(MAILER_URL)%'
spool: { type: 'memory' }
transport: 'sendmail'
command: '/usr/sbin/sendmail -oi -t'
Path to file:
/my_sf4_project/config/packages/swiftmailer.yaml
I'm using Symfony 4.3.1 and SwiftMailer 6.2.0. You can read in SwiftMailer bundle documentation that:
/**
* Start the standalone SMTP session if running in -bs mode.
*/
and then:
/**
* Set the command to invoke.
*
* If using -t mode you are strongly advised to include -oi or -i in the flags.
* For example: /usr/sbin/sendmail -oi -t
* Swift will append a -f<sender> flag if one is not present.
*
* The recommended mode is "-bs" since it is interactive and failure notifications
* are hence possible.
*
* #param string $command
*
* #return $this
*/
Path to file with these adnotations:
vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/SendmailTransport.php
Before changing into '/usr/sbin/sendmail -oi -t' i was receiving error from SwiftMailer:
app.ERROR: Exception occurred while flushing email queue: Expected response code 220 but got an empty response [] []
After changing sendmail parameters now i'm sending mails successfully.
Not sure I got your problem correctly but in my case I use a Gmail account and here is the 23rd line of my .env file
MAILER_URL=gmail://myadress#gmail.com:myemailpassword#localhost
Have you already installed the SwiftMailer by composer require symfony/swiftmailer-bundle ?
(Sorry for my english)

Symfony 2: Swiftmailer not sending, no errors

Ive recently migrated this website (made with Symfony 2) to a new server, and we decided to go with Google Apps to send emails.
After some connection problems, Ive managed to set it up. I know is working because I can send email in the command line using:
app/console swiftmailer:email:send --subject="Test" --body="test" --from="xxxx" --to="yyyyy"
It works, the email is sent and I receive it immediately.
The problem is: inside the site, is not working. Here is the code:
$mailer = $this->get('mailer');
$message = $mailer->createMessage()
->setSubject('Caderno Mágico: Redefinir Senha')
->setFrom(array($this->container->getParameter('server_mail_address') => 'Caderno Mágico'))
->setTo($usuario[0]->getEmail())
->setBody($this->renderView('Emails/recuperar_conta.html.twig', array('username' => $usuario_selecionado->getUsername(), 'dados' => $hash)), 'text/html');
$mailer->send($message);
Seems right, was working before. The user email there is the same email I used on the command line test. And the config used there is supposed to be the same that's being used when I send it though the command line:
swiftmailer:
transport: smtp
host: smtp.gmail.com
username: yyyy
password: ******
auth_mode: login
port: 465
encryption: ssl
spool: { type: memory }
swiftmailer.plugins.loggerplugin:
class: 'Swift_Plugins_LoggerPlugin'
arguments: ['#swiftmailer.plugins.loggerplugin.logger']
tags: [{ name: 'swiftmailer.default.plugin' }]
swiftmailer.plugins.loggerplugin.logger:
class: 'Swift_Plugins_Loggers_EchoLogger'
arguments: [false]
There is no errors on any log, and the "send" method return true. It just dont works. (Ive tried with and without the spool: no difference). No email is sent.
Ive set this "EchoLogger" plugin, and it works on the command line. I see can all messages and errors at the output, which helped me setting the config and fixing the connection problems. But that doest not seems to do anything when being executed by the server, I cant see any messages on the screen or in any logs.
Ive even tried writing all the values in the code exactly like they are on my command line test, to rule out the possibility of something being wrong there, and still nothing:
$mailer = $this->get('mailer');
$message = $mailer->createMessage()
->setSubject('Test')
->setFrom('yyyyy')
->setTo('xxxxx')
->setBody('test');
$mailer->send($message);
So what can I do? What could be wrong? I dont even know how to debug this. Why would it work when run at the command line and fail silently when run inside the website? Is there any way or any place to see those EchoLogger messages when the code is being run at the server?
Ok, Ive found my own solution. Well, more like a workaround, actually.
It seems like I was having a spool problem: messages were going to the spool and then never sent, for some reason.
So Ive found 2 ways to make ir work:
force a spool flush right after sending:
$mailer->send($message);
$spool = $mailer->getTransport()->getSpool();
$transport = $this->get('swiftmailer.transport.real');
$spool->flushQueue($transport);
explicitly disable the spool in the config:
spool:
enabled: false
In both ways, emails are sent normally
This might be because you didn't tell the controller to send the mail, use this:
$this->get('mailer')->send($message);

Can't override sendmail_path with mail() PHP

In the php.ini, the sendmail_path is : -femail#site.com -t -i
But, in a subdomain, I need to send email with the sender : email#new.site.com
I tried to use
ini_set('sendmail_path',-femail#new.site.com),
but sendmail_path is system, so nothing append.
I tried to define sender in mail(), doesn't work (on the log of the server, the sender is still email#site.com, but in the email client, the sender is fine, but it doesn't matter).
I tried to define the 5th parameter, but the function just stop working (do nothing, no error).
Any suggestions ?
Thanks,
Greg
Think about how mail is configured in PHP - it's just a wrapper around an exec call (with some predefined arguments). Hence it's trivial to invoke sendmail via exec substituting your own aruments. This is described in the first comment on the page describing PHP mail config. You just need to composite your own headers (sendmail extracts the recipient addresses from the headers to fill in the envelope, any Bcc lines are stripped before the email is forwarded).
Another approach would be to use a SMTP capable abstraction layer such as swiftmailer or phpmailer - but you probably won't be able to use 'localhost' if it's configured as a slave relay.

mail() timeout issue

When I execute my email script via browser a timeout fatal error is returned (unless I drastically increase the execution time, then it will run ok, not the solution I'm looking for). The email is sent tho, but it takes forever (5 min. average) to arrive (at my inbox)!
(Considering that via command line it works perfectly I think that SMTP at php.ini is certainly well configured.)
So this is the code executed by browser request:
<?php
mail('amatos#example.com', 'test subject', 'test body', 'From: Andre Matos <amatos#example.com>');
?>
and when I run this same (is it really the same? I'm starting to doubt myself) code via command line:
php -r "mail('amatos#example.com', 'test subject', 'test body', 'From: Andre Matos <amatos#example.com>');"
it works perfectly! The script runs, it stop and the email arrives instantly (2/3 seconds).
So, what can cause this difference and how to fix it? Any ideas?
Thanks in advance.
[edit] some extra info:
- the machine is windows
- the server is localhost
- php.ini is the same for both the browser and the cli instance
[edit2]
Thank you all for trying to guess which was the problem. I placed the question hopping that someone had the problem before and knew of something specific. Given nothing specific showed up and none of the suggestions really worked, I've decided to accept the one that allowed me to reach more conclusions about the problem... +1 For all your helpful knowledge/thoughts (/guesses) :-)
I've hypothesised some couses, but I used to linux and on windows I can olny guess:
php_cli and mod_php are 2 different binaries, mod_php can be slightly damaged
php_cli and mod_php use 2 different users, the network profile of apache user can be the problem (dns, firewall, proxy...)
your php script is on "problematic" location or contains some problematic character, but your cli script is by param, try to execute same script: php -f z:\path\to\php\mail.php
Given this note from http://php.net/manual/en/function.mail.php, it seems very likely that the issue is with the MTA and not PHP directly:
The Windows implementation of mail() differs in many ways from the Unix implementation. First, it doesn't use a local binary for composing messages but only operates on direct sockets which means a MTA is needed listening on a network socket (which can either on the localhost or a remote machine).
Perhaps it has something to do with the way the MTA is responding to the particular user, or user-specific firewall rules for outgoing mail connections on your machine. Can you run the command-line as the web server user rather than yourself? If so, does that re-create the problem from the command-line?
How about having the web server execute the command-line PHP rather than the parsed PHP file? (For example, perhaps you can run a batch script via CGI.) Does that solve the problem?
(Sorry that these are more guesses than definite answers.)
Just to be clear: The php-instance used by the script is the same as the one used by the command line code?
Many web hosts use smtp-relay, which will gather a bunch of emails and send them all at once, so it won't be strange behaviour if your mail is late. However, the long execution time is not normal.
Before you send your mail in the script make sure to print out the ini_get() of the variables SMTP, smtp_port, and sendmail_from and be certain that these are working values. PHP running on Windows does not have the benefit of sending mail out via Sendmail, and whatever the PHP devs cobbled together for it is sketchy at best.
I always like to test mail via telnet so I can see if the server is giving an error that is not being passed back properly by the client:
c:\> telnet smtp.domain.com 25
220 smtp.domain.com ESMTP Postfix
helo mailtest
250 smtp.domain.com
mail from: user#local.com
250 2.1.0 Ok
rcpt to: user#remote.com
250 2.1.5 Ok
data
354 End data with <CR><LF>.<CR><LF>
from: user#local.com
to: user#remote.com
subject: test mail
this is a test message
.
250 2.0.0 Ok: queued as 42AD8364FE0E
quit
221 2.0.0 Bye
Try to set username and password to "From" mail id. so it can authenticate and sends the mail quickly.
Have you tried PHP mailer?
In my observation its sends mails within seconds. Below example will give you a quick look how to use php mailer class.
include "class.phpmailer.php";
$msg="Hello! This is a test..."
$mail=new PHPMailer();
$email="someone#friend.com"; //person who receives your mail
$mail->IsSMTP();
$mail->Host = "localhost";
$mail->SMTPAuth = true;
$mail->Username = "admin#example.com"; //your mail id
$mail->Password = "sdfsd441"; //password for your mail id
$mail->SetFrom('admin#example.com', 'admin'); //from address
$mail->AddAddress($email);
$mail->Subject ="Test Mail";
$mail->Body = $msg;
$mail->IsHTML(true);
$mail->MsgHTML($msg);
$mail->Send();
EDIT :
In PHP manual they stated like this,
The Windows implementation of mail() differs in many ways from the Unix implementation. First, it doesn't use a local binary for composing messages but only operates on direct sockets which means a MTA is needed listening on a network socket (which can either on the localhost or a remote machine).
so that may cause delay? I think this link might help you.
My first guess would be that the browser version of your mailing has already a context or connections ready for the sending.
On the contrary, the direct (php -r) execution has to load the mailing context.
To confirm this idea, you can make a loop for sending 10 mails and check wether the mails after the first are much quicker.

Categories