From 449e267fa636681e2f328c745a6e9b0056c67988 Mon Sep 17 00:00:00 2001 From: vanchelo Date: Mon, 7 Sep 2015 23:27:41 +0300 Subject: [PATCH] Support Phalcon 2.0. - PSR-2 - Configuration improvement --- README.md | 60 ++++++++++++++++------- composer.json | 3 ++ src/Mailer.php | 77 ++++++++++++++--------------- src/MailerService.php | 110 ++++++++++++++++++++++-------------------- src/Message.php | 57 ++++++++++++---------- src/helpers.php | 22 +++------ 6 files changed, 181 insertions(+), 148 deletions(-) diff --git a/README.md b/README.md index a00693f..ee3a7b9 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,13 @@ -phalcon-mailer +Phalcon Mailer ============== -[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/vanchelo/phalcon-mailer/trend.png)](https://bitdeli.com/free "Bitdeli Badge") - -Сервис для отправки почты для Phalcon используя Swift Mailer. +Удобная библиотека для отправки Вашей почты в [Phalcon](http://phalconphp.com/). Код заимствован из Laravel 4 и адаптирован под Phalcon. ##Установка C помощью `composer`: -Добавить в файл `composer.json` в секцию `require`: + +Добавить в файл `composer.json` в секцию `require` следующую строку: ``` "vanchelo/phalcon-mailer": "dev-master" ``` @@ -20,7 +19,10 @@ C помощью `composer`: } } ``` -В терминале выполнить команду `composer update` +После этого выполните в терминале команду: +```bash +composer update +``` Инициализация сервиса --------- @@ -34,6 +36,32 @@ $this->di['mailer'] = function() { return $service->mailer(); }; ``` +или с передачей параметров на этапе инициализации сервиса + +```php +/** + * Register Mailer Service + */ +$this->di['mailer'] = function() { + $service = new MailerService([ + 'driver' => 'smtp', // mail, sendmail, smtp + 'host' => 'smtp.email.com', + 'port' => 587, + 'from' => [ + 'address' => 'no-reply@my-domain.com', + 'name' => 'My Cool Company', + ], + 'encryption' => 'tls', + 'username' => 'no-reply@my-domain.com', + 'password' => 'some-strong-password', + 'sendmail' => '/usr/sbin/sendmail -bs', + // Путь используемый для поиска шаблонов писем + 'viewsDir' => __DIR__ . '/../app/views/', // optional + ]); + + return $service->mailer(); +}; +``` Отправка письма --------- @@ -55,27 +83,23 @@ $this->mailer->send('emails/xxx', [ Настройки по умолчанию необходимо прописать в конфигурационном файле вашего приложения config/config.php ```php array( - // Путь используемый для поиска шаблонов писем - 'viewsDir' => __DIR__ . '/../app/views/', - /* ... */ - ), - - 'mail' => array( +return new \Phalcon\Config([ + 'mail' => [ 'driver' => 'smtp', // mail, sendmail, smtp 'host' => 'smtp.email.com', 'port' => 587, - 'from' => array( + 'from' => [ 'address' => 'no-reply@my-domain.com', 'name' => 'My Cool Company' - ), + ], 'encryption' => 'tls', 'username' => 'no-reply@my-domain.com', 'password' => 'some-strong-password', 'sendmail' => '/usr/sbin/sendmail -bs', - ), -)); + // Путь используемый для поиска шаблонов писем + 'viewsDir' => __DIR__ . '/../app/views/', // optional + ], +]); ``` Если будет необходимость, настройки почты можно вынести в отдельный конфигурационный файл diff --git a/composer.json b/composer.json index 17f3ab9..e723633 100644 --- a/composer.json +++ b/composer.json @@ -15,6 +15,9 @@ "swiftmailer/swiftmailer": "~5.3", "jeremeamia/superclosure": "~1.0.1" }, + "require-dev": { + "phalcon/devtools": "~2.0" + }, "autoload": { "psr-4": { "Vanchelo\\Mailer\\": "src/" diff --git a/src/Mailer.php b/src/Mailer.php index 5d759a3..7438b6d 100644 --- a/src/Mailer.php +++ b/src/Mailer.php @@ -1,12 +1,20 @@ -setBody($this->render($view, $data), 'text/html'); } - if (isset($plain)) - { + if (isset($plain)) { $message->addPart($this->render($plain, $data), 'text/plain'); } } @@ -151,19 +157,17 @@ protected function parseView($view) // If the given view is an array with numeric keys, we will just assume that // both a "pretty" and "plain" view were provided, so we will return this // array as is, since must should contain both views with numeric keys. - if (is_array($view) && isset($view[0])) - { + if (is_array($view) && isset($view[0])) { return $view; } // If the view is an array, but doesn't contain numeric keys, we will assume // the the views are being explicitly specified and will extract them via // named keys instead, allowing the developers to use one or the other. - elseif (is_array($view)) - { + elseif (is_array($view)) { return [ array_get($view, 'html'), - array_get($view, 'text') + array_get($view, 'text'), ]; } @@ -177,7 +181,7 @@ protected function parseView($view) * * @return int */ - public function sendSwiftMessage($message) + public function sendSwiftMessage(Swift_Message $message) { return $this->swift->send($message); } @@ -193,8 +197,7 @@ public function sendSwiftMessage($message) */ protected function callMessageBuilder($callback, $message) { - if ($callback instanceof Closure) - { + if ($callback instanceof Closure) { return call_user_func($callback, $message); } @@ -213,8 +216,7 @@ protected function createMessage() // 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'])) - { + if (isset($this->from['address'])) { $message->from($this->from['address'], $this->from['name']); } @@ -225,7 +227,7 @@ protected function createMessage() * Render the given view * * @param string $view - * @param array $data + * @param array $data * * @return string */ @@ -277,7 +279,7 @@ public function setSwiftMailer($swift) */ protected function buildQueueCallable($callback) { - if ( ! $callback instanceof Closure) return $callback; + if (!$callback instanceof Closure) return $callback; return serialize(new SerializableClosure($callback)); } @@ -286,7 +288,7 @@ protected function buildQueueCallable($callback) * Handle a queued e-mail message job * * @param \Phalcon\Queue\Beanstalk\Job $job - * @param array $data + * @param array $data */ public function handleQueuedMessage($job, $data) { @@ -304,8 +306,7 @@ public function handleQueuedMessage($job, $data) */ protected function getQueuedCallable(array $data) { - if (str_contains($data['callback'], 'SerializableClosure')) - { + if (str_contains($data['callback'], 'SerializableClosure')) { return with(unserialize($data['callback']))->getClosure(); } @@ -315,8 +316,8 @@ protected function getQueuedCallable(array $data) /** * Queue a new e-mail message for sending * - * @param string|array $view - * @param array $data + * @param string|array $view + * @param array $data * @param \Closure|string $callback * * @return mixed @@ -332,7 +333,7 @@ public function queue($view, array $data, $callback) 'data' => [ 'view' => $view, 'data' => $data, - 'callback' => $callback + 'callback' => $callback, ], ])); } @@ -350,7 +351,7 @@ public function failures() /** * Set the Beanstalk queue instance * - * @param \Phalcon\Queue\Beanstalk $queue + * @param \Phalcon\Queue\Beanstalk $queue * * @return self */ @@ -364,9 +365,9 @@ public function setQueue(Beanstalk $queue) /** * Sets the dependency injector * - * @param \Phalcon\DiInterface $dependencyInjector + * @param mixed $dependencyInjector */ - public function setDI($dependencyInjector) + public function setDI(DiInterface $dependencyInjector) { $this->di = $dependencyInjector; } @@ -374,7 +375,7 @@ public function setDI($dependencyInjector) /** * Returns the internal dependency injector * - * @return \Phalcon\DiInterface + * @return DiInterface */ public function getDI() { diff --git a/src/MailerService.php b/src/MailerService.php index 4536780..64689ed 100644 --- a/src/MailerService.php +++ b/src/MailerService.php @@ -1,4 +1,6 @@ -di->has('config')) { + throw new \RuntimeException('Correct config for Mailer is not provided!'); + } + + $this->config = $config ?: $this->di['config']->mail->toArray(); + $this->registerSwiftMailer(); $this->registerView(); } @@ -32,10 +52,9 @@ public function mailer() $this->setMailerDependencies($mailer); - $from = $this->di['config']->mail->from->toArray(); + $from = $this->config['from']; - if (is_array($from) && isset($from['address'])) - { + if (is_array($from) && isset($from['address'])) { $mailer->alwaysFrom($from['address'], $from['name']); } @@ -44,20 +63,15 @@ public function mailer() /** * Register the Swift Mailer instance. - * - * @return void */ protected function registerSwiftMailer() { - $config = $this->di['config']->mail->toArray(); - - $this->registerSwiftTransport($config); + $this->registerSwiftTransport($this->config); // Once we have the transporter registered, we will register the actual Swift // mailer instance, passing in the transport instances, which allows us to // override this transporter instances during app start-up if necessary. - $this->di['swift.mailer'] = function () - { + $this->di['swift.mailer'] = function () { return new Swift_Mailer($this->di['swift.transport']); }; } @@ -65,14 +79,15 @@ protected function registerSwiftMailer() /** * Register the Swift Transport instance. * - * @param array $config - * - * @return void + * @param array $config */ - protected function registerSwiftTransport($config) + protected function registerSwiftTransport(array $config) { - switch ($config['driver']) - { + if (!isset($config['driver'])) { + throw new \InvalidArgumentException('Please set "driver" for Mailer!'); + } + + switch ($config['driver']) { case 'smtp': return $this->registerSmtpTransport($config); @@ -90,31 +105,32 @@ protected function registerSwiftTransport($config) /** * Register the SMTP Swift Transport instance. * - * @param array $config + * @param array $config * - * @return void + * return null */ - protected function registerSmtpTransport($config) + protected function registerSmtpTransport(array $config) { - $this->di['swift.transport'] = function () use ($config) - { + $this->di['swift.transport'] = function () use ($config) { extract($config); + if (!isset($host, $port)) { + throw new \InvalidArgumentException('Please set "host" and "port" for Mailer!'); + } + // 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($host, $port); - if (isset($encryption)) - { + if (isset($encryption)) { $transport->setEncryption($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 (isset($username)) - { + if (isset($username, $password)) { $transport->setUsername($username); $transport->setPassword($password); @@ -127,27 +143,21 @@ protected function registerSmtpTransport($config) /** * Register the Sendmail Swift Transport instance. * - * @param array $config - * - * @return void + * @param array $config */ - protected function registerSendmailTransport($config) + protected function registerSendmailTransport(array $config) { - $this->di['swift.transport'] = function () use ($config) - { + $this->di['swift.transport'] = function () use ($config) { return SendmailTransport::newInstance($config['sendmail']); }; } /** * Register the Mail Swift Transport instance. - * - * @return void */ protected function registerMailTransport() { - $this->di['swift.transport'] = function () - { + $this->di['swift.transport'] = function () { return MailTransport::newInstance(); }; } @@ -157,20 +167,19 @@ protected function registerMailTransport() */ protected function registerView() { - if ($this->di->has('view')) - { - $this->di['mailer.view'] = function () - { + if ($this->di->has('view')) { + $this->di['mailer.view'] = function () { return $this->di->get('view'); }; - } - else - { - $this->di['mailer.view'] = function () - { + } else { + $this->di['mailer.view'] = function () { + if (!isset($this->config['viewsDir'])) { + throw new \InvalidArgumentException('Invalid views dir!'); + } + $view = new SimpleView; - $view->setViewsDir($this->config->application->viewsDir); + $view->setViewsDir($this->config['viewsDir']); return $view; }; @@ -181,15 +190,12 @@ protected function registerView() * Set a few dependencies on the mailer instance. * * @param Mailer $mailer - * - * @return void */ - protected function setMailerDependencies($mailer) + protected function setMailerDependencies(Mailer $mailer) { $mailer->setDI($this->di); - if ($this->di->has('queue')) - { + if ($this->di->has('queue')) { $mailer->setQueue($this->di['queue']); } } diff --git a/src/Message.php b/src/Message.php index b01520a..0826bea 100644 --- a/src/Message.php +++ b/src/Message.php @@ -1,9 +1,20 @@ -swift = $swift; } @@ -26,8 +37,8 @@ public function __construct($swift) /** * Add a "from" address to the message. * - * @param string $address - * @param string $name + * @param string $address + * @param string $name * * @return Message */ @@ -70,8 +81,8 @@ public function returnPath($address) /** * Add a recipient to the message. * - * @param string|array $address - * @param string $name + * @param string|array $address + * @param string $name * * @return Message */ @@ -123,18 +134,16 @@ public function replyTo($address, $name = null) * Add a recipient to the message. * * @param string|array $address - * @param string $name + * @param string $name + * @param string $type * * @return Message */ protected function addAddresses($address, $name, $type) { - if (is_array($address)) - { + if (is_array($address)) { $this->swift->{"set{$type}"}($address, $name); - } - else - { + } else { $this->swift->{"add{$type}"}($address, $name); } @@ -173,7 +182,7 @@ public function priority($level) * Attach a file to the message. * * @param string $file - * @param array $options + * @param array $options * * @return Message */ @@ -201,7 +210,7 @@ protected function createAttachmentFromPath($file) * * @param string $data * @param string $name - * @param array $options + * @param array $options * * @return Message */ @@ -257,25 +266,23 @@ public function embedData($data, $name, $contentType = null) * Prepare and attach the given attachment. * * @param Swift_Attachment $attachment - * @param array $options + * @param array $options * * @return Message */ - protected function prepAttachment($attachment, $options = []) + protected function prepAttachment(Swift_Attachment $attachment, array $options = []) { // 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'])) - { + 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'])) - { + if (isset($options['as'])) { $attachment->setFilename($options['as']); } @@ -298,14 +305,12 @@ public function getSwiftMessage() * Dynamically pass missing methods to the Swift instance. * * @param string $method - * @param array $parameters + * @param array $parameters * * @return mixed */ - public function __call($method, $parameters) + public function __call($method, array $parameters) { - $callable = [$this->swift, $method]; - - return call_user_func_array($callable, $parameters); + return call_user_func_array([$this->swift, $method], $parameters); } } diff --git a/src/helpers.php b/src/helpers.php index 1b7d078..14230f4 100644 --- a/src/helpers.php +++ b/src/helpers.php @@ -1,16 +1,14 @@