├── tests └── .gitkeep ├── .gitignore ├── composer.json ├── LICENSE.md ├── CHANGELOG.md ├── README.md └── src ├── Manager.php └── Message.php /tests/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | vendor 3 | composer.lock -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "phalcon-ext/mailer", 3 | "type": "library", 4 | "description": "Mailer component as wrapper over SwiftMailer for Phalcon.", 5 | "keywords": ["mailer", "phalcon", "phalcon-ext", "phalcon-mailer"], 6 | "minimum-stability": "stable", 7 | "license": "MIT", 8 | "authors": [ 9 | { 10 | "name": "Stanislav Kiryukhin", 11 | "email": "korsar.zn@gmail.com", 12 | "role": "Founder and project lead" 13 | } 14 | ], 15 | "require": { 16 | "php": ">=5.4.0", 17 | "swiftmailer/swiftmailer": "^5.4 || ^6.0.0" 18 | }, 19 | "autoload": { 20 | "psr-4": { 21 | "Phalcon\\Ext\\Mailer\\": "src/" 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017-2021 Stanislav Kiryukhin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG 2 | 3 | ## v3.0.0 (2021-02-24) 4 | - Fix compatibility with Phalcon 4+ [#13](https://github.com/phalcon-ext/mailer/issues/13) 5 | 6 | ## v2.1.0 (2017-09-30) 7 | - Fix [#7](https://github.com/phalcon-ext/mailer/issues/7) 8 | - Add support `auth_mode` [#6](https://github.com/phalcon-ext/mailer/issues/6) 9 | - Allow composers use Swiftmailer v6 [#8](https://github.com/phalcon-ext/mailer/pull/8) 10 | - Change license LGPL-3.0 to MIT 11 | 12 | ## v2.0.3 (2015-12-18) 13 | - Added method `contentAlternative()` - optionally an alternative text body 14 | - fix [#5](https://github.com/phalcon-ext/mailer/issues/5) 15 | 16 | ## v2.0.2 (2015-03-03) 17 | - fix [#2](https://github.com/phalcon-ext/mailer/issues/2) 18 | 19 | ## v2.0.1 (2014-11-05) 20 | - Changes in the private logic... 21 | - Added protected method `isInitSwiftMailer()` 22 | - Added lazy init `SwiftMailer` 23 | - Added check for the required of dependency injection object 24 | 25 | ## v2.0.0 (2014-10-16) 26 | - rename root namespace `\Phalcon\Mailer` to `\Phalcon\Ext\Mailer` 27 | - remove deprecated method `getMessage()` in class `\Phalcon\Ext\Mailer\Message` 28 | 29 | ## v1.1.0 (2014-10-16) 30 | - added method `getSwiftMessage()` in class `\Phalcon\Mailer\Message` analogue for `getMessage()` 31 | - method `getMessage()` in class `\Phalcon\Mailer\Message` is deprecated (will removed since 2.0.0) 32 | 33 | ## v1.0.2 (2014-09-17) 34 | - fixed bug when you create a message via View (incorrect namespace) 35 | 36 | ## v1.0.1 (2014-09-15) 37 | - fixed bug in the attachment file. 38 | - In `\Phalcon\Mailer\Message`, creation SwiftMailer of instances moved to the DI 39 | 40 | ## v1.0.0 (2014-09-14) 41 | - Release of component :) 42 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Phalcon\Ext\Mailer 2 | ============== 3 | 4 | Mailer wrapper over SwiftMailer for Phalcon. 5 | 6 | ## Installing ## 7 | 8 | Install composer in a common location or in your project: 9 | 10 | curl -s http://getcomposer.org/installer | php 11 | 12 | Create the composer.json file as follows: 13 | 14 | ``` 15 | { 16 | "require": { 17 | "phalcon-ext/mailer": "~2.0" 18 | } 19 | } 20 | ``` 21 | 22 | Run the composer installer: 23 | 24 | ```bash 25 | php composer.phar install 26 | ``` 27 | 28 | Add in your the code 29 | 30 | require_once('vendor/autoload.php'); 31 | 32 | ## Configure ## 33 | 34 | **SMTP** 35 | 36 | ```php 37 | $config = [ 38 | 'driver' => 'smtp', 39 | 'host' => 'smtp.gmail.com', 40 | 'port' => 465, 41 | 'encryption' => 'ssl', 42 | 'username' => 'example@gmail.com', 43 | 'password' => 'your_password', 44 | 'from' => [ 45 | 'email' => 'example@gmail.com', 46 | 'name' => 'YOUR FROM NAME' 47 | ] 48 | ]; 49 | ``` 50 | 51 | > **Warning** 52 | > If you are using GMAIL and get error `...Username and Password not accepted...` or `password incorrect`, 53 | > please using password token ([how get token?](https://support.google.com/accounts/answer/185833)) and fix in configuration 54 | > 55 | > ```php 56 | > ... 57 | > 58 | > 'username' => 'example@gmail.com', 59 | > 'password' => 'your_password_token', 60 | > 61 | > ... 62 | > ``` 63 | 64 | **Sendmail** 65 | 66 | ```php 67 | $config = [ 68 | 'driver' => 'sendmail', 69 | 'sendmail' => '/usr/sbin/sendmail -bs', 70 | 'from' => [ 71 | 'email' => 'example@gmail.com', 72 | 'name' => 'YOUR FROM NAME' 73 | ] 74 | ]; 75 | ``` 76 | 77 | **PHP Mail** 78 | 79 | ```php 80 | $config = [ 81 | 'driver' => 'mail', 82 | 'from' => [ 83 | 'email' => 'example@gmail.com', 84 | 'name' => 'YOUR FROM NAME' 85 | ] 86 | ]; 87 | ``` 88 | 89 | ## Example ## 90 | 91 | ### createMessage() ### 92 | 93 | ```php 94 | $mailer = new \Phalcon\Ext\Mailer\Manager($config); 95 | 96 | $message = $mailer->createMessage() 97 | ->to('example_to@gmail.com', 'OPTIONAL NAME') 98 | ->subject('Hello world!') 99 | ->content('Hello world!'); 100 | 101 | // Set the Cc addresses of this message. 102 | $message->cc('example_cc@gmail.com'); 103 | 104 | // Set the Bcc addresses of this message. 105 | $message->bcc('example_bcc@gmail.com'); 106 | 107 | // Send message 108 | $message->send(); 109 | ``` 110 | 111 | ### createMessageFromView() ### 112 | 113 | > **Warning** 114 | > If you want to use as a template engine VOLT (.volt), 115 | > please setup "view" service according to the official [docs](http://docs.phalconphp.com/en/latest/reference/volt.html#activating-volt) Phalcon 116 | 117 | ```php 118 | /** 119 | * Global viewsDir for current instance Mailer\Manager. 120 | * 121 | * This parameter is OPTIONAL, If it is not specified, 122 | * use DI from "view" service (getViewsDir) 123 | */ 124 | $config['viewsDir'] = __DIR__ . '/views/email/'; 125 | 126 | $mailer = new \Phalcon\Ext\Mailer\Manager($config); 127 | 128 | // view relative to the folder viewsDir (REQUIRED) 129 | $viewPath = 'email/example_message'; 130 | 131 | // Set variables to views (OPTIONAL) 132 | $params [ 133 | 'var1' => 'VAR VALUE 1', 134 | 'var2' => 'VAR VALUE 2', 135 | ... 136 | 'varN' => 'VAR VALUE N', 137 | ]; 138 | 139 | /** 140 | * The local path to the folder viewsDir only this message. (OPTIONAL) 141 | * 142 | * This parameter is OPTIONAL, If it is not specified, 143 | * use global parameter "viewsDir" from configuration. 144 | */ 145 | $viewsDirLocal = __DIR__ . '/views/email/local/'; 146 | 147 | 148 | $message = $mailer->createMessageFromView($viewPath, $params, $viewsDirLocal) 149 | ->to('example_to@gmail.com', 'OPTIONAL NAME') 150 | ->subject('Hello world!'); 151 | 152 | // Set the Cc addresses of this message. 153 | $message->cc('example_cc@gmail.com'); 154 | 155 | // Set the Bcc addresses of this message. 156 | $message->bcc('example_bcc@gmail.com'); 157 | 158 | // Send message 159 | $message->send(); 160 | ``` 161 | 162 | ## Events ## 163 | - mailer:beforeCreateMessage 164 | - mailer:afterCreateMessage 165 | - mailer:beforeSend 166 | - mailer:afterSend 167 | - mailer:beforeAttachFile 168 | - mailer:afterAttachFile 169 | -------------------------------------------------------------------------------- /src/Manager.php: -------------------------------------------------------------------------------- 1 | 7 | * @copyright Copyright (c) 2014-2021 8 | * 9 | * ---------------------------------------------- 10 | * All Rights Reserved. 11 | * ---------------------------------------------- 12 | */ 13 | namespace Phalcon\Ext\Mailer; 14 | 15 | use Phalcon\Config; 16 | use Phalcon\Mvc\View; 17 | use Phalcon\Di\DiInterface; 18 | use Phalcon\Di\Injectable; 19 | use Phalcon\Events\ManagerInterface; 20 | use Phalcon\Events\EventsAwareInterface; 21 | 22 | /** 23 | * Class Manager 24 | */ 25 | class Manager extends Injectable implements EventsAwareInterface 26 | { 27 | const AUTHENTICATION_MODE_CRAM_MD5 = 'CRAM-MD5'; 28 | const AUTHENTICATION_MODE_LOGIN = 'LOGIN'; 29 | const AUTHENTICATION_MODE_NTLM = 'NTLM'; 30 | const AUTHENTICATION_MODE_PLAIN = 'PLAIN'; 31 | const AUTHENTICATION_MODE_OAUTH = 'XOAUTH2'; 32 | 33 | const ENCRYPTION_NONE = ''; 34 | const ENCRYPTION_SSL = 'ssl'; 35 | const ENCRYPTION_TLS = 'tls'; 36 | 37 | /** 38 | * @var ManagerInterface 39 | */ 40 | protected $eventsManager; 41 | 42 | /** 43 | * @var array 44 | */ 45 | protected $config = []; 46 | 47 | /** 48 | * @var \Swift_Transport 49 | */ 50 | protected $transport; 51 | 52 | /** 53 | * @var \Swift_Mailer 54 | */ 55 | protected $mailer; 56 | 57 | /** 58 | * @var \Phalcon\Mvc\View\Simple 59 | */ 60 | protected $view; 61 | 62 | /** 63 | * Create a new MailerManager component using $config for configuring 64 | * 65 | * @param array $config 66 | */ 67 | public function __construct(array $config) 68 | { 69 | $this->configure($config); 70 | } 71 | 72 | /** 73 | * Returns the internal event manager 74 | * @return ManagerInterface 75 | */ 76 | public function getEventsManager(): ?ManagerInterface { 77 | return $this->eventsManager; 78 | } 79 | 80 | /** 81 | * Sets the events manager 82 | * @return void 83 | */ 84 | public function setEventsManager(ManagerInterface $eventsManager): void { 85 | $this->eventsManager = $eventsManager; 86 | } 87 | 88 | /** 89 | * Returns the internal dependency injector 90 | * 91 | * @return \Phalcon\DiInterface 92 | */ 93 | public function getDI(): DiInterface 94 | { 95 | if (!($di = parent::getDI()) && !($di instanceof DiInterface)) { 96 | throw new \RuntimeException('A dependency injection object is required to access internal services'); 97 | } 98 | 99 | return $di; 100 | } 101 | 102 | /** 103 | * Create a new Message instance. 104 | * 105 | * Events: 106 | * - mailer:beforeCreateMessage 107 | * - mailer:afterCreateMessage 108 | * 109 | * @return \Phalcon\Ext\Mailer\Message 110 | */ 111 | public function createMessage() 112 | { 113 | $eventsManager = $this->getEventsManager(); 114 | 115 | if ($eventsManager) { 116 | $eventsManager->fire('mailer:beforeCreateMessage', $this); 117 | } 118 | 119 | /** @var $message Message */ 120 | $message = $this->getDI()->get('\Phalcon\Ext\Mailer\Message', [$this]); 121 | 122 | if (($from = $this->getConfig('from'))) { 123 | $message->from($from['email'], isset($from['name']) ? $from['name'] : null); 124 | } 125 | 126 | if ($eventsManager) { 127 | $eventsManager->fire('mailer:afterCreateMessage', $this, [$message]); 128 | } 129 | 130 | return $message; 131 | } 132 | 133 | /** 134 | * Create a new Message instance. 135 | * For the body of the message uses the result of render of view 136 | * 137 | * Events: 138 | * - mailer:beforeCreateMessage 139 | * - mailer:afterCreateMessage 140 | * 141 | * @param string $view 142 | * @param array $params optional 143 | * @param null|string $viewsDir optional 144 | * 145 | * @return \Phalcon\Ext\Mailer\Message 146 | * 147 | * @see \Phalcon\Ext\Mailer\Manager::createMessage() 148 | */ 149 | public function createMessageFromView($view, $params = [], $viewsDir = null) 150 | { 151 | $message = $this->createMessage(); 152 | $message->content($this->renderView($view, $params, $viewsDir), $message::CONTENT_TYPE_HTML); 153 | 154 | return $message; 155 | } 156 | 157 | /** 158 | * Return a {@link \Swift_Mailer} instance 159 | * 160 | * @return \Swift_Mailer 161 | */ 162 | public function getSwift() 163 | { 164 | if (!$this->isInitSwiftMailer()) { 165 | $this->registerSwiftMailer(); 166 | } 167 | 168 | return $this->mailer; 169 | } 170 | 171 | /** 172 | * Normalize IDN domains. 173 | * 174 | * @param $email 175 | * 176 | * @return string 177 | * 178 | * @see \Phalcon\Ext\Mailer\Manager::punycode() 179 | */ 180 | public function normalizeEmail($email) 181 | { 182 | if (preg_match('#[^(\x20-\x7F)]+#', $email)) { 183 | 184 | list($user, $domain) = explode('@', $email); 185 | 186 | return $user . '@' . $this->punycode($domain); 187 | 188 | } else { 189 | return $email; 190 | } 191 | } 192 | 193 | /** 194 | * Configure MailerManager class 195 | * 196 | * @param array $config 197 | * 198 | * @see \Phalcon\Ext\Mailer\Manager::registerSwiftTransport() 199 | * @see \Phalcon\Ext\Mailer\Manager::registerSwiftMailer() 200 | */ 201 | protected function configure(array $config) 202 | { 203 | $this->config = $config; 204 | } 205 | 206 | /** 207 | * Create a new Driver-mail of SwiftTransport instance. 208 | * 209 | * Supported driver-mail: 210 | * - smtp 211 | * - sendmail 212 | * - mail 213 | * 214 | */ 215 | protected function registerSwiftTransport() 216 | { 217 | switch ($driver = $this->getConfig('driver')) { 218 | case 'smtp': 219 | $this->transport = $this->registerTransportSmtp(); 220 | break; 221 | 222 | case 'mail': 223 | $this->transport = $this->registerTransportMail(); 224 | break; 225 | 226 | case 'sendmail': 227 | $this->transport = $this->registerTransportSendmail(); 228 | break; 229 | 230 | default: 231 | throw new \InvalidArgumentException(sprintf('Driver-mail "%s" is not supported', $driver)); 232 | } 233 | } 234 | 235 | /** 236 | * Create a new SmtpTransport instance. 237 | * 238 | * @return \Swift_SmtpTransport 239 | * 240 | * @see \Swift_SmtpTransport 241 | */ 242 | protected function registerTransportSmtp() 243 | { 244 | $config = $this->getConfig(); 245 | 246 | /** @var $transport \Swift_SmtpTransport: */ 247 | $transport = $this->getDI()->get('\Swift_SmtpTransport'); 248 | 249 | if (isset($config['encryption'])) { 250 | $transport->setEncryption($config['encryption']); 251 | } 252 | 253 | if (isset($config['host'])) { 254 | $transport->setHost($config['host']); 255 | } else { 256 | $transport->setHost('localhost'); 257 | } 258 | 259 | if (isset($config['port'])) { 260 | $transport->setPort($config['port']); 261 | } else { 262 | switch ($transport->getEncryption()) { 263 | case static::ENCRYPTION_SSL: 264 | $transport->setPort(465); 265 | break; 266 | 267 | case static::ENCRYPTION_TLS: 268 | $transport->setPort(587); 269 | break; 270 | 271 | default: 272 | $transport->setPort(25); 273 | } 274 | } 275 | 276 | if (isset($config['auth_mode'])) { 277 | $transport->setAuthMode($config['auth_mode']); 278 | } 279 | 280 | if (isset($config['username'])) { 281 | $transport->setUsername($this->normalizeEmail($config['username'])); 282 | } 283 | 284 | if (isset($config['password'])) { 285 | $transport->setPassword($config['password']); 286 | } 287 | 288 | return $transport; 289 | } 290 | 291 | /** 292 | * Get option config or the entire array of config, if the parameter $key is not specified. 293 | * 294 | * @param null $key 295 | * @param null $default 296 | * 297 | * @return string|array 298 | */ 299 | protected function getConfig($key = null, $default = null) 300 | { 301 | if ($key !== null) { 302 | if (isset($this->config[$key])) { 303 | return $this->config[$key]; 304 | } else { 305 | return $default; 306 | } 307 | 308 | } else { 309 | return $this->config; 310 | } 311 | } 312 | 313 | /** 314 | * Convert UTF-8 encoded domain name to ASCII 315 | * 316 | * @param $str 317 | * 318 | * @return string 319 | */ 320 | protected function punycode($str) 321 | { 322 | if (function_exists('idn_to_ascii')) { 323 | return idn_to_ascii($str); 324 | } else { 325 | return $str; 326 | } 327 | } 328 | 329 | /** 330 | * Create a new MailTransport instance. 331 | * 332 | * @return \Swift_MailTransport 333 | * 334 | * @see \Swift_MailTransport 335 | */ 336 | protected function registerTransportMail() 337 | { 338 | return $this->getDI()->get('\Swift_MailTransport'); 339 | } 340 | 341 | /** 342 | * Create a new SendmailTransport instance. 343 | * 344 | * @return \Swift_SendmailTransport 345 | * 346 | * @see \Swift_SendmailTransport 347 | */ 348 | protected function registerTransportSendmail() 349 | { 350 | /** @var $transport \Swift_SendmailTransport */ 351 | $transport = $this->getDI()->get('\Swift_SendmailTransport') 352 | ->setCommand($this->getConfig('sendmail', '/usr/sbin/sendmail -bs')); 353 | 354 | return $transport; 355 | } 356 | 357 | /** 358 | * Register SwiftMailer 359 | * 360 | * @see \Swift_Mailer 361 | */ 362 | protected function registerSwiftMailer() 363 | { 364 | $this->registerSwiftTransport(); 365 | $this->mailer = $this->getDI()->get('\Swift_Mailer', [$this->transport]); 366 | } 367 | 368 | /** 369 | * Renders a view 370 | * 371 | * @param $viewPath 372 | * @param $params 373 | * @param null $viewsDir 374 | * 375 | * @return string 376 | */ 377 | protected function renderView($viewPath, $params, $viewsDir = null) 378 | { 379 | $view = $this->getView(); 380 | 381 | if ($viewsDir !== null) { 382 | $view = clone $view; 383 | $view->setViewsDir($viewsDir); 384 | } 385 | 386 | if (!$view->getViewsDir()) { 387 | throw new \RuntimeException('Please set config property "viewsDir"'); 388 | } 389 | 390 | return $view->render($viewPath, $params); 391 | } 392 | 393 | /** 394 | * Return a {@link \Phalcon\Mvc\View\Simple} instance 395 | * 396 | * @return \Phalcon\Mvc\View\Simple 397 | */ 398 | protected function getView() 399 | { 400 | if ($this->view) { 401 | return $this->view; 402 | } else { 403 | 404 | /** @var $viewApp \Phalcon\Mvc\View */ 405 | $viewApp = $this->getDI()->get('view'); 406 | 407 | if (!($viewsDir = $this->getConfig('viewsDir'))) { 408 | $viewsDir = $viewApp->getViewsDir(); 409 | } 410 | 411 | /** @var $view \Phalcon\Mvc\View\Simple */ 412 | $view = $this->getDI()->get('\Phalcon\Mvc\View\Simple'); 413 | $view->setViewsDir($viewsDir); 414 | 415 | if ($engines = $viewApp->getRegisteredEngines()) { 416 | $view->registerEngines($engines); 417 | } 418 | 419 | return $this->view = $view; 420 | } 421 | } 422 | 423 | /** 424 | * Check init SwiftMailer 425 | * 426 | * @return bool 427 | */ 428 | protected function isInitSwiftMailer() 429 | { 430 | return $this->mailer && $this->transport; 431 | } 432 | 433 | } 434 | -------------------------------------------------------------------------------- /src/Message.php: -------------------------------------------------------------------------------- 1 | 8 | * @copyright Copyright (c) 2014-2021 9 | * 10 | * ---------------------------------------------- 11 | * All Rights Reserved. 12 | * ---------------------------------------------- 13 | */ 14 | namespace Phalcon\Ext\Mailer; 15 | 16 | /** 17 | * Class Message 18 | */ 19 | class Message 20 | { 21 | /** 22 | * content type of PLAIN text. 23 | */ 24 | const CONTENT_TYPE_PLAIN = 'text/plain'; 25 | 26 | /** 27 | * content type HTML text. 28 | */ 29 | const CONTENT_TYPE_HTML = 'text/html'; 30 | 31 | /** 32 | * @var \Phalcon\Ext\Mailer\Manager 33 | */ 34 | protected $manager; 35 | 36 | /** 37 | * @var \Swift_Message 38 | */ 39 | protected $swiftMessage; 40 | 41 | /** 42 | * An array of email which failed send to recipients. 43 | * 44 | * @var array 45 | */ 46 | protected $failedRecipients = []; 47 | 48 | /** 49 | * Create a new Message using $mailer for sending from SwiftMailer 50 | * 51 | * @param Manager $manager 52 | */ 53 | public function __construct(Manager $manager) 54 | { 55 | $this->manager = $manager; 56 | } 57 | 58 | /** 59 | * Set the from address of this message. 60 | * 61 | * You may pass an array of addresses if this message is from multiple people. 62 | * Example: array('receiver@domain.org', 'other@domain.org' => 'A name') 63 | * 64 | * If $name is passed and the first parameter is a string, this name will be 65 | * associated with the address. 66 | * 67 | * @param string|array $email 68 | * @param string|null $name optional 69 | * 70 | * @return $this 71 | * 72 | * @see \Swift_Message::setFrom() 73 | */ 74 | public function from($email, $name = null) 75 | { 76 | $email = $this->normalizeEmail($email); 77 | $this->getSwiftMessage()->setFrom($email, $name); 78 | 79 | return $this; 80 | } 81 | 82 | /** 83 | * Get the from address of this message. 84 | * 85 | * @return string 86 | * 87 | * @see \Swift_Message::getFrom() 88 | */ 89 | public function getFrom() 90 | { 91 | return $this->getSwiftMessage()->getFrom(); 92 | } 93 | 94 | /** 95 | * Set the reply-to address of this message. 96 | * 97 | * You may pass an array of addresses if replies will go to multiple people. 98 | * Example: array('receiver@domain.org', 'other@domain.org' => 'A name') 99 | * 100 | * If $name is passed and the first parameter is a string, this name will be 101 | * associated with the address. 102 | * 103 | * @param string|array $email 104 | * @param string|null $name optional 105 | * 106 | * @return $this 107 | * 108 | * @see \Swift_Message::setReplyTo() 109 | */ 110 | public function replyTo($email, $name = null) 111 | { 112 | $email = $this->normalizeEmail($email); 113 | $this->getSwiftMessage()->setReplyTo($email, $name); 114 | 115 | return $this; 116 | } 117 | 118 | /** 119 | * Get the reply-to address of this message. 120 | * 121 | * @return string 122 | * 123 | * @see \Swift_Message::getReplyTo() 124 | */ 125 | public function getReplyTo() 126 | { 127 | return $this->getSwiftMessage()->getReplyTo(); 128 | } 129 | 130 | /** 131 | * Set the to addresses of this message. 132 | * 133 | * If multiple recipients will receive the message an array should be used. 134 | * Example: array('receiver@domain.org', 'other@domain.org' => 'A name') 135 | * 136 | * If $name is passed and the first parameter is a string, this name will be 137 | * associated with the address. 138 | * 139 | * @param string|array $email 140 | * @param string|null $name optional 141 | * 142 | * @return $this 143 | * 144 | * @see \Swift_Message::setTo() 145 | */ 146 | public function to($email, $name = null) 147 | { 148 | $email = $this->normalizeEmail($email); 149 | $this->getSwiftMessage()->setTo($email, $name); 150 | 151 | return $this; 152 | } 153 | 154 | /** 155 | * Get the To addresses of this message. 156 | * 157 | * @return array 158 | * 159 | * @see \Swift_Message::getTo() 160 | */ 161 | public function getTo() 162 | { 163 | return $this->getSwiftMessage()->getTo(); 164 | } 165 | 166 | /** 167 | * Set the Cc addresses of this message. 168 | * 169 | * If multiple recipients will receive the message an array should be used. 170 | * Example: array('receiver@domain.org', 'other@domain.org' => 'A name') 171 | * 172 | * If $name is passed and the first parameter is a string, this name will be 173 | * associated with the address. 174 | * 175 | * @param string|array $email 176 | * @param string|null $name optional 177 | * 178 | * @return $this 179 | * 180 | * @see \Swift_Message::setCc() 181 | */ 182 | public function cc($email, $name = null) 183 | { 184 | $email = $this->normalizeEmail($email); 185 | $this->getSwiftMessage()->setCc($email, $name); 186 | 187 | return $this; 188 | } 189 | 190 | /** 191 | * Get the Cc address of this message. 192 | * 193 | * @return array 194 | * 195 | * @see \Swift_Message::getCc() 196 | */ 197 | public function getCc() 198 | { 199 | return $this->getSwiftMessage()->getCc(); 200 | } 201 | 202 | /** 203 | * Set the Bcc addresses of this message. 204 | * 205 | * If multiple recipients will receive the message an array should be used. 206 | * Example: array('receiver@domain.org', 'other@domain.org' => 'A name') 207 | * 208 | * If $name is passed and the first parameter is a string, this name will be 209 | * associated with the address. 210 | * 211 | * @param string|array $email 212 | * @param string|null $name optional 213 | * 214 | * @return $this 215 | * 216 | * @see \Swift_Message::setBcc() 217 | */ 218 | public function bcc($email, $name = null) 219 | { 220 | $email = $this->normalizeEmail($email); 221 | $this->getSwiftMessage()->setBcc($email, $name); 222 | 223 | return $this; 224 | } 225 | 226 | /** 227 | * Get the Bcc addresses of this message. 228 | * 229 | * @return array 230 | * 231 | * @see \Swift_Message::getBcc() 232 | */ 233 | public function getBcc() 234 | { 235 | return $this->getSwiftMessage()->getBcc(); 236 | } 237 | 238 | /** 239 | * Set the sender of this message. 240 | * 241 | * This does not override the From field, but it has a higher significance. 242 | * 243 | * @param string|array $email 244 | * @param string|null $name optional 245 | * 246 | * @return $this 247 | * 248 | * @see \Swift_Message::setSender() 249 | */ 250 | public function sender($email, $name = null) 251 | { 252 | $email = $this->normalizeEmail($email); 253 | $this->getSwiftMessage()->setSender($email, $name); 254 | 255 | return $this; 256 | } 257 | 258 | /** 259 | * Get the sender of this message. 260 | * 261 | * @return string 262 | * 263 | * @see \Swift_Message::getSender() 264 | */ 265 | public function getSender() 266 | { 267 | return $this->getSwiftMessage()->getSender(); 268 | } 269 | 270 | /** 271 | * Set the subject of this message. 272 | * 273 | * @param string $subject 274 | * 275 | * @return $this 276 | * 277 | * @see \Swift_Message::setSubject() 278 | */ 279 | public function subject($subject) 280 | { 281 | $this->getSwiftMessage()->setSubject($subject); 282 | 283 | return $this; 284 | } 285 | 286 | /** 287 | * Get the subject of this message. 288 | * 289 | * @return string 290 | * 291 | * @see \Swift_Message::getSubject() 292 | */ 293 | public function getSubject() 294 | { 295 | return $this->getSwiftMessage()->getSubject(); 296 | } 297 | 298 | /** 299 | * Set the body of this message, either as a string, or as an instance of 300 | * {@link \Swift_OutputByteStream}. 301 | * 302 | * @param mixed $content 303 | * @param string $contentType optional 304 | * @param string $charset optional 305 | * 306 | * @return $this 307 | * 308 | * @see \Swift_Message::setBody() 309 | */ 310 | public function content($content, $contentType = self::CONTENT_TYPE_HTML, $charset = null) 311 | { 312 | $this->getSwiftMessage()->setBody($content, $contentType, $charset); 313 | 314 | return $this; 315 | } 316 | 317 | /** 318 | * Get the body of this message as a string. 319 | * 320 | * @return string 321 | * 322 | * @see \Swift_Message::getBody() 323 | */ 324 | public function getContent() 325 | { 326 | return $this->getSwiftMessage()->getBody(); 327 | } 328 | 329 | /** 330 | * Add optionally an alternative body 331 | * 332 | * @param string $content 333 | * @param string $contentType optional 334 | * @param string $charset optional 335 | * 336 | * @return $this 337 | */ 338 | public function contentAlternative($content, $contentType = null, $charset = null) 339 | { 340 | $this->getSwiftMessage()->addPart($content, $contentType, $charset); 341 | 342 | return $this; 343 | } 344 | 345 | /** 346 | * Set the Content-type of this message. 347 | * 348 | * @param string $contentType 349 | * 350 | * @return $this 351 | * 352 | * @see \Swift_Message::setContentType() 353 | */ 354 | public function contentType($contentType) 355 | { 356 | $this->getSwiftMessage()->setContentType($contentType); 357 | 358 | return $this; 359 | } 360 | 361 | /** 362 | * Get the Content-type of this message. 363 | * 364 | * @return string 365 | * 366 | * @see \Swift_Message::getContentType() 367 | */ 368 | public function getContentType() 369 | { 370 | return $this->getSwiftMessage()->getContentType(); 371 | } 372 | 373 | /** 374 | * Set the character set of this message. 375 | * 376 | * @param string $charset 377 | * 378 | * @return $this 379 | * 380 | * @see \Swift_Message::setCharset() 381 | */ 382 | public function charset($charset) 383 | { 384 | $this->getSwiftMessage()->setCharset($charset); 385 | 386 | return $this; 387 | } 388 | 389 | /** 390 | * Get the character set of this message. 391 | * 392 | * @return string 393 | * 394 | * @see \Swift_Message::getCharset() 395 | */ 396 | public function getCharset() 397 | { 398 | return $this->getSwiftMessage()->getCharset(); 399 | } 400 | 401 | /** 402 | * Set the priority of this message. 403 | * 404 | * The value is an integer where 1 is the highest priority and 5 is the lowest. 405 | * 406 | * @param int $priority 407 | * 408 | * @return $this 409 | * 410 | * @see \Swift_Message::setPriority() 411 | */ 412 | public function priority($priority) 413 | { 414 | $this->getSwiftMessage()->setPriority($priority); 415 | 416 | return $this; 417 | } 418 | 419 | /** 420 | * Get the priority of this message. 421 | * 422 | * The returned value is an integer where 1 is the highest priority and 5 423 | * is the lowest. 424 | * 425 | * @return int 426 | * 427 | * @see \Swift_Message::getPriority() 428 | */ 429 | public function getPriority() 430 | { 431 | return $this->getSwiftMessage()->getPriority(); 432 | } 433 | 434 | /** 435 | * Ask for a delivery receipt from the recipient to be sent to $addresses 436 | * 437 | * @param array $email 438 | * 439 | * @return $this 440 | * 441 | * @see \Swift_Message::setReadReceiptTo() 442 | */ 443 | public function setReadReceiptTo($email) 444 | { 445 | $email = $this->normalizeEmail($email); 446 | $this->getSwiftMessage()->setReadReceiptTo($email); 447 | 448 | return $this; 449 | } 450 | 451 | /** 452 | * An array of email which failed send to recipients. 453 | * 454 | * @return array 455 | */ 456 | public function getFailedRecipients() 457 | { 458 | return $this->failedRecipients; 459 | } 460 | 461 | /** 462 | * Get the addresses to which a read-receipt will be sent. 463 | * 464 | * @return string 465 | * 466 | * @see \Swift_Message::getReadReceiptTo() 467 | */ 468 | public function getReadReceiptTo() 469 | { 470 | return $this->getSwiftMessage()->getReadReceiptTo(); 471 | } 472 | 473 | /** 474 | * Set the return-path (the bounce address) of this message. 475 | * 476 | * @param string $email 477 | * 478 | * @return $this 479 | * 480 | * @see \Swift_Message::setReturnPath() 481 | */ 482 | public function setReturnPath($email) 483 | { 484 | $this->getSwiftMessage()->setReturnPath($email); 485 | 486 | return $this; 487 | } 488 | 489 | /** 490 | * Get the return-path (bounce address) of this message. 491 | * 492 | * @return string 493 | * 494 | * @see \Swift_Message::getReturnPath() 495 | */ 496 | public function getReturnPath() 497 | { 498 | return $this->getSwiftMessage()->getReturnPath(); 499 | } 500 | 501 | /** 502 | * Set the format of this message (flowed or fixed). 503 | * 504 | * @param string $format 505 | * 506 | * @return string 507 | * 508 | * @see \Swift_Message::setFormat() 509 | */ 510 | public function setFormat($format) 511 | { 512 | $this->getSwiftMessage()->setFormat($format); 513 | 514 | return $this; 515 | } 516 | 517 | /** 518 | * Get the format of this message (i.e. flowed or fixed). 519 | * 520 | * @return string 521 | * 522 | * @see \Swift_Message::getFormat() 523 | */ 524 | public function getFormat() 525 | { 526 | return $this->getSwiftMessage()->getFormat(); 527 | } 528 | 529 | /** 530 | * Attach a file to the message. 531 | * 532 | * Events: 533 | * - mailer:beforeAttachFile 534 | * - mailer:afterAttachFile 535 | * 536 | * @param string $file 537 | * @param array $options optional 538 | * 539 | * @return $this 540 | * 541 | * @see Phalcon\Ext\Mailer\Message::createAttachmentViaPath() 542 | * @see Phalcon\Ext\Mailer\Message::prepareAttachment() 543 | */ 544 | public function attachment($file, array $options = []) 545 | { 546 | $attachment = $this->createAttachmentViaPath($file); 547 | 548 | return $this->prepareAttachment($attachment, $options); 549 | } 550 | 551 | /** 552 | * Attach in-memory data as an attachment. 553 | * 554 | * @param string $data 555 | * @param string $name 556 | * @param array $options optional 557 | * 558 | * @return Message 559 | * 560 | * @see Phalcon\Ext\Mailer\Message::createAttachmentViaData() 561 | * @see Phalcon\Ext\Mailer\Message::prepareAttachment() 562 | */ 563 | public function attachmentData($data, $name, array $options = []) 564 | { 565 | $attachment = $this->createAttachmentViaData($data, $name); 566 | 567 | return $this->prepareAttachment($attachment, $options); 568 | } 569 | 570 | /** 571 | * Embed a file in the message and get the CID. 572 | * 573 | * @param string $file 574 | * 575 | * @return string 576 | */ 577 | public function embed($file) 578 | { 579 | $embed = $this->createEmbedViaPath($file); 580 | 581 | return $this->getSwiftMessage()->embed($embed); 582 | } 583 | 584 | /** 585 | * Embed in-memory data in the message and get the CID. 586 | * 587 | * @param string $data 588 | * @param string $name 589 | * @param string $contentType 590 | * 591 | * @return string 592 | */ 593 | public function embedData($data, $name, $contentType = null) 594 | { 595 | $embed = $this->createEmbedViaData($data, $name, $contentType); 596 | 597 | return $this->getSwiftMessage()->embed($embed); 598 | } 599 | 600 | /** 601 | * Return a {@link \Swift_Message} instance 602 | * 603 | * @return \Swift_Message 604 | */ 605 | public function getSwiftMessage() 606 | { 607 | if (!$this->swiftMessage) { 608 | $this->swiftMessage = $this->getManager()->getSwift()->createMessage(); 609 | } 610 | 611 | return $this->swiftMessage; 612 | } 613 | 614 | /** 615 | * Return a {@link \Phalcon\Ext\Mailer\Manager} instance 616 | * 617 | * @return \Phalcon\Ext\Mailer\Manager 618 | */ 619 | public function getManager() 620 | { 621 | return $this->manager; 622 | } 623 | 624 | /** 625 | * Send the given Message like it would be sent in a mail client. 626 | * 627 | * All recipients (with the exception of Bcc) will be able to see the other 628 | * recipients this message was sent to. 629 | * 630 | * Recipient/sender data will be retrieved from the Message object. 631 | * 632 | * The return value is the number of recipients who were accepted for 633 | * delivery. 634 | * 635 | * Events: 636 | * - mailer:beforeSend 637 | * - mailer:afterSend 638 | * 639 | * @return int 640 | * 641 | * @see \Swift_Mailer::send() 642 | */ 643 | public function send() 644 | { 645 | $eventManager = $this->getManager()->getEventsManager(); 646 | 647 | if ($eventManager) { 648 | $result = $eventManager->fire('mailer:beforeSend', $this); 649 | } else { 650 | $result = true; 651 | } 652 | 653 | if ($result !== false) { 654 | 655 | $this->failedRecipients = []; 656 | 657 | $count = $this->getManager()->getSwift()->send($this->getSwiftMessage(), $this->failedRecipients); 658 | 659 | if ($eventManager) { 660 | $eventManager->fire('mailer:afterSend', $this, [$count, $this->failedRecipients]); 661 | } 662 | 663 | return $count; 664 | 665 | } else { 666 | return false; 667 | } 668 | } 669 | 670 | /** 671 | * Prepare and attach the given attachment. 672 | * 673 | * @param \Swift_Attachment $attachment 674 | * @param array $options optional 675 | * 676 | * @return $this 677 | * 678 | * @see \Swift_Message::attach() 679 | */ 680 | protected function prepareAttachment(\Swift_Attachment $attachment, array $options = []) 681 | { 682 | if (isset($options['mime'])) { 683 | $attachment->setContentType($options['mime']); 684 | } 685 | 686 | if (isset($options['as'])) { 687 | $attachment->setFilename($options['as']); 688 | } 689 | 690 | $eventManager = $this->getManager()->getEventsManager(); 691 | 692 | if ($eventManager) { 693 | $result = $eventManager->fire('mailer:beforeAttachFile', $this, [$attachment]); 694 | } else { 695 | $result = true; 696 | } 697 | 698 | if ($result !== false) { 699 | $this->getSwiftMessage()->attach($attachment); 700 | 701 | if ($eventManager) { 702 | $eventManager->fire('mailer:afterAttachFile', $this, [$attachment]); 703 | } 704 | } 705 | 706 | return $this; 707 | } 708 | 709 | /** 710 | * Create a Swift new Attachment from a filesystem path. 711 | * 712 | * @param string $file 713 | * 714 | * @return \Swift_Attachment 715 | * 716 | * @see \Swift_Attachment::fromPath() 717 | */ 718 | protected function createAttachmentViaPath($file) 719 | { 720 | /** @var $byteStream \Swift_ByteStream_FileByteStream */ 721 | $byteStream = $this->getManager()->getDI()->get('\Swift_ByteStream_FileByteStream', [$file]); 722 | 723 | /** @var $image \Swift_Attachment */ 724 | $attachment = $this->getManager()->getDI()->get('\Swift_Attachment') 725 | ->setFile($byteStream); 726 | 727 | return $attachment; 728 | } 729 | 730 | /** 731 | * Create a Swift Attachment instance from data. 732 | * 733 | * @param string $data 734 | * @param string $name optional 735 | * 736 | * @return \Swift_Attachment 737 | * 738 | * @see \Swift_Attachment::newInstance() 739 | */ 740 | protected function createAttachmentViaData($data, $name) 741 | { 742 | return $this->getManager()->getDI()->get('\Swift_Attachment', [$data, $name]); 743 | } 744 | 745 | /** 746 | * Create a Swift new Image from a filesystem path. 747 | * 748 | * @param string $file 749 | * 750 | * @return \Swift_Image 751 | * 752 | * @see \Swift_Image::fromPath() 753 | */ 754 | protected function createEmbedViaPath($file) 755 | { 756 | /** @var $byteStream \Swift_ByteStream_FileByteStream */ 757 | $byteStream = $this->getManager()->getDI()->get('\Swift_ByteStream_FileByteStream', [$file]); 758 | 759 | /** @var $image \Swift_Image */ 760 | $image = $this->getManager()->getDI()->get('\Swift_Image') 761 | ->setFile($byteStream); 762 | 763 | return $image; 764 | } 765 | 766 | /** 767 | * Create a Swift new Image. 768 | * 769 | * @param string $data 770 | * @param string|null $filename 771 | * @param string|null $contentType 772 | * 773 | * @return \Swift_Image 774 | * 775 | * @see \Swift_Image::newInstance() 776 | */ 777 | protected function createEmbedViaData($data, $filename = null, $contentType = null) 778 | { 779 | return $this->getManager()->getDI()->get('\Swift_Image', [$data, $filename, $contentType]); 780 | } 781 | 782 | /** 783 | * Normalize IDN domains. 784 | * 785 | * @param $email 786 | * 787 | * @return array|string 788 | */ 789 | protected function normalizeEmail($email) 790 | { 791 | if (is_array($email)) { 792 | 793 | $emails = []; 794 | 795 | foreach ($email as $k => $v) { 796 | if (is_int($k)) { 797 | $emails[$k] = $this->getManager()->normalizeEmail($v); 798 | } else { 799 | $k = $this->getManager()->normalizeEmail($k); 800 | $emails[$k] = $v; 801 | } 802 | } 803 | 804 | return $emails; 805 | 806 | } else { 807 | return $this->getManager()->normalizeEmail($email); 808 | } 809 | } 810 | } 811 | --------------------------------------------------------------------------------