[置顶] swiftmailer 的快捷助手 qser-mailer

来源:互联网 发布:传智播客java课程表 编辑:程序博客网 时间:2024/05/24 01:51

近日在对charsen的修改版上进行了再次的修改与调整,对原版的qee v3 做了更多的bug修改,目前经过测试基本可以使用,虽然还有一些坑,但是代码量始终只有那么一点,填补起来应该很方便,加上qee-v3确实有些技术知识点可供学习..

因为 qee-v3 只给出了一些极简单的库支持,而邮件功能在项目开发过程中又是不可或缺的部分,所以就集成了swiftmailer, 这个库在国外的知名度蛮高的,在性能上比phpmailer要好不少,尤其是对大附件的支持上.唯独的缺陷就是中文文档太少,为了方便使用,故对其做了如下封装....

如果非要对这个封装代码起个名字,那就叫做 qser-mailer 吧

先给出一个如何使用的demo,个人感觉还是比较方便和简单的

<?phpnamespace qser\app\actions;use qeephp\mvc\BaseAction;use qeephp\Config;use qeephp\tools\Logger;use qeephp\storage\mysql\DataSource;use qeephp\storage\Meta;use qser\app\models\Post;use qser\libraries\Validator;use qser\libraries\PinyinLib;class IndexAction extends BaseAction{/**     * @var mysql\DataSource     */    private $_ds;    private $_handle;    function execute()    {    try{            $post5 = Post::find_one(5);            }        catch( \Exception $ex )        {            Logger::instance('test')->fatal($ex);        }        Logger::instance('test')->debug($post5);        dump('indexAction',PinyinLib::topinyin("我爱北京天门"));        ///dump($this->app);        // $value = 7;        // $result = Validator::validateBatch($value, array(array('is_int'),array('between', 2, 6)));        // var_dump($result);        $this->view(array('action' => 'a', __DIR__));$email = array('vb@qq.com');$content = $this->result;$this->app->tool('mail')->mailer->send(function($message) use($email,$content){$text = $content->execute();$message->to($email)->subject('qeev3 测试邮件');$message->setBody($text, 0 ? 'text/plain' : 'text/html');$message->attachData($text,'runtest',array('as' => $message->encodeAttachmentName('啥都好说')));$message->attach(MYAPP_SRC_PATH . '/tmp/tests.log',array('as' => $message->encodeAttachmentName('尼玛')));});//dump($this->app->tool('mail')->mailer , $email);//              //dump( $post5 );        /*$sql = 'show tables';         $result = $this->_ds->execute($sql);         dump($result,$sql); // out resource         $result = $this->_ds->find_one('post',null);         dump($result,'post_one');         $result = $this->_ds->find('post',null)->fetch();         dump($result,'fetch');         $result = $this->_ds->find('post',null)->sort('post_id DESC')->fetch();         dump($result,'fetch by sort');*/         //$result = $this->_ds->find('post',null)->fetch_all();        // dump($result,'fetch_all');        //        //$meta = new Meta('qser\\app\\models\\Revision');        //$meta = array();       // dump( $meta ,'meta');    }    protected function __before_execute()    {    // init resource         // $this->_ds = new DataSource( Config::get('storage.domains.default') );         // $this->_ds->connect();         // $this->_ds->set_logger(Logger::instance('test'));         // $this->_handle = $this->_ds->handle();         // $this->_ds->execute('SET AUTOCOMMIT=0');         // $this->_ds->execute('START TRANSACTION');         // foreach (self::post_recordset() as $post)         // {         // $this->_ds->insert('qser_posts', $post);         // }         // $this->_ds->execute('COMMIT');         // $this->_ds->execute('SET AUTOCOMMIT=1');        return true;    }    // test func    static function post_recordset($begin_post_id = 31)    {        static $authors = array('dualface', 'liaoyulei', 'lownr', 'dox', 'quietlife');        $recordset = array();        for ($post_id = $begin_post_id; $post_id < $begin_post_id + 10; $post_id++)        {            $author = $authors[mt_rand(0, count($authors) - 1)];            $recordset[$post_id] = array(                'post_id' => $post_id,                'title' => 'post ' . $post_id,                'author' => $author,                'click_count' => mt_rand(1, 999),            );        }        return $recordset;    }    static function revisions_recordset($begin_post_id = 1)    {        $recordset = array();        $created = time();        for ($post_id = $begin_post_id; $post_id < $begin_post_id + 5; $post_id++)        {            $num_rev = mt_rand(1, 5);            for ($i = 0; $i < $num_rev; $i++)            {                $recordset[] = array(                    'post_id' => $post_id,                    'body'    => sprintf('post %u rev %u', $post_id, $i),                    'created' => $created,                );            }        }        return $recordset;    }}

 

测试的结果蛮好,如图所示,中文附件名字也能正常显示,灰常给力是不是


------------------------------------------------------------
所有代码如下所示:

<?php namespace qser\app\tools;use qeephp\mvc\App;use qser\libraries\Mail\Mailer;class MailTool{/**     * 当前请求     *     * @var Mailer     */    public $mailer;/** * Create a new Mailer instance. * * @param App $app * @param array $config */public function __construct(App $app, array $config) {$this->mailer = new Mailer($config);}}

 

<?php namespace qser\libraries\Mail;if (!defined('SWIFT_INIT_LOADED')) {    require ROOT_PATH . '/packages/swiftmailer/lib/swift_init.php';}use Swift_Mailer;use Swift_Message;use qeephp\tools\Logger;use qser\libraries\Mail\Provider;class Mailer {/** * The Swift Mailer instance. * * @var \Swift_Mailer */protected $swift;/** * The global from address and name. * * @var array */protected $from;/** * The log writer instance. * * @var ILogger */protected $logger;/** * Indicates if the actual sending is disabled. * * @var bool */protected $pretending = false;/** * Array of failed recipients. * * @var array */protected $failedRecipients = array();/** * Create a new Mailer instance. * * @param  array  $config * @return void */public function __construct(array  $config){$this->swift = Provider::registerSwiftMailer($config);$logger = val($config, 'logger' , false);        if ($logger)        {            $this->setLogger(Logger::instance($logger));        }$from = val($config, 'from' , false);if (is_array($from) && isset($from['address'])){$this->alwaysFrom($from['address'], $from['name']);}// Here we will determine if the mailer should be in "pretend" mode for this// environment, which will simply write out e-mail to the logs instead of// sending it over the web, which is useful for local dev environments.$pretend = val($config, 'pretend' , false);$this->pretend($pretend);}/** * Set the global from address and name. * * @param  string  $address * @param  string  $name * @return void */public function alwaysFrom($address, $name = null){$this->from = compact('address', 'name');}/** * Send a new message. * * @param  callback  $callback * @return int */public function send($callback){$message = $this->createMessage();$data['message'] = $message;if ($callback && is_callable($callback)){call_user_func($callback,$message);}else{throw new \InvalidArgumentException('Invalid mail send callback.');}$message = $message->getSwiftMessage();return $this->sendSwiftMessage($message);}/** * Send a Swift Message instance. * * @param  \Swift_Message  $message * @return int */protected function sendSwiftMessage($message){if ( !$this->pretending){return $this->swift->send($message, $this->failedRecipients);}elseif (isset($this->logger)){$this->logMessage($message);return 1;}}/** * Log that a message was sent. * * @param  \Swift_Message  $message * @return void */protected function logMessage($message){$emails = implode(', ', array_keys((array) $message->getTo()));$this->logger->info("Pretending to mail message to: {$emails}");}/** * Create a new message instance. * * @return Message */protected function createMessage(){$message = new Message(new Swift_Message);// If a global from address has been specified we will set it on every message// instances so the developer does not have to repeat themselves every time// they create a new message. We will just go ahead and push the address.if (isset($this->from['address'])){$message->from($this->from['address'], $this->from['name']);}return $message;}/** * Tell the mailer to not really send messages. * * @param  bool  $value * @return void */public function pretend($value = true){$this->pretending = $value;}/** * Get the Swift Mailer instance. * * @return \Swift_Mailer */public function getSwiftMailer(){return $this->swift;}/** * Get the array of failed recipients. * * @return array */public function failures(){return $this->failedRecipients;}/** * Set the log writer instance. * * @param  Logger  $logger */public function setLogger(Logger $logger){$this->logger = $logger;}}

 

<?php namespace qser\libraries\Mail;use Swift_Mailer;use Swift_SmtpTransport as SmtpTransport;use Swift_MailTransport as MailTransport;use Swift_SendmailTransport as SendmailTransport;class Provider{/** * Register the Swift Mailer instance. * * @return \Swift_Mailer */public static function registerSwiftMailer($config){$self = new static();return new Swift_Mailer( $self->registerSwiftTransport($config) );}/** * Register the Swift Transport instance. * * @param  array  $config * @return void * * @throws \InvalidArgumentException */protected function registerSwiftTransport($config){switch ($config['driver']){case 'smtp':return $this->registerSmtpTransport($config);case 'sendmail':return $this->registerSendmailTransport($config);case 'mail':return $this->registerMailTransport($config);default:throw new \InvalidArgumentException('Invalid mail driver.');}}/** * Register the SMTP Swift Transport instance. * * @param  array  $config * @return void */protected function registerSmtpTransport($config){// The Swift SMTP transport instance will allow us to use any SMTP backend// for delivering mail such as Sendgrid, Amazon SMS, or a custom server// a developer has available. We will just pass this configured host.$transport = SmtpTransport::newInstance($config['host'], $config['port']);if (!empty($config['encryption'])){$transport->setEncryption($config['encryption']);}// Once we have the transport we will check for the presence of a username// and password. If we have it we will set the credentials on the Swift// transporter instance so that we'll properly authenticate delivery.if (!empty($config['username'])){$transport->setUsername($config['username']);$transport->setPassword($config['password']);}return $transport;}/** * Register the Sendmail Swift Transport instance. * * @param  array  $config * @return void */protected function registerSendmailTransport($config){return SendmailTransport::newInstance($config['sendmail']);}/** * Register the Mail Swift Transport instance. * * @param  array  $config * @return void */protected function registerMailTransport($config){return MailTransport::newInstance();}/** * Get the services provided by the provider. * * @return array */public function provides(){return array('mailer', 'swift.mailer', 'swift.transport');}}

 

<?php namespace qser\libraries\Mail;use Swift_Image;use Swift_Attachment;class Message {/** * The Swift Message instance. * * @var \Swift_Message */protected $swift;/** * Create a new message instance. * * @param  \Swift_Message  $swift * @return void */public function __construct($swift){$this->swift = $swift;}/** * Add a "from" address to the message. * * @param  string  $address * @param  string  $name * @return \qser\libraries\Mail\Message */public function from($address, $name = null){$this->swift->setFrom($address, $name);return $this;}/** * Set the "sender" of the message. * * @param  string  $address * @param  string  $name * @return \qser\libraries\Mail\Message */public function sender($address, $name = null){$this->swift->setSender($address, $name);return $this;}/** * Set the "return path" of the message. * * @param  string  $address * @return \qser\libraries\Mail\Message */public function returnPath($address){$this->swift->setReturnPath($address);return $this;}/** * Add a recipient to the message. * * @param  string|array  $address * @param  string  $name * @return \qser\libraries\Mail\Message */public function to($address, $name = null){return $this->addAddresses($address, $name, 'To');}/** * Add a carbon copy to the message. * * @param  string  $address * @param  string  $name * @return \qser\libraries\Mail\Message */public function cc($address, $name = null){return $this->addAddresses($address, $name, 'Cc');}/** * Add a blind carbon copy to the message. * * @param  string  $address * @param  string  $name * @return \qser\libraries\Mail\Message */public function bcc($address, $name = null){return $this->addAddresses($address, $name, 'Bcc');}/** * Add a reply to address to the message. * * @param  string  $address * @param  string  $name * @return \qser\libraries\Mail\Message */public function replyTo($address, $name = null){return $this->addAddresses($address, $name, 'ReplyTo');}/** * Add a recipient to the message. * * @param  string|array  $address * @param  string  $name * @param  string  $type * @return \qser\libraries\Mail\Message */protected function addAddresses($address, $name, $type){if (is_array($address)){$this->swift->{"set{$type}"}($address, $name);}else{$this->swift->{"add{$type}"}($address, $name);}return $this;}/** * Set the subject of the message. * * @param  string  $subject * @return \qser\libraries\Mail\Message */public function subject($subject){$this->swift->setSubject($subject);return $this;}/** * Set the message priority level. * * @param  int  $level * @return \qser\libraries\Mail\Message */public function priority($level){$this->swift->setPriority($level);return $this;}/** * 编码附件名称(可用于显示中文附件名) *  * @param  string  $file *  * @return string */public function encodeAttachmentName($name){return "=?UTF-8?B?" . base64_encode($name) . "?=";}/** * Attach a file to the message. * * @param  string  $file * @param  array   $options * @return \qser\libraries\Mail\Message */public function attach($file, array $options = array()){$attachment = $this->createAttachmentFromPath($file);return $this->prepAttachment($attachment, $options);}/** * Create a Swift Attachment instance. * * @param  string  $file * @return \Swift_Attachment */protected function createAttachmentFromPath($file){return Swift_Attachment::fromPath($file);}/** * Attach in-memory data as an attachment. * * @param  string  $data * @param  string  $name * @param  array   $options * @return \qser\libraries\Mail\Message */public function attachData($data, $name, array $options = array()){$attachment = $this->createAttachmentFromData($data, $name);return $this->prepAttachment($attachment, $options);}/** * Create a Swift Attachment instance from data. * * @param  string  $data * @param  string  $name * @return \Swift_Attachment */protected function createAttachmentFromData($data, $name){return Swift_Attachment::newInstance($data, $name);}/** * Embed a file in the message and get the CID. * * @param  string  $file * @return string */public function embed($file){return $this->swift->embed(Swift_Image::fromPath($file));}/** * Embed in-memory data in the message and get the CID. * * @param  string  $data * @param  string  $name * @param  string  $contentType * @return string */public function embedData($data, $name, $contentType = null){$image = Swift_Image::newInstance($data, $name, $contentType);return $this->swift->embed($image);}/** * Prepare and attach the given attachment. * * @param  \Swift_Attachment  $attachment * @param  array  $options * @return \qser\libraries\Mail\Message */protected function prepAttachment($attachment, $options = array()){// First we will check for a MIME type on the message, which instructs the// mail client on what type of attachment the file is so that it may be// downloaded correctly by the user. The MIME option is not required.if (isset($options['mime'])){$attachment->setContentType($options['mime']);}// If an alternative name was given as an option, we will set that on this// attachment so that it will be downloaded with the desired names from// the developer, otherwise the default file names will get assigned.if (isset($options['as'])){$attachment->setFilename($options['as']);}$this->swift->attach($attachment);return $this;}/** * Get the underlying Swift Message instance. * * @return \Swift_Message */public function getSwiftMessage(){return $this->swift;}/** * Dynamically pass missing methods to the Swift instance. * * @param  string  $method * @param  array   $parameters * @return mixed */public function __call($method, $parameters){$callable = array($this->swift, $method);return call_user_func_array($callable, $parameters);}}

 

 

 


-------- 配置信息如下所示

写道

# Tools 设置
'app.tools' => array(

# mail 工具配置
'mail' => array(
'class' => 'qser\\app\\tools\\MailTool',

'driver' => 'smtp', #Supported: "smtp", "mail", "sendmail"
'host' => 'smtp.qq.com',
'port' => 4650,
'encryption' => 'ssl',
'username' => "noreply@sese.cn",
'password' =>"qwaszyss",
'pretend' => false,#启用此选项,邮件不会真正发送,而是写到日志文件中
'logger' => 'test', #使用日志对象

'from' => array('address' => 'noreply@sese.cn', 'name' => '易结网'),
),

),

 


 

原创粉丝点击