RonasIT / laravel-empty-project

7 stars 2 forks source link

Mailer uses a 'default' queue instead of 'mails' #66

Closed Goodmain closed 5 months ago

Goodmain commented 9 months ago

At the BaseMail class we have a build() method where the queue was set. It worked until the 8th version of Laravel where they changed a Mailer class. Also they removed a build method from the documentation:

Laravel 8: https://laravel.com/docs/8.x/mail#configuring-the-sender

Laravel 9+: https://laravel.com/docs/9.x/mail#configuring-the-sender

I also found that we are using incorrect directory for the mails. It should be Mail instead of Mails, because an artisan command creates a new Mails there.

image

And finally, this is the current structure of Mail. Could we use the modern format instead of old one?

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;

class OrderShipped extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * Create a new message instance.
     */
    public function __construct()
    {
        //
    }

    /**
     * Get the message envelope.
     */
    public function envelope(): Envelope
    {
        return new Envelope(
            subject: 'Order Shipped',
        );
    }

    /**
     * Get the message content definition.
     */
    public function content(): Content
    {
        return new Content(
            view: 'view.name',
        );
    }

    /**
     * Get the attachments for the message.
     *
     * @return array<int, \Illuminate\Mail\Mailables\Attachment>
     */
    public function attachments(): array
    {
        return [];
    }
}
Goodmain commented 9 months ago

Here is my idea

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;

abstract class BaseMail extends Mailable implements ShouldQueue
{
    use Queueable;
    use SerializesModels;

    public int $tries = 5;

    public function __construct(public array $data = [])
    {
        $this->queue = 'mails';
    }

    abstract public function envelope(): Envelope;

    abstract public function content(): Content;
}

And the mail example

use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;

class SecurityCodeMail extends BaseMail
{
    public function __construct(array $data, public bool $isDeletion)
    {
        parent::__construct($data);
    }

    public function envelope(): Envelope
    {
        return new Envelope(
            subject: 'Your security code',
        );
    }

    public function content(): Content
    {
        return new Content(
            view: ($this->isDeletion) ? 'emails.security_code_deletion' : 'emails.security_code',
            with: $this->data
        );
    }
}

We also should make the following changes at the Laravel Helpers:


    protected function assertFixture(array $expectedMailData, Mailable $mail, bool $exportMode = false): void
    {
        // before: $mailContent = view($mail->view, $mail->viewData)->render();
        $mailContent = $mail->render();

I think that the usage of Content and Envelope makes our BaseModal more flexible because Laravel added a new formats for email (markdown and text) and an Envelope class also has a lot of parameters (tags, metadata).

DenTray commented 9 months ago

@Goodmain good idea! Let's implement new format inside the EmptyProject repo, about the LaravelHelpers package - I believe we should keep backward compatibility and add some checks for the current app version