swiftmailer 的快捷助手 qser-mailer_PHP_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > PHP > swiftmailer 的快捷助手 qser-mailer

swiftmailer 的快捷助手 qser-mailer

 2014/9/10 12:39:49  vb2005xu  程序员俱乐部  我要评论(0)
  • 摘要:近日在对charsen的修改版上进行了再次的修改与调整,对原版的qeev3做了更多的bug修改,目前经过测试基本可以使用,虽然还有一些坑,但是代码量始终只有那么一点,填补起来应该很方便,加上qee-v3确实有些技术知识点可供学习..因为qee-v3只给出了一些极简单的库支持,而邮件功能在项目开发过程中又是不可或缺的部分,所以就集成了swiftmailer,这个库在国外的知名度蛮高的,在性能上比phpmailer要好不少,尤其是对大附件的支持上.唯独的缺陷就是中文文档太少,为了方便使用
  • 标签:

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

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

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

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

class="php" name="code"><?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__));
		
		$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' => '易结网'),
),

),

?


?

  • 大小: 61.4 KB
  • 查看图片附件
  • 相关文章
发表评论
用户名: 匿名