如果本文图片显示不出来,请看我的博客 http://vb2005xu.iteye.com/blog/2114518
近日在对charsen的修改版上进行了再次的修改与调整,对原版的qee v3 做了更多的bug修改,目前经过测试基本可以使用,虽然还有一些坑,但是代码量始终只有那么一点,填补起来应该很方便,加上qee-v3确实有些技术知识点可供学习..
因 为 qee-v3 只给出了一些极简单的库支持,而邮件功能在项目开发过程中又是不可或缺的部分,所以就集成了swiftmailer, 这个库在国外的知名度蛮高的,在性能上比phpmailer要好不少,尤其是对大附件的支持上.唯独的缺陷就是中文文档太少,为了方便使用,故对其做了如 下封装....
如果非要对这个封装代码起个名字,那就叫做 qser-mailer 吧
先给出一个如何使用的demo,个人感觉还是比较方便和简单的
- <?php
- namespace 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__));
- <span style="color: #ff6600;"><strong>$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('尼玛')));
- });
- </strong></span>
- // 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 (!emptyempty($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 (!emptyempty($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' => '易结网'),
),
),
来源:oschina
链接:https://my.oschina.net/u/1174918/blog/312025