| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545 | 
							- <?php
 
- namespace Grav\Plugin\Email;
 
- use Grav\Common\Config\Config;
 
- use Grav\Common\Grav;
 
- use Grav\Common\Language\Language;
 
- use Grav\Common\Markdown\Parsedown;
 
- use Grav\Common\Twig\Twig;
 
- use Grav\Framework\Form\Interfaces\FormInterface;
 
- use \Monolog\Logger;
 
- use \Monolog\Handler\StreamHandler;
 
- class Email
 
- {
 
-     /**
 
-      * @var \Swift_Transport
 
-      */
 
-     protected $mailer;
 
-     /**
 
-      * @var \Swift_Plugins_LoggerPlugin
 
-      */
 
-     protected $logger;
 
-     protected $queue_path;
 
-     /**
 
-      * Returns true if emails have been enabled in the system.
 
-      *
 
-      * @return bool
 
-      */
 
-     public static function enabled()
 
-     {
 
-         return Grav::instance()['config']->get('plugins.email.mailer.engine') !== 'none';
 
-     }
 
-     /**
 
-      * Returns true if debugging on emails has been enabled.
 
-      *
 
-      * @return bool
 
-      */
 
-     public static function debug()
 
-     {
 
-         return Grav::instance()['config']->get('plugins.email.debug') == 'true';
 
-     }
 
-     /**
 
-      * Creates an email message.
 
-      *
 
-      * @param string $subject
 
-      * @param string $body
 
-      * @param string $contentType
 
-      * @param string $charset
 
-      * @return \Swift_Message
 
-      */
 
-     public function message($subject = null, $body = null, $contentType = null, $charset = null)
 
-     {
 
-         return new \Swift_Message($subject, $body, $contentType, $charset);
 
-     }
 
-     /**
 
-      * Creates an attachment.
 
-      *
 
-      * @param string $data
 
-      * @param string $filename
 
-      * @param string $contentType
 
-      * @return \Swift_Attachment
 
-      */
 
-     public function attachment($data = null, $filename = null, $contentType = null)
 
-     {
 
-         return new \Swift_Attachment($data, $filename, $contentType);
 
-     }
 
-     /**
 
-      * Creates an embedded attachment.
 
-      *
 
-      * @param string $data
 
-      * @param string $filename
 
-      * @param string $contentType
 
-      * @return \Swift_EmbeddedFile
 
-      */
 
-     public function embedded($data = null, $filename = null, $contentType = null)
 
-     {
 
-         return new \Swift_EmbeddedFile($data, $filename, $contentType);
 
-     }
 
-     /**
 
-      * Creates an image attachment.
 
-      *
 
-      * @param string $data
 
-      * @param string $filename
 
-      * @param string $contentType
 
-      * @return \Swift_Image
 
-      */
 
-     public function image($data = null, $filename = null, $contentType = null)
 
-     {
 
-         return new \Swift_Image($data, $filename, $contentType);
 
-     }
 
-     /**
 
-      * Send email.
 
-      *
 
-      * @param \Swift_Message $message
 
-      * @return int
 
-      */
 
-     public function send($message)
 
-     {
 
-         $mailer = $this->getMailer();
 
-         $result = $mailer ? $mailer->send($message) : 0;
 
-         // Check if emails and debugging are both enabled.
 
-         if ($mailer && $this->debug()) {
 
-             $log = new Logger('email');
 
-             $locator = Grav::instance()['locator'];
 
-             $log_file = $locator->findResource('log://email.log', true, true);
 
-             $log->pushHandler(new StreamHandler($log_file, Logger::DEBUG));
 
-             // Append the SwiftMailer log to the log.
 
-             $log->addDebug($this->getLogs());
 
-         }
 
-         return $result;
 
-     }
 
-     /**
 
-      * Build e-mail message.
 
-      *
 
-      * @param array $params
 
-      * @param array $vars
 
-      * @return \Swift_Message
 
-      */
 
-     public function buildMessage(array $params, array $vars = [])
 
-     {
 
-         /** @var Twig $twig */
 
-         $twig = Grav::instance()['twig'];
 
-         /** @var Config $config */
 
-         $config = Grav::instance()['config'];
 
-         /** @var Language $language */
 
-         $language = Grav::instance()['language'];
 
-         // Extend parameters with defaults.
 
-         $params += [
 
-             'bcc' => $config->get('plugins.email.bcc', []),
 
-             'body' => $config->get('plugins.email.body', '{% include "forms/data.html.twig" %}'),
 
-             'cc' => $config->get('plugins.email.cc', []),
 
-             'cc_name' => $config->get('plugins.email.cc_name'),
 
-             'charset' =>  $config->get('plugins.email.charset', 'utf-8'),
 
-             'from' => $config->get('plugins.email.from'),
 
-             'from_name' => $config->get('plugins.email.from_name'),
 
-             'content_type' => $config->get('plugins.email.content_type', 'text/html'),
 
-             'reply_to' => $config->get('plugins.email.reply_to', []),
 
-             'reply_to_name' => $config->get('plugins.email.reply_to_name'),
 
-             'subject' => !empty($vars['form']) && $vars['form'] instanceof FormInterface ? $vars['form']->page()->title() : null,
 
-             'to' => $config->get('plugins.email.to'),
 
-             'to_name' => $config->get('plugins.email.to_name'),
 
-             'process_markdown' => false,
 
-             'template' => false
 
-         ];
 
-         // Create message object.
 
-         $message = $this->message();
 
-         if (!$params['to']) {
 
-             throw new \RuntimeException($language->translate('PLUGIN_EMAIL.PLEASE_CONFIGURE_A_TO_ADDRESS'));
 
-         }
 
-         if (!$params['from']) {
 
-             throw new \RuntimeException($language->translate('PLUGIN_EMAIL.PLEASE_CONFIGURE_A_FROM_ADDRESS'));
 
-         }
 
-         // Process parameters.
 
-         foreach ($params as $key => $value) {
 
-             switch ($key) {
 
-                 case 'body':
 
-                     if (is_string($value)) {
 
-                         $body = $twig->processString($value, $vars);
 
-                         if ($params['process_markdown']) {
 
-                             $parsedown = new Parsedown();
 
-                             $body = $parsedown->text($body);
 
-                         }
 
-                         if ($params['template']) {
 
-                             $vars = array_merge($vars, ['content' => $body]);
 
-                             $body = $twig->processTemplate($params['template'], $vars);
 
-                         }
 
-                         $content_type = !empty($params['content_type']) ? $twig->processString($params['content_type'], $vars) : null;
 
-                         $charset = !empty($params['charset']) ? $twig->processString($params['charset'], $vars) : null;
 
-                         $message->setBody($body, $content_type, $charset);
 
-                     }
 
-                     elseif (is_array($value)) {
 
-                         foreach ($value as $body_part) {
 
-                             $body_part += [
 
-                                 'charset' => $params['charset'],
 
-                                 'content_type' => $params['content_type'],
 
-                             ];
 
-                             $body = !empty($body_part['body']) ? $twig->processString($body_part['body'], $vars) : null;
 
-                             if ($params['process_markdown']) {
 
-                                 $parsedown = new Parsedown();
 
-                                 $body = $parsedown->text($body);
 
-                             }
 
-                             $content_type = !empty($body_part['content_type']) ? $twig->processString($body_part['content_type'], $vars) : null;
 
-                             $charset = !empty($body_part['charset']) ? $twig->processString($body_part['charset'], $vars) : null;
 
-                             if (!$message->getBody()) {
 
-                                 $message->setBody($body, $content_type, $charset);
 
-                             }
 
-                             else {
 
-                                 $message->addPart($body, $content_type, $charset);
 
-                             }
 
-                         }
 
-                     }
 
-                     break;
 
-                 case 'subject':
 
-                     $message->setSubject($twig->processString($language->translate($value), $vars));
 
-                     break;
 
-                 case 'to':
 
-                     if (is_string($value) && !empty($params['to_name'])) {
 
-                         $value = [
 
-                             'mail' => $twig->processString($value, $vars),
 
-                             'name' => $twig->processString($params['to_name'], $vars),
 
-                         ];
 
-                     }
 
-                     foreach ($this->parseAddressValue($value, $vars) as $address) {
 
-                         $message->addTo($address->mail, $address->name);
 
-                     }
 
-                     break;
 
-                 case 'cc':
 
-                     if (is_string($value) && !empty($params['cc_name'])) {
 
-                         $value = [
 
-                             'mail' => $twig->processString($value, $vars),
 
-                             'name' => $twig->processString($params['cc_name'], $vars),
 
-                         ];
 
-                     }
 
-                     foreach ($this->parseAddressValue($value, $vars) as $address) {
 
-                         $message->addCc($address->mail, $address->name);
 
-                     }
 
-                     break;
 
-                 case 'bcc':
 
-                     foreach ($this->parseAddressValue($value, $vars) as $address) {
 
-                         $message->addBcc($address->mail, $address->name);
 
-                     }
 
-                     break;
 
-                 case 'from':
 
-                     if (is_string($value) && !empty($params['from_name'])) {
 
-                         $value = [
 
-                             'mail' => $twig->processString($value, $vars),
 
-                             'name' => $twig->processString($params['from_name'], $vars),
 
-                         ];
 
-                     }
 
-                     foreach ($this->parseAddressValue($value, $vars) as $address) {
 
-                         $message->addFrom($address->mail, $address->name);
 
-                     }
 
-                     break;
 
-                 case 'reply_to':
 
-                     if (is_string($value) && !empty($params['reply_to_name'])) {
 
-                         $value = [
 
-                             'mail' => $twig->processString($value, $vars),
 
-                             'name' => $twig->processString($params['reply_to_name'], $vars),
 
-                         ];
 
-                     }
 
-                     foreach ($this->parseAddressValue($value, $vars) as $address) {
 
-                         $message->addReplyTo($address->mail, $address->name);
 
-                     }
 
-                     break;
 
-             }
 
-         }
 
-         return $message;
 
-     }
 
-     /**
 
-      * Return parsed e-mail address value.
 
-      *
 
-      * @param string|string[] $value
 
-      * @param array $vars
 
-      * @return array
 
-      */
 
-     public function parseAddressValue($value, array $vars = [])
 
-     {
 
-         $parsed = [];
 
-         /** @var Twig $twig */
 
-         $twig = Grav::instance()['twig'];
 
-         // Single e-mail address string
 
-         if (is_string($value)) {
 
-             $parsed[] = (object) [
 
-                 'mail' => $twig->processString($value, $vars),
 
-                 'name' => null,
 
-             ];
 
-         }
 
-         else {
 
-             // Cast value as array
 
-             $value = (array) $value;
 
-             // Single e-mail address array
 
-             if (!empty($value['mail'])) {
 
-                 $parsed[] = (object) [
 
-                     'mail' => $twig->processString($value['mail'], $vars),
 
-                     'name' => !empty($value['name']) ? $twig->processString($value['name'], $vars) : NULL,
 
-                 ];
 
-             }
 
-             // Multiple addresses (either as strings or arrays)
 
-             elseif (!(empty($value['mail']) && !empty($value['name']))) {
 
-                 foreach ($value as $y => $itemx) {
 
-                     $addresses = $this->parseAddressValue($itemx, $vars);
 
-                     if (($address = reset($addresses))) {
 
-                         $parsed[] = $address;
 
-                     }
 
-                 }
 
-             }
 
-         }
 
-         return $parsed;
 
-     }
 
-     /**
 
-      * Return debugging logs if enabled
 
-      *
 
-      * @return string
 
-      */
 
-     public function getLogs()
 
-     {
 
-         if ($this->debug()) {
 
-             return $this->logger->dump();
 
-         }
 
-         return '';
 
-     }
 
-     /**
 
-      * @internal
 
-      * @return null|\Swift_Mailer
 
-      */
 
-     protected function getMailer()
 
-     {
 
-         if (!$this->enabled()) {
 
-             return null;
 
-         }
 
-         if (!$this->mailer) {
 
-             /** @var Config $config */
 
-             $config = Grav::instance()['config'];
 
-             $queue_enabled = $config->get('plugins.email.queue.enabled');
 
-             $transport = $queue_enabled === true ? $this->getQueue() : $this->getTransport();
 
-             // Create the Mailer using your created Transport
 
-             $this->mailer = new \Swift_Mailer($transport);
 
-             // Register the logger if we're debugging.
 
-             if ($this->debug()) {
 
-                 $this->logger = new \Swift_Plugins_Loggers_ArrayLogger();
 
-                 $this->mailer->registerPlugin(new \Swift_Plugins_LoggerPlugin($this->logger));
 
-             }
 
-         }
 
-         return $this->mailer;
 
-     }
 
-     protected static function getQueuePath()
 
-     {
 
-         $queue_path = Grav::instance()['locator']->findResource('user://data', true) . '/email-queue';
 
-         if (!file_exists($queue_path)) {
 
-             mkdir($queue_path);
 
-         }
 
-         return $queue_path;
 
-     }
 
-     protected static function getQueue()
 
-     {
 
-         $queue_path = static::getQueuePath();
 
-         $spool = new \Swift_FileSpool($queue_path);
 
-         $transport = new \Swift_SpoolTransport($spool);
 
-         return $transport;
 
-     }
 
-     public static function flushQueue()
 
-     {
 
-         $grav = Grav::instance();
 
-         $grav['debugger']->enabled(false);
 
-         $config = $grav['config']->get('plugins.email.queue');
 
-         $queue = static::getQueue();
 
-         $spool = $queue->getSpool();
 
-         $spool->setMessageLimit($config['flush_msg_limit']);
 
-         $spool->setTimeLimit($config['flush_time_limit']);
 
-         try {
 
-             $failures = [];
 
-             $result = $spool->flushQueue(static::getTransport(), $failures);
 
-             return $result . ' messages flushed from queue...';
 
-         } catch (\Exception $e) {
 
-             $grav['log']->error($e->getMessage());
 
-             return $e->getMessage();
 
-         }
 
-     }
 
-     public static function clearQueueFailures()
 
-     {
 
-         $grav = Grav::instance();
 
-         $grav['debugger']->enabled(false);
 
-         $preferences = \Swift_Preferences::getInstance();
 
-         $preferences->setTempDir(sys_get_temp_dir());
 
-         /** @var \Swift_Transport $transport */
 
-         $transport = static::getTransport();
 
-         if (!$transport->isStarted()) {
 
-             $transport->start();
 
-         }
 
-         $queue_path = static::getQueuePath();
 
-         foreach (new \GlobIterator($queue_path . '/*.sending') as $file) {
 
-             $final_message = $file->getPathname();
 
-             /** @var \Swift_Message $message */
 
-             $message = unserialize(file_get_contents($final_message));
 
-             echo(sprintf(
 
-                 'Retrying "%s" to "%s"',
 
-                 $message->getSubject(),
 
-                 implode(', ', array_keys($message->getTo()))
 
-             ) . "\n");
 
-             try {
 
-                 $clean = static::cloneMessage($message);
 
-                 $transport->send($clean);
 
-                 echo("sent!\n");
 
-                 // DOn't want to trip up any errors from sending too fast
 
-                 sleep(1);
 
-             } catch (\Swift_TransportException $e) {
 
-                 echo("ERROR: Send failed - deleting spooled message\n");
 
-             }
 
-             // Remove the file
 
-             unlink($final_message);
 
-         }
 
-     }
 
-     /**
 
-      * Clean copy a message
 
-      *
 
-      * @param \Swift_Message $message
 
-      */
 
-     public static function cloneMessage($message)
 
-     {
 
-         $clean = new \Swift_Message();
 
-         $clean->setBoundary($message->getBoundary());
 
-         $clean->setBcc($message->getBcc());
 
-         $clean->setBody($message->getBody());
 
-         $clean->setCharset($message->getCharset());
 
-         $clean->setChildren($message->getChildren());
 
-         $clean->setContentType($message->getContentType());
 
-         $clean->setCc($message->getCc());
 
-         $clean->setDate($message->getDate());
 
-         $clean->setDescription($message->getDescription());
 
-         $clean->setEncoder($message->getEncoder());
 
-         $clean->setFormat($message->getFormat());
 
-         $clean->setFrom($message->getFrom());
 
-         $clean->setId($message->getId());
 
-         $clean->setMaxLineLength($message->getMaxLineLength());
 
-         $clean->setPriority($message->getPriority());
 
-         $clean->setReplyTo($message->getReplyTo());
 
-         $clean->setReturnPath($message->getReturnPath());
 
-         $clean->setSender($message->getSender());
 
-         $clean->setSubject($message->getSubject());
 
-         $clean->setTo($message->getTo());
 
-         return $clean;
 
-     }
 
-     protected static function getTransport()
 
-     {
 
-         /** @var Config $config */
 
-         $config = Grav::instance()['config'];
 
-         $engine = $config->get('plugins.email.mailer.engine');
 
-         // Create the Transport and initialize it.
 
-         switch ($engine) {
 
-             case 'smtp':
 
-                 $transport = new \Swift_SmtpTransport();
 
-                 $options = $config->get('plugins.email.mailer.smtp');
 
-                 if (!empty($options['server'])) {
 
-                     $transport->setHost($options['server']);
 
-                 }
 
-                 if (!empty($options['port'])) {
 
-                     $transport->setPort($options['port']);
 
-                 }
 
-                 if (!empty($options['encryption']) && $options['encryption'] !== 'none') {
 
-                     $transport->setEncryption($options['encryption']);
 
-                 }
 
-                 if (!empty($options['user'])) {
 
-                     $transport->setUsername($options['user']);
 
-                 }
 
-                 if (!empty($options['password'])) {
 
-                     $transport->setPassword($options['password']);
 
-                 }
 
-                 break;
 
-             case 'sendmail':
 
-             default:
 
-                 $options = $config->get('plugins.email.mailer.sendmail');
 
-                 $bin = !empty($options['bin']) ? $options['bin'] : '/usr/sbin/sendmail';
 
-                 $transport = new \Swift_SendmailTransport($bin);
 
-                 break;
 
-         }
 
-         return $transport;
 
-     }
 
- }
 
 
  |