From 501dd5b173975866357c6d441376eb2dad60166c Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Fri, 23 Feb 2018 00:02:44 +0200 Subject: [PATCH] Implement Postmark API --- app/Models/Traits/HasLogo.php | 12 ++ app/Ninja/Mailers/Mailer.php | 128 ++++++++++++------ composer.json | 2 +- composer.lock | 110 +++++++-------- config/app.php | 2 +- .../emails/partials/account_logo.blade.php | 2 +- 6 files changed, 154 insertions(+), 102 deletions(-) diff --git a/app/Models/Traits/HasLogo.php b/app/Models/Traits/HasLogo.php index 6caf188ec009..1feb8c0a3d87 100644 --- a/app/Models/Traits/HasLogo.php +++ b/app/Models/Traits/HasLogo.php @@ -145,6 +145,18 @@ trait HasLogo return round($this->logo_size / 1000); } + /** + * @return string|null + */ + public function getLogoName() + { + if (! $this->hasLogo()) { + return null; + } + + return $this->logo; + } + /** * @return bool */ diff --git a/app/Ninja/Mailers/Mailer.php b/app/Ninja/Mailers/Mailer.php index 26cd5165d71c..c246b4553eb1 100644 --- a/app/Ninja/Mailers/Mailer.php +++ b/app/Ninja/Mailers/Mailer.php @@ -6,6 +6,9 @@ use App\Models\Invoice; use Exception; use Mail; use Utils; +use Postmark\PostmarkClient; +use Postmark\Models\PostmarkException; +use Postmark\Models\PostmarkAttachment; /** * Class Mailer. @@ -34,6 +37,25 @@ class Mailer 'emails.'.$view.'_text', ]; + $toEmail = strtolower($toEmail); + $replyEmail = $fromEmail; + $fromEmail = CONTACT_EMAIL; + //\Log::info("{$toEmail} | {$replyEmail} | $fromEmail"); + + // Optionally send for alternate domain + if (! empty($data['fromEmail'])) { + $fromEmail = $data['fromEmail']; + } + + if (config('services.postmark')) { + return $this->sendPostmarkMail($toEmail, $fromEmail, $fromName, $replyEmail, $subject, $views, $data); + } else { + return $this->sendLaravelMail($toEmail, $fromEmail, $fromName, $replyEmail, $subject, $views, $data); + } + } + + private function sendLaravelMail($toEmail, $fromEmail, $fromName, $replyEmail, $subject, $views, $data = []) + { if (Utils::isSelfHost()) { if (isset($data['account'])) { $account = $data['account']; @@ -60,17 +82,7 @@ class Mailer } try { - $response = Mail::send($views, $data, function ($message) use ($toEmail, $fromEmail, $fromName, $subject, $data) { - $toEmail = strtolower($toEmail); - $replyEmail = $fromEmail; - $fromEmail = CONTACT_EMAIL; - //\Log::info("{$toEmail} | {$replyEmail} | $fromEmail"); - - // Optionally send for alternate domain - if (! empty($data['fromEmail'])) { - $fromEmail = $data['fromEmail']; - } - + $response = Mail::send($views, $data, function ($message) use ($toEmail, $fromEmail, $fromName, $replyEmail, $subject, $data) { $message->to($toEmail) ->from($fromEmail, $fromName) ->replyTo($replyEmail, $fromName) @@ -95,9 +107,64 @@ class Mailer } }); - return $this->handleSuccess($response, $data); + return $this->handleSuccess($data); } catch (Exception $exception) { - return $this->handleFailure($exception); + return $this->handleFailure($data, $exception->getMessage()); + } + } + + private function sendPostmarkMail($toEmail, $fromEmail, $fromName, $replyEmail, $subject, $views, $data = []) + { + $htmlBody = view($views[0], $data)->render(); + $textBody = view($views[1], $data)->render(); + $attachments = []; + + if (isset($data['account'])) { + $account = $data['account']; + $logoName = $account->getLogoName(); + $attachments[] = PostmarkAttachment::fromFile($account->getLogoPath(), $logoName, null, 'cid:' . $logoName); + } + + // Handle invoice attachments + if (! empty($data['pdfString']) && ! empty($data['pdfFileName'])) { + $attachments[] = PostmarkAttachment::fromRawData($document['pdfString'], $document['pdfFileName']); + } + if (! empty($data['ublString']) && ! empty($data['ublFileName'])) { + $attachments[] = PostmarkAttachment::fromRawData($document['ublString'], $document['ublFileName']); + } + if (! empty($data['documents'])) { + foreach ($data['documents'] as $document) { + $attachments[] = PostmarkAttachment::fromRawData($document['data'], $document['name']); + } + } + + try { + $client = new PostmarkClient(config('services.postmark')); + $message = [ + 'To' => $toEmail, + 'From' => $fromEmail, + 'ReplyTo' => $replyEmail, + 'Subject' => $subject, + 'TextBody' => $textBody, + 'HtmlBody' => $htmlBody, + 'Attachments' => $attachments, + ]; + + if (! empty($data['bccEmail'])) { + $message['Bcc'] = $data['bccEmail']; + } + + $response = $client->sendEmailBatch([$message]); + if ($messageId = $response[0]->messageid) { + return $this->handleSuccess($data, $messageId); + } else { + return $this->handleFailure($data, $response[0]->message); + } + } catch (PostmarkException $exception) { + return $this->handleFailure($data, $exception->getMessage()); + } catch (Exception $exception) { + Utils::logError(Utils::getErrorString($exception)); + throw $exception; } } @@ -107,19 +174,11 @@ class Mailer * * @return bool */ - private function handleSuccess($response, $data) + private function handleSuccess($data, $messageId = false) { if (isset($data['invitation'])) { $invitation = $data['invitation']; $invoice = $invitation->invoice; - $messageId = false; - - // Track the Postmark message id - if (isset($_ENV['POSTMARK_API_TOKEN']) && $response) { - $json = json_decode((string) $response->getBody()); - $messageId = $json->MessageID; - } - $notes = isset($data['notes']) ? $data['notes'] : false; if (! empty($data['proposal'])) { @@ -137,35 +196,14 @@ class Mailer * * @return string */ - private function handleFailure($exception) + private function handleFailure($data, $emailError) { - if (isset($_ENV['POSTMARK_API_TOKEN']) && method_exists($exception, 'getResponse')) { - $response = $exception->getResponse(); - - if (! $response) { - $error = trans('texts.postmark_error', ['link' => link_to('https://status.postmarkapp.com/')]); - Utils::logError($error); - - if (config('queue.default') === 'sync') { - return $error; - } else { - throw $exception; - } - } - - $response = $response->getBody()->getContents(); - $response = json_decode($response); - $emailError = nl2br($response->Message); - } else { - $emailError = $exception->getMessage(); - } - if (isset($data['invitation'])) { $invitation = $data['invitation']; $invitation->email_error = $emailError; $invitation->save(); } elseif (! Utils::isNinjaProd()) { - Utils::logError(Utils::getErrorString($exception)); + Utils::logError($emailError); } return $emailError; diff --git a/composer.json b/composer.json index 3e4fe81ea0ae..6b86090154a0 100644 --- a/composer.json +++ b/composer.json @@ -62,7 +62,7 @@ "webpatser/laravel-countries": "dev-master", "websight/l5-google-cloud-storage": "dev-master", "wepay/php-sdk": "^0.2", - "wildbit/laravel-postmark-provider": "dev-master#134f359" + "wildbit/postmark-php": "^2.5" }, "require-dev": { "symfony/dom-crawler": "~3.1", diff --git a/composer.lock b/composer.lock index b9972255cd20..cfe8e11f2256 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "5b06c2acfc8bddcbf559e41191aa7dce", - "content-hash": "aadd859625636a9b39cc0a124f690335", + "hash": "8e8cf009110c559e312b5bb77154f830", + "content-hash": "f2f5c5139acd1664ab9a36f747b33017", "packages": [ { "name": "abdala/omnipay-pagseguro", @@ -10380,59 +10380,25 @@ "time": "2015-08-14 19:42:37" }, { - "name": "wildbit/laravel-postmark-provider", - "version": "dev-master", + "name": "wildbit/postmark-php", + "version": "2.5.0", "source": { "type": "git", - "url": "https://github.com/wildbit/laravel-postmark-provider.git", - "reference": "134f359" + "url": "https://github.com/wildbit/postmark-php.git", + "reference": "10fbcc61216ddee5f944c3082d16a8c858a998ea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wildbit/laravel-postmark-provider/zipball/134f359", - "reference": "134f359", - "shasum": "" - }, - "require": { - "illuminate/mail": "~5.2", - "wildbit/swiftmailer-postmark": "~2.0" - }, - "type": "library", - "autoload": { - "psr-0": { - "Postmark\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "An officially supported mail provider to send mail from Laravel through Postmark, see instructions for integrating it here: https://github.com/wildbit/laravel-postmark-provider/blob/master/README.md", - "time": "2017-01-19 19:52:38" - }, - { - "name": "wildbit/swiftmailer-postmark", - "version": "2.1.0", - "source": { - "type": "git", - "url": "https://github.com/wildbit/swiftmailer-postmark.git", - "reference": "fb49114bc8033b125f9d19473dc0741385131d84" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/wildbit/swiftmailer-postmark/zipball/fb49114bc8033b125f9d19473dc0741385131d84", - "reference": "fb49114bc8033b125f9d19473dc0741385131d84", + "url": "https://api.github.com/repos/wildbit/postmark-php/zipball/10fbcc61216ddee5f944c3082d16a8c858a998ea", + "reference": "10fbcc61216ddee5f944c3082d16a8c858a998ea", "shasum": "" }, "require": { "guzzlehttp/guzzle": "~6.0", - "swiftmailer/swiftmailer": ">=4.1.5" + "php": ">=5.5.0" }, "require-dev": { - "phpunit/phpunit": "~4.5" - }, - "suggest": { - "wildbit/laravel-postmark-provider": "~1.0" + "phpunit/phpunit": "4.4.0" }, "type": "library", "autoload": { @@ -10444,14 +10410,8 @@ "license": [ "MIT" ], - "authors": [ - { - "name": "Postmark", - "email": "support@postmarkapp.com" - } - ], - "description": "A Swiftmailer Transport for Postmark.", - "time": "2017-04-18 14:24:10" + "description": "The officially supported client for Postmark (http://postmarkapp.com)", + "time": "2017-12-13 14:35:57" }, { "name": "zendframework/zend-escaper", @@ -12757,6 +12717,49 @@ "validate" ], "time": "2018-01-29 19:49:41" + }, + { + "name": "wildbit/swiftmailer-postmark", + "version": "2.1.0", + "source": { + "type": "git", + "url": "https://github.com/wildbit/swiftmailer-postmark.git", + "reference": "fb49114bc8033b125f9d19473dc0741385131d84" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wildbit/swiftmailer-postmark/zipball/fb49114bc8033b125f9d19473dc0741385131d84", + "reference": "fb49114bc8033b125f9d19473dc0741385131d84", + "shasum": "" + }, + "require": { + "guzzlehttp/guzzle": "~6.0", + "swiftmailer/swiftmailer": ">=4.1.5" + }, + "require-dev": { + "phpunit/phpunit": "~4.5" + }, + "suggest": { + "wildbit/laravel-postmark-provider": "~1.0" + }, + "type": "library", + "autoload": { + "psr-0": { + "Postmark\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Postmark", + "email": "support@postmarkapp.com" + } + ], + "description": "A Swiftmailer Transport for Postmark.", + "time": "2017-04-18 14:24:10" } ], "aliases": [ @@ -12782,8 +12785,7 @@ "roave/security-advisories": 20, "simshaun/recurr": 20, "webpatser/laravel-countries": 20, - "websight/l5-google-cloud-storage": 20, - "wildbit/laravel-postmark-provider": 20 + "websight/l5-google-cloud-storage": 20 }, "prefer-stable": true, "prefer-lowest": false, diff --git a/config/app.php b/config/app.php index 05821f9e7fe8..06d24f55aca6 100644 --- a/config/app.php +++ b/config/app.php @@ -130,7 +130,7 @@ return [ 'Illuminate\Filesystem\FilesystemServiceProvider', 'Illuminate\Foundation\Providers\FoundationServiceProvider', 'Illuminate\Hashing\HashServiceProvider', - (isset($_ENV['POSTMARK_API_TOKEN']) ? 'Postmark\Adapters\LaravelMailProvider' : 'Illuminate\Mail\MailServiceProvider'), + 'Illuminate\Mail\MailServiceProvider', 'Illuminate\Pagination\PaginationServiceProvider', 'Illuminate\Pipeline\PipelineServiceProvider', 'Illuminate\Queue\QueueServiceProvider', diff --git a/resources/views/emails/partials/account_logo.blade.php b/resources/views/emails/partials/account_logo.blade.php index c750e0c0d487..94d54db64c12 100644 --- a/resources/views/emails/partials/account_logo.blade.php +++ b/resources/views/emails/partials/account_logo.blade.php @@ -3,7 +3,7 @@ @endif - {{ trans('texts.logo') }} + {{ trans('texts.logo') }} @if ($account->website)