Skip to content

Instantly share code, notes, and snippets.

@rahimov
Last active March 22, 2016 12:53
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save rahimov/bad626a32dd334273a9f to your computer and use it in GitHub Desktop.
Save rahimov/bad626a32dd334273a9f to your computer and use it in GitHub Desktop.
yii2 db spool
'mailer' => [
'class' => 'yii\swiftmailer\Mailer',
'transport' => [
'class' => 'Swift_SpoolTransport',
'constructArgs' => [
'spool' => new common\components\swiftmailer\DbSpool(),
]
],
],
<?php
namespace common\components\swiftmailer;
use common\models\MailerQueue;
use yii\helpers\HtmlPurifier;
class DbSpool extends \Swift_ConfigurableSpool
{
/**
* File WriteRetry Limit
*
* @var int
*/
private $_retryLimit = 10;
// /**
// * Create a new DbSpool.
// *
// * @param string $path
//
// */
public function __construct()
{
}
/**
* Tests if this Spool mechanism has started.
*
* @return bool
*/
public function isStarted()
{
return true;
}
/**
* Starts this Spool mechanism.
*/
public function start()
{
}
/**
* Stops this Spool mechanism.
*/
public function stop()
{
}
/**
* Allow to manage the enqueuing retry limit.
*
* Default, is ten and allows over 64^20 different fileNames
*
* @param int $limit
*/
public function setRetryLimit($limit)
{
$this->_retryLimit = $limit;
}
/**
* Queues a message.
*
* @param Swift_Mime_Message $message The message to store
*
* @return bool
*
* @throws Swift_IoException
*/
public function queueMessage(\Swift_Mime_Message $message)
{
$queueObject = new MailerQueue();
$queueObject->from = implode('; ', array_keys($message->getFrom()));
if($message->getTo() !== null ){
$queueObject->to = implode('; ', array_keys($message->getTo()));
}
if($message->getCc() !== null ){
$queueObject->cc = implode('; ', array_keys($message->getCc()));
}
if($message->getBcc() !== null ){
$queueObject->bcc = implode('; ', array_keys($message->getBcc()));
}
$queueObject->text_body = HtmlPurifier::process($message->getBody(), ['HTML.Allowed' => '']);
$queueObject->subject = $message->getSubject();
$queueObject->html_body = $message->getBody();
$queueObject->message_object = serialize($message);
if($queueObject->save()){
} else {
//FIXME УБРАТЬ!!!
// print_r($queueObject->getErrors());
// die();
}
}
// /**
// * Execute a recovery if for any reason a process is sending for too long.
// *
// * @param int $timeout in second Defaults is for very slow smtp responses
// */
// public function recover($timeout = 900)
// {
// foreach (new \DirectoryIterator($this->_path) as $file) {
// $file = $file->getRealPath();
//
// if (substr($file, - 16) == '.message.sending') {
// $lockedtime = filectime($file);
// if ((time() - $lockedtime) > $timeout) {
// rename($file, substr($file, 0, - 8));
// }
// }
// }
// }
/**
* Sends messages using the given transport instance.
*
* @param Swift_Transport $transport A transport instance
* @param string[] $failedRecipients An array of failures by-reference
*
* @return int The number of sent e-mail's
*/
public function flushQueue(\Swift_Transport $transport, &$failedRecipients = null)
{
if (!$transport->isStarted())
{
$transport->start();
}
$failedRecipients = (array) $failedRecipients;
$count = 0;
$emails = MailerQueue::find()
->where('sent_time IS NULL')
->orderBy('id')
->all();
if (!count($emails)) {
return 0;
}
//->count($this->getMessageLimit())
// $emails = $this->repository->getEmailQueue($this->getMessageLimit());
foreach($emails as $email){
/*@var $message \Swift_Mime_Message */
$message = unserialize($email->getAttribute('message_object'));
try{
$count+= $transport->send($message, $failedRecipients);
if($count > 0){
// $this->repository->markCompleteSending($email);
$time = new \DateTime();
$email->setAttribute('sent_time', $time->format('Y-m-d H:i:s'));
$email->save();
}else{
throw new \Swift_SwiftException('The email was not sent.');
}
}catch(\Swift_SwiftException $ex){
// $this->repository->markFailedSending($email, $ex);
}
}
return $count;
}
}
CREATE TABLE `mailer_queue` (
`id` int(11) NOT NULL AUTO_INCREMENT ,
`from` text CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL ,
`to` text CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL ,
`cc` text CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL ,
`bcc` text CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL ,
`subject` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL ,
`html_body` text CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL ,
`text_body` text CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL ,
`message_object` mediumtext CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL ,
`reply_to` text CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL ,
`charset` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL ,
`created_at` datetime NOT NULL ,
`attempts` int(11) NULL DEFAULT NULL ,
`last_attempt_time` datetime NULL DEFAULT NULL ,
`sent_time` datetime NULL DEFAULT NULL ,
PRIMARY KEY (`id`),
INDEX `idx_queue_sent_time` (`sent_time`) USING BTREE ,
INDEX `idx_queue_subject` (`subject`) USING BTREE
)
ENGINE=InnoDB
DEFAULT CHARACTER SET=utf8 COLLATE=utf8_unicode_ci
AUTO_INCREMENT=1
ROW_FORMAT=COMPACT
;
public function actionSpooler()
{
$spool = new DbSpool();
$transport = \Swift_SpoolTransport::newInstance($spool);
$mailer = \Swift_Mailer::newInstance($transport);
$message = \Swift_Message::newInstance('Subject')
->setFrom(array('info@example.com' => 'John Doe'))
->setTo(array('to@example.com'))
->setBody('<p>spool message</p>');
$result = $mailer->send($message);
//OR
$message = Yii::$app->mailer->compose()
->setFrom('info@example.com')
->setTo('to@example.com')
->setSubject('Subject')
->setTextBody('<p>spool message</p>');
$message->send();
}
public function actionSend()
{
$messageLimit = 10;
$timeLimit = 0;
$spool = new DbSpool();
//$transportReal = \Swift_MailTransport::newInstance();
$transportReal = \Swift_SmtpTransport::newInstance(
"smtp.gmail.com",
"465",
"ssl"
)
->setUsername("username")
->setPassword("password");
$spool->setMessageLimit($messageLimit);
$spool->setTimeLimit($timeLimit);
$sent = $spool->flushQueue($transportReal);
echo sprintf('sent %s emails', $sent);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment