Yii2 SwiftMailer sends mails twice - php

I write a game for football fans. So, I have to send similar mails to a group of people (not completely duplicated e-mail copies).
When I send the mails in a cycle - Yii framework sends the mails twice.
I suppose - it is because of the static variable Yii::$app.
Can someone give me a hint, please.
A code for example.
foreach ($oRace->user as $currUser) {
$htmlContent = $this->renderPartial('start_race', ['oRace' => $oRace]);
Yii::$app->mailer->compose()
->setFrom('info#example.com')
->setTo($currUser->mail)
->setSubject('Race "' . $raceName . '" has Started')
->setHtmlBody($htmlContent)
->send();
}
Thanks all in advance!
My Mailer config.
'mailer' => [
'class' => 'yii\swiftmailer\Mailer',
'useFileTransport' => false,
'transport' => [
'class' => 'Swift_SmtpTransport',
'host' => 'mail.example.eu',
'username' => 'support#example.com',
'password' => 'password',
'port' => '587',
'encryption' => 'TLS',
]
],
One more thing. The last mail in the cycle is never duplicated (only the last).
Another failed option.
Yii::$app->mailer->sendMultiple($allMails);

I recommend you to use CC or BCC option in the email instead of using foreach loop to send emails. I hope this will help someone.
$email = [];
foreach ($oRace->user as $currUser) {
$email[] = $currUser->mail;
}
$htmlContent = $this->renderPartial('start_race', ['oRace' => $oRace]);
Yii::$app->mailer->compose()
->setFrom('info#example.com')
->setCc($email) // If you're using Bcc use "setBcc()"
->setSubject('Race "' . $raceName . '" has Started')
->setHtmlBody($htmlContent)
->send();

