Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Octane] Error because of MailManager replacement #27

Closed
maxeckel opened this issue Apr 6, 2021 · 4 comments · Fixed by #50
Closed

[Octane] Error because of MailManager replacement #27

maxeckel opened this issue Apr 6, 2021 · 4 comments · Fixed by #50

Comments

@maxeckel
Copy link

maxeckel commented Apr 6, 2021

Hey Folks,

I've just installed Octane (using Swoole) in a project where also Helo is used.
The Workers constantly throw errors, telling that "setApplication()" does not exist on the Laravel7Mailer:

Method BeyondCode\HeloLaravel\Laravel7Mailer::setApplication does not exist.

at vendor/laravel/framework/src/Illuminate/Macroable/Traits/Macroable.php:103
     99▕      */
    100▕     public function __call($method, $parameters)
    101▕     {
    102▕         if (! static::hasMacro($method)) {
  ➜ 103▕             throw new BadMethodCallException(sprintf(
    104▕                 'Method %s::%s does not exist.', static::class, $method
    105▕             ));
    106▕         }
    107▕ 

I've chased this down to the call to Mail::swap($instance) in the HeloLaravelServiceProvider:26 .
As by calling this method the underlying MailManager binding is swapped, this error appears.

If you are fine with e.g. adding a new Laravel8Mailer (which would add support for the setApplication method), as Octane requires Laravel 8, I'd be happy to PR this addition :)
If you have another solution in mind (like adding the methods on the current mailer), I'd also be happy to take on the implementation ;)

Best regards,

Max

@mpociot
Copy link
Member

mpociot commented May 11, 2021

Hi @maxeckel,

A Laravel8Mailer class would be a great solution for this. A PR would be great, thank you! :)

@maxeckel
Copy link
Author

Hey @mpociot,

Thanks for the update!

I'll add a PR as soon as possible!

@abishekrsrikaanth
Copy link

@maxeckel any updates on a PR for this?

@2h4services
Copy link

I got this running, but I haven't tested it fully

src/HeloLaravelServiceProvider.php

     /**
     * Register the application services.
     */
    public function register()
    {
       ...
        $this->app->singleton(Mailer::class, function ($app) {
            if (version_compare($app->version(), '7.0.0', '<')) {
                return $this->createLaravel6Mailer($app);
            }

           //---[Changed]---
            if (version_compare($app->version(), '8.0.0', '<')) {
                return $this->createLaravel7Mailer($app);
            }

            return $this->createLaravel8Mailer($app);
        });
    }
    //Added method
    protected function createLaravel8Mailer($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 Laravel8Mailer(
            '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;
    }

New src/Laravel8Mailer.php

<?php

namespace BeyondCode\HeloLaravel;

use Illuminate\Contracts\Mail\Factory as MailFactory;
use Illuminate\Contracts\Mail\Mailer as MailerContract;

class Laravel8Mailer extends Mailer implements MailerContract, MailFactory
{
    public function mailer($name = null)
    {
        $this->currentMailer = $name;

        return $this;
    }

    /**
     * Set laravel application.
     *
     * @param \Illuminate\Contracts\Container\Container $app
     */
    public function setApplication($app)
    {
        $this->app = $app;
    }

    /**
     * Forget all of the resolved mailer instances.
     *
     * @return $this
     */
    public function forgetMailers()
    {
        $this->mailers = [];

        return $this;
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants