ytake / Laravel.Smarty

smarty template engine for laravel
MIT License
84 stars 24 forks source link

Artisan queue:work command does not clear assignments in mailables #86

Open linushstge opened 1 year ago

linushstge commented 1 year ago

In Version 6 and 7 there is an issue with assigned template variables in relation with the queue:work command. Instead of queue:listen queue:work does not always boot Laravel so the existing Smarty Instance is kept.

Steps to reproduce

  1. Create two Mailables
  2. Create a simple smarty template where the variable is dumped
  3. Assign a variable only to the first mailable view
  4. Queue both Mails

Result in queue:listen: As expected, the variable gets only applied to the first mailable Result in queue:work: The variable is dumped in both templates

Example files

App/Mail/TestMail1.php

<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;

class TestMail1 extends Mailable
{
    use Queueable;

    public function build()
    {
        $this->view('mail.test', [
            'example' => 'assigned to first mailable'
        ]);

        return $this;
    }
}

App/Mail/TestMail2.php

<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;

class TestMail2 extends Mailable
{
    use Queueable;

    public function build()
    {
        // "example" is not applied here
        $this->view('mail.test');

        return $this;
    }
}

templates/mail/test.tpl

<pre>{$example}</pre>

TestController.php

Mail::queue(new TestMail1());
Mail::queue(new TestMail2());

Required Changes

Smarty assignments have to be cleared on each Mailable.

In the current implementation, there is a risk that variables that are not overwritten by a second Mailable are erroneously transmitted in an email.

Notes

linushstge commented 1 year ago

Update

I was able to figure out that the error does not only occur in the mailables, but globally in the entire application. As soon as variables are assigned to any template, the existing variables are also applied to all following templates.

Example:

$template1 = view('mail.test',['example' => 'assigned to first template'])->render();
$template2 = view('mail.test')->render();

echo $template1;
// <pre>assigned to first template</pre> (expected)

echo $template2;
// <pre>assigned to first template</pre> (unexpected)

To fix this issue, all previous assignments have to be cleared for uncached template fetches as suggested in #87