From the provided code snippets, there are 3 possible reasons for that. Either:
$oRace->user contains every user twice
$currUser->mail contains the email twice like `email#example.com;email#example.com"
something is wrong inside the send function of SwiftMailer

After all - I have found that the issue was not with my Yii2 framework, but with my hosting mail server.
I have used https://github.com/ChangemakerStudios/Papercut for listening what my framework sends. It receives mails on port 25, while it listens for events on port 37804. It's a little bit confusing. Yii2 web.php simple configuration for local mail server is:
$config = [
'components' =>
'mailer' => [
'class' => 'yii\swiftmailer\Mailer',
'useFileTransport' => false,
'transport' => [
'class' => 'Swift_SmtpTransport',
'host' => 'localhost', // '127.0.0.1'
'port' => '25',
]
],
],
];
Thank of all, who have read my post!

Related

Cakephp 3 email with SMTP not working

I am trying to send an email from my CakePHP 3 application. But every time it is using the localhost SMTP and I am getting the error.
So here is my code.
public function sendEmail($email, $subject, $message){
// Sample SMTP configuration.
$this->loadModel('Generalsettings');
$query = $this->Generalsettings->find('all')->where(['meta_key' => 'smtp_details'])->applyOptions(['default' => false]);
$smtpdetail = $query->first();
$detail = json_decode($smtpdetail->value);
Email::configTransport('gmail', [
'host' => $detail['host'], //value is 'ssl://smtp.gmail.com'
'port' => $detail['port'], //value is 465
'username' => $detail['username'],
'password' => $detail['password'],
'className' => 'Smtp'
]);
$emailClass = new Email();
$emailClass->from(['er.dhimanmanoj#gmail.com' => "Sender"])
->to($email)
->subject($subject)
->send($message);
}
Please tell me if I am doing something wrong. Thanks in advance.
You haven't specified the transport you just created using configTransport() method. So it is taking the default settings from config/app.php.
You can setup transport like this:
$emailClass = new Email();
$emailClass->transport('gmail');
NOTE: Deprecated since version 3.4.0: Use setTransport() instead of transport().
For more info please refer to this link #https://book.cakephp.org/3.0/en/core-libraries/email.html
Hope this helps!

SparkPost PHP reply_to not working

I am using SparkPost PHP API for sending emails and it seems like reply_to feature is not working. I tried to both ways with headers and with reply_to field. Any ideas what could be wrong? Domain name of reply_to emails is different as senders one. I didn't found any restrictions regarding this in their documentation. Any ideas?
Here is my code:
$emailData = array(
'from'=> $data["from_name"].' <'.$data["from_email"].'>',
'html'=> $data["html"],
'inline_css' => true,
'transactional' => true,
'subject'=> $data["subject"],
'recipients'=> $rec["r"]
);
if(isset($data["headers"]["Reply-To"]))
$emailData['reply_to'] = $data["headers"]["Reply-To"];
try {
// Build your email and send it!
$this->mandrill->transmission->send($emailData);
} catch (\Exception $err) {
echo "<pre>";
print_r($err);
echo "</pre>";
}
Regarding: SparkPost PHP ReplyTo, reply_to, Reply
For anyone else wondering the same thing. Here's my implementation using SparkPost client library for PHP v2.1. I hope it helps.
I used the transmissions endpoint as seen in the docs.
https://github.com/sparkpost/php-sparkpost
$promise = $sparky->transmissions->post([
'content' => [
'from' => [
'name' => 'Company Name',
'email' => 'noreply#company.com',
],
'reply_to' => $email,
'subject' => 'Some Subject',
'html' => $html_message,
'text' => $text_message,
],
'substitution_data' => $subData,
'recipients' => [
[
'address' => [
'name' => 'My Recipient',
'email' => 'me#company.com',
]
],
],
]);
Thank god for slack :)
Solution is that SparkPost has different name for parameters in API documentation. Correct parameter for PHP API is not reply_to (as it's written in doc) but replyTo.

Silex + Swift Mailer not working

I have a Silex app with Swift Mailer, but it seems like the configuration was not loaded from $app['swiftmailer.options'].
I registered the service in my bootstrap file
$app->register(new SwiftmailerServiceProvider());
And in my configuration file
$app['swiftmailer.options'] = array(
'host' => 'smtp.mandrillapp.com',
'port' => '587',
'username' => 'MY_USERNAME',
'password' => 'MY_PASSWORD',
'encryption' => null,
'auth_mode' => null
);
And then I send my email with
$message = \Swift_Message::newInstance()
->setSubject($this->app['forum_name'] . ' Account Verification')
->setFrom(array('no-reply#domain.com'))
->setTo(array('recipient#example.com'))
->setBody('My email content')
->setContentType("text/html");
$this->app['mailer']->send($message);
The send function returns 1 but the email was never sent. But, when I try manually creating an instance of Swift_SmtpTransport, the email would send.
$transport = \Swift_SmtpTransport::newInstance('smtp.mandrillapp.com', 587)
->setUsername('MY_USERNAME')
->setPassword('MY_PASSWORD');
...
$mailer = \Swift_Mailer::newInstance($transport);
$mailer->send($message);
So the problem is the $app['swiftmailer.options'] is not read or loaded. Am I missing something here?
I'm following the instructions from here.
By default the SwiftmailerServiceProvider uses a spooled transport to queue up emails and sends them all during the TERMINATE stage (after a response is sent back to the client). If you don't call Application->run(), you are bypassing this process. Your mail will stay in the spool and never get sent.
If you want to sent mail outside of the normal Silex flow, you can flush the spool manually with
if ($app['mailer.initialized']) {
$app['swiftmailer.spooltransport']
->getSpool()
->flushQueue($app['swiftmailer.transport']);
}
That's taken directly from the SwiftmailerServiceProvider.
Or you can simply turn off spooling with
$app['swiftmailer.use_spool'] = false;
Try this:
$app->register(new \Silex\Provider\SwiftmailerServiceProvider(), array(
'swiftmailer.options' => array(
'sender' => 'sender',
'host' => 'host',
'port' => 'port',
'username' => 'username',
'password' => 'password'
)
));
It is not in the documentation.

Can swiftMailer be used on localhost to send emails?

I am currently not receiving emails using the below configuration and was wondering if's it something to do with my set up maybe missing something or it doesnt work on MAMP localhost?
main-local.php in common config directory
'mailer' => [
'class' => 'yii\swiftmailer\Mailer',
'viewPath' => '#common/mail',
// send all mails to a file by default. You have to set
// 'useFileTransport' to false and configure a transport
// for the mailer to send real emails.
'useFileTransport' => true,
],
And then to send the email (which does display a success message)
public function submitreview($email)
{
//return Yii::$app->mailer->compose(['html' => '#app/mail-templates/submitreview'])
return Yii::$app->mailer->compose()
->setTo($email)
->setFrom([$this->email => $this->name])
->setSubject($this->title)
->setTextBody($this->description)
->attachContent($this->file)
->send();
}
You can send mail through localhost in Yii2 with following config.
'mailer' => [
'class' => 'yii\swiftmailer\Mailer',
'useFileTransport' => false,
'transport' => [
'class' => 'Swift_SmtpTransport',
'host' => 'smtp.gmail.com',
'username' => 'ENTER_EMAIL_ADDRESS_HERE',
'password' => 'ENTER_PASSWORD',
'port' => '587',
'encryption' => 'tls',
],
]
and in your controller
\Yii::$app->mail->compose('your_view', ['params' => $params])
->setFrom([\Yii::$app->params['supportEmail'] => 'Test Mail'])
->setTo('to_email#xx.com')
->setSubject('This is a test mail ' )
->send();
I simply m using gmail for testing, used this php file to send mail from local host.
When you're going for production, replace the transport file with your original credentials.
the $result will echo 1, if the mail is successfully sent
<?php
$subject="Testing Mail";
$body="<h2>This is the body</h2>";
$to="*******#gmail.com"; //this is the to email address
require_once 'swiftmailer/swift_required.php';
// Create the mail transport configuration
$transport = Swift_SmtpTransport::newInstance('smtp.gmail.com', 465, 'ssl')->setUsername('######')->setPassword('######');
//$transport = Swift_MailTransport::newInstance();
$message = Swift_Message::newInstance()
->setSubject($subject)
->setFrom(array('#######gmail.com'))
->setTo(array($to))
->setBody($body,'text/html');
//send the message
$mailer = Swift_Mailer::newInstance($transport);
$result=$mailer->send($message);
?>
When useFileTransport is set to true (Default in development environment) then mails are saved as files in the 'runtime' folder.
For example, if you are using the advanced starter template and signup as a user when in the backend of the site (And using an extension that sends user registration emails), the registration email will be saved in /backend/runtime/mail

CakePHP mail not working on server

I recently uploaded a CakePHP 2.3.8 app to a Ubuntu 12.04 EC2 instance and now I cannot send emails when using $Email->send() but I can do it with the "fast" method of CakeEmail::deliver('to#gmail.com', 'Subject', 'Content');, however I have a layout that I want to use.
When I try to send an email I get an error stating "Could not send email.
Error: An Internal Error Has Occurred."
Here is my code for sending the email.
App::uses('CakeEmail', 'Network/Email');
$Email = new CakeEmail();
$Email->from(array('myemailaddress#gmail.com' => 'Me'));
$Email->to('person#gmail.com');
$Email->subject('Test Email');
$Email->template('layout_1');
$Email->emailFormat('html');
$testvalues = array('item1' => 'test1', 'item2' => 'test2');
$Email->viewVars(array('tesvalues'=> $testvalues));
$Email->send();
$this->Session->setFlash('Email has been sent');
$this->redirect($this->referer(), null, true);
In /App/Config/email.php here is what I have for smtp
public $smtp = array(
'transport' => 'Smtp',
'from' => array('me#gmail.com' => 'Me'),
'host' => 'ssl://smtp.gmail.com',
'port' => 465,
'timeout' => 30,
'username' => 'me#gmail.com',
'password' => '****',
'client' => null,
'log' => false,
//'charset' => 'utf-8',
//'headerCharset' => 'utf-8',
);
The exact line that the stack trace flags is in CORE/Cake/Network/Email/MailTransport.php
$this->_mail($to, $email->subject(), $message, $headers, $params);
I checked the error log and it says
Error: [SocketException] Could not send email.
I am going to shoot in the dark here.
It seems to me that you are not setting the layout correctly, according to the documentation you need to tell cake the layout and the view you want to use, for example:
$Email = new CakeEmail();
$Email->template('welcome', 'fancy')
->emailFormat('html')
->to('bob#example.com')
->from('app#domain.com')
->send();
The above would use app/View/Emails/html/welcome.ctp for the view, and app/View/Layouts/Emails/html/fancy.ctp for the layout.
Anyways, I recommend taking a look at Cake logs (app/tmp/logs) and see the cause of your error

Categories