Browse Source

Merge pull request #1683 from Ragazzo/mail_event

Mail events before/after
tags/2.0.0-beta
Qiang Xue 11 years ago
parent
commit
1361bd3c7f
  1. 35
      framework/yii/base/MailEvent.php
  2. 48
      framework/yii/mail/BaseMailer.php
  3. 12
      tests/unit/framework/mail/BaseMailerTest.php

35
framework/yii/base/MailEvent.php

@ -0,0 +1,35 @@
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\base;
/**
* ActionEvent represents the event parameter used for an action event.
*
* By setting the [[isValid]] property, one may control whether to continue running the action.
*
* @author Mark Jebri <mark.github@yandex.ru>
* @since 2.0
*/
class MailEvent extends Event
{
/**
* @var \yii\mail\MessageInterface mail message being send
*/
public $message;
/**
* @var boolean if message send was successful
*/
public $isSuccessful;
/**
* @var boolean whether to continue send. Event handlers of
* [[\yii\mail\BaseMailer::EVENT_BEFORE_SEND]] may set this property to decide whether
* to continue send or not.
*/
public $isValid = true;
}

48
framework/yii/mail/BaseMailer.php

@ -12,6 +12,7 @@ use yii\base\Component;
use yii\base\InvalidConfigException; use yii\base\InvalidConfigException;
use yii\base\ViewContextInterface; use yii\base\ViewContextInterface;
use yii\web\View; use yii\web\View;
use yii\base\MailEvent;
/** /**
* BaseMailer serves as a base class that implements the basic functions required by [[MailerInterface]]. * BaseMailer serves as a base class that implements the basic functions required by [[MailerInterface]].
@ -28,6 +29,16 @@ use yii\web\View;
*/ */
abstract class BaseMailer extends Component implements MailerInterface, ViewContextInterface abstract class BaseMailer extends Component implements MailerInterface, ViewContextInterface
{ {
/**
* @event \yii\base\MailEvent an event raised right before send.
* You may set [[\yii\base\MailEvent::isValid]] to be false to cancel the send.
*/
const EVENT_BEFORE_SEND = 'beforeSend';
/**
* @event \yii\base\MailEvent an event raised right after send.
*/
const EVENT_AFTER_SEND = 'afterSend';
/** /**
* @var string directory containing view files for this email messages. * @var string directory containing view files for this email messages.
* This can be specified as an absolute path or path alias. * This can be specified as an absolute path or path alias.
@ -206,6 +217,10 @@ abstract class BaseMailer extends Component implements MailerInterface, ViewCont
*/ */
public function send($message) public function send($message)
{ {
if (!$this->beforeSend($message)) {
return false;
}
$address = $message->getTo(); $address = $message->getTo();
if (is_array($address)) { if (is_array($address)) {
$address = implode(', ', array_keys($address)); $address = implode(', ', array_keys($address));
@ -213,10 +228,12 @@ abstract class BaseMailer extends Component implements MailerInterface, ViewCont
Yii::info('Sending email "' . $message->getSubject() . '" to "' . $address . '"', __METHOD__); Yii::info('Sending email "' . $message->getSubject() . '" to "' . $address . '"', __METHOD__);
if ($this->useFileTransport) { if ($this->useFileTransport) {
return $this->saveMessage($message); $isSuccessful = $this->saveMessage($message);
} else { } else {
return $this->sendMessage($message); $isSuccessful = $this->sendMessage($message);
} }
$this->afterSend($message, $isSuccessful);
return $isSuccessful;
} }
/** /**
@ -297,4 +314,31 @@ abstract class BaseMailer extends Component implements MailerInterface, ViewCont
{ {
return Yii::getAlias($this->viewPath) . DIRECTORY_SEPARATOR . $view; return Yii::getAlias($this->viewPath) . DIRECTORY_SEPARATOR . $view;
} }
/**
* This method is invoked right before mail send.
* You may override this method to do last-minute preparation for the message.
* If you override this method, please make sure you call the parent implementation first.
* @param MessageInterface $message
*/
public function beforeSend($message)
{
$event = new MailEvent(['message' => $message]);
$this->trigger(self::EVENT_BEFORE_SEND, $event);
return $event->isValid;
}
/**
* This method is invoked right after mail was send.
* You may override this method to do some postprocessing or logging based on mail send status.
* If you override this method, please make sure you call the parent implementation first.
* @param MessageInterface $message
* @param boolean $isSuccessful
*/
public function afterSend($message, $isSuccessful)
{
$event = new MailEvent(['message' => $message, 'isSuccessful' => $isSuccessful]);
$this->trigger(self::EVENT_AFTER_SEND, $event);
}
} }

12
tests/unit/framework/mail/BaseMailerTest.php

@ -230,6 +230,17 @@ class BaseMailerTest extends TestCase
$this->assertTrue(is_file($file)); $this->assertTrue(is_file($file));
$this->assertEquals($message->toString(), file_get_contents($file)); $this->assertEquals($message->toString(), file_get_contents($file));
} }
public function testBeforeSendEvent()
{
$message = new Message();
$mailerMock = $this->getMockBuilder('yiiunit\framework\mail\Mailer')->setMethods(['beforeSend','afterSend'])->getMock();
$mailerMock->expects($this->once())->method('beforeSend')->with($message)->will($this->returnValue(true));
$mailerMock->expects($this->once())->method('afterSend')->with($message,true);
$mailerMock->send($message);
}
} }
/** /**
@ -243,6 +254,7 @@ class Mailer extends BaseMailer
protected function sendMessage($message) protected function sendMessage($message)
{ {
$this->sentMessages[] = $message; $this->sentMessages[] = $message;
return true;
} }
} }

Loading…
Cancel
Save