From a064e60a0e699a0c9ed5a1b56da4affc648aec67 Mon Sep 17 00:00:00 2001 From: Joel Butcher Date: Thu, 23 Feb 2023 15:36:41 +0000 Subject: [PATCH] Fix for Laravel 10 --- src/CreatesMailers.php | 120 ++++++++++++++++++++++++++++ src/HeloLaravelServiceProvider.php | 122 ++++------------------------- src/MailManager.php | 20 +++++ src/Mailer.php | 2 +- 4 files changed, 156 insertions(+), 108 deletions(-) create mode 100644 src/CreatesMailers.php create mode 100644 src/MailManager.php diff --git a/src/CreatesMailers.php b/src/CreatesMailers.php new file mode 100644 index 0000000..0cba6e2 --- /dev/null +++ b/src/CreatesMailers.php @@ -0,0 +1,120 @@ +getConfig(); + + // Once we have create the mailer instance, we will set a container instance + // on the mailer. This allows us to resolve mailer classes via containers + // for maximum testability on said classes instead of passing Closures. + $mailer = new Mailer( + $app['view'], $app['swift.mailer'], $app['events'] + ); + + if ($app->bound('queue')) { + $mailer->setQueue($app['queue']); + } + + // Next we will set all of the global addresses on this mailer, which allows + // for easy unification of all "from" addresses as well as easy debugging + // of sent messages since they get be sent into a single email address. + foreach (['from', 'reply_to', 'to'] as $type) { + $this->setGlobalAddress($mailer, $config, $type); + } + + return $mailer; + } + + protected function createLaravel7Mailer($app) + { + $defaultDriver = $app['mail.manager']->getDefaultDriver(); + $config = $this->getConfig($defaultDriver); + + // Laravel 7 no longer bindes the swift.mailer: + $swiftMailer = new Swift_Mailer($app['mail.manager']->createTransport($config)); + + // Once we have create the mailer instance, we will set a container instance + // on the mailer. This allows us to resolve mailer classes via containers + // for maximum testability on said classes instead of passing Closures. + $mailer = new Laravel7Mailer( + 'smtp', $app['view'], $swiftMailer, $app['events'] + ); + + if ($app->bound('queue')) { + $mailer->setQueue($app['queue']); + } + + // Next we will set all of the global addresses on this mailer, which allows + // for easy unification of all "from" addresses as well as easy debugging + // of sent messages since they get be sent into a single email address. + foreach (['from', 'reply_to', 'to', 'return_path'] as $type) { + $this->setGlobalAddress($mailer, $config, $type); + } + + return $mailer; + } + + protected function createLaravel9Mailer($app) + { + $defaultDriver = $app['mail.manager']->getDefaultDriver(); + $config = $this->getConfig($defaultDriver); + + // We get Symfony Transport from Laravel 9 mailer + $symfonyTransport = $app['mail.manager']->getSymfonyTransport(); + + // Once we have create the mailer instance, we will set a container instance + // on the mailer. This allows us to resolve mailer classes via containers + // for maximum testability on said classes instead of passing Closures. + $mailer = new Laravel7Mailer( + 'smtp', $app['view'], $symfonyTransport, $app['events'] + ); + + if ($app->bound('queue')) { + $mailer->setQueue($app['queue']); + } + + // Next we will set all of the global addresses on this mailer, which allows + // for easy unification of all "from" addresses as well as easy debugging + // of sent messages since they get be sent into a single email address. + foreach (['from', 'reply_to', 'to', 'return_path'] as $type) { + $this->setGlobalAddress($mailer, $config, $type); + } + + return $mailer; + } + + protected function getConfig($name = 'smtp') + { + return $this->app['config']['mail.driver'] + ? $this->app['config']['mail'] + : $this->app['config']["mail.mailers.{$name}"]; + } + + /** + * Set a global address on the mailer by type. + * + * @param \Illuminate\Mail\Mailer $mailer + * @param array $config + * @param string $type + * @return void + */ + protected function setGlobalAddress($mailer, array $config, $type) + { + if (version_compare(app()->version(), '7.0.0', '<')) { + $address = Arr::get($config, $type); + } else { + $address = Arr::get($config, $type, $this->app['config']['mail.'.$type]); + } + + if (is_array($address) && isset($address['address'])) { + $mailer->{'always' . Str::studly($type)}($address['address'], $address['name']); + } + } +} diff --git a/src/HeloLaravelServiceProvider.php b/src/HeloLaravelServiceProvider.php index a180592..ae0022f 100644 --- a/src/HeloLaravelServiceProvider.php +++ b/src/HeloLaravelServiceProvider.php @@ -3,15 +3,15 @@ namespace BeyondCode\HeloLaravel; use Illuminate\Contracts\Mail\Mailer as MailerContract; -use Illuminate\Support\Arr; use Illuminate\Support\Facades\Mail; use Illuminate\Support\Facades\View; use Illuminate\Support\ServiceProvider; -use Illuminate\Support\Str; use Swift_Mailer; class HeloLaravelServiceProvider extends ServiceProvider { + use CreatesMailers; + /** * Bootstrap the application services. */ @@ -21,11 +21,8 @@ public function boot() return; } - $instance = app()->make(Mailer::class); - - Mail::swap($instance); - app()->instance(MailerContract::class, $instance); + $this->bootMailable(); if ($this->app->runningInConsole()) { View::addNamespace('helo', __DIR__ . '/../resources/views'); @@ -50,7 +47,7 @@ public function register() $this->mergeConfigFrom(__DIR__.'/../config/helo.php', 'helo'); $this->app->singleton(Mailer::class, function ($app) { - $version = (int) Str::of($app->version())->explode('.')->first(); + $version = $this->version($app); if ($version < 7) { return $this->createLaravel6Mailer($app); @@ -63,114 +60,25 @@ public function register() }); } - protected function createLaravel6Mailer($app) + protected function bootMailable() { - $config = $this->getConfig(); + if ($this->version() < 10) { + $instance = app()->make(Mailer::class); - // Once we have create the mailer instance, we will set a container instance - // on the mailer. This allows us to resolve mailer classes via containers - // for maximum testability on said classes instead of passing Closures. - $mailer = new Mailer( - $app['view'], $app['swift.mailer'], $app['events'] - ); + Mail::swap($instance); - if ($app->bound('queue')) { - $mailer->setQueue($app['queue']); - } - - // Next we will set all of the global addresses on this mailer, which allows - // for easy unification of all "from" addresses as well as easy debugging - // of sent messages since they get be sent into a single email address. - foreach (['from', 'reply_to', 'to'] as $type) { - $this->setGlobalAddress($mailer, $config, $type); - } - - return $mailer; - } - - protected function createLaravel7Mailer($app) - { - $defaultDriver = $app['mail.manager']->getDefaultDriver(); - $config = $this->getConfig($defaultDriver); - - // Laravel 7 no longer bindes the swift.mailer: - $swiftMailer = new Swift_Mailer($app['mail.manager']->createTransport($config)); - - // Once we have create the mailer instance, we will set a container instance - // on the mailer. This allows us to resolve mailer classes via containers - // for maximum testability on said classes instead of passing Closures. - $mailer = new Laravel7Mailer( - 'smtp', $app['view'], $swiftMailer, $app['events'] - ); - - if ($app->bound('queue')) { - $mailer->setQueue($app['queue']); - } - - // Next we will set all of the global addresses on this mailer, which allows - // for easy unification of all "from" addresses as well as easy debugging - // of sent messages since they get be sent into a single email address. - foreach (['from', 'reply_to', 'to', 'return_path'] as $type) { - $this->setGlobalAddress($mailer, $config, $type); - } - - return $mailer; - } - - protected function createLaravel9Mailer($app) - { - $defaultDriver = $app['mail.manager']->getDefaultDriver(); - $config = $this->getConfig($defaultDriver); - - // We get Symfony Transport from Laravel 9 mailer - $symfonyTransport = $app['mail.manager']->getSymfonyTransport(); - - // Once we have create the mailer instance, we will set a container instance - // on the mailer. This allows us to resolve mailer classes via containers - // for maximum testability on said classes instead of passing Closures. - $mailer = new Laravel7Mailer( - 'smtp', $app['view'], $symfonyTransport, $app['events'] - ); - - if ($app->bound('queue')) { - $mailer->setQueue($app['queue']); - } - - // Next we will set all of the global addresses on this mailer, which allows - // for easy unification of all "from" addresses as well as easy debugging - // of sent messages since they get be sent into a single email address. - foreach (['from', 'reply_to', 'to', 'return_path'] as $type) { - $this->setGlobalAddress($mailer, $config, $type); + $this->app->instance(MailerContract::class, $instance); + } else { + Mail::swap(new MailManager($this->app)); } - - return $mailer; - } - - protected function getConfig($name = 'smtp') - { - return $this->app['config']['mail.driver'] - ? $this->app['config']['mail'] - : $this->app['config']["mail.mailers.{$name}"]; } - /** - * Set a global address on the mailer by type. - * - * @param \Illuminate\Mail\Mailer $mailer - * @param array $config - * @param string $type - * @return void - */ - protected function setGlobalAddress($mailer, array $config, $type) + private function version($app = null): int { - if (version_compare(app()->version(), '7.0.0', '<')) { - $address = Arr::get($config, $type); - } else { - $address = Arr::get($config, $type, $this->app['config']['mail.'.$type]); + if (! $app) { + $app = $this->app; } - if (is_array($address) && isset($address['address'])) { - $mailer->{'always' . Str::studly($type)}($address['address'], $address['name']); - } + return (int) collect(explode('.', $app->version()))->first(); } } diff --git a/src/MailManager.php b/src/MailManager.php new file mode 100644 index 0000000..65d4f0e --- /dev/null +++ b/src/MailManager.php @@ -0,0 +1,20 @@ +createLaravel9Mailer($this->app); + } + + return $this->mailers[$name] = $this->get($name); + } +} diff --git a/src/Mailer.php b/src/Mailer.php index 67ead7a..27f632c 100644 --- a/src/Mailer.php +++ b/src/Mailer.php @@ -27,7 +27,7 @@ public function send($view, array $data = [], $callback = null) protected function applyDebugHeaders(Mailable $mailable) { $methodName = method_exists($mailable, 'withSymfonyMessage') ? 'withSymfonyMessage' : 'withSwiftMessage'; - + $mailable->$methodName(function ($message) use ($mailable) { $viewFile = $view = $viewContent = $viewData = null;