spatie / laravel-blade-comments

Add debug comments to your rendered output
https://freek.dev/2500-a-laravel-package-to-quickly-see-which-html-is-rendered-by-which-blade-view
MIT License
162 stars 9 forks source link

[Bug]: Call to undefined method name() when previewing a Mailable in the browser #23

Closed mi-dave closed 6 months ago

mi-dave commented 10 months ago

What happened?

When I preview a Mailable in the browser, I get this error:

Call to undefined method App\Mail\TestMailable::name()

The backtrace points to Spatie\BladeComments\Commenters\RequestCommenters\ViewCommenter line 17:

$viewName = $response->original->name();

The problem is $response->original is an instance of Mailable not View.

How to reproduce the bug

Create a standard mailable:

class TestMailable extends Mailable
{
    use Queueable, SerializesModels;

    public function envelope(): Envelope
    {
        return new Envelope(
            subject: 'Test Mailable',
        );
    }

    public function content(): Content
    {
        return new Content(
            view: 'mail.test-mailable',
        );
    }

    public function attachments(): array
    {
        return [];
    }

    // Uncomment this as a workaround
    // public function name()
    // {
    //     return $this->content()->view;
    // }
}

Create a view for it:

<p>Content to go here...</p>

Create a route that returns the mailable:

class MailTestController extends Controller
{
    public function testMailable()
    {
        return new TestMailable();
    }
}

Open the route in the browser - it should give the error.

Uncomment the name() method above - it should work correctly.

Package Version

1.2.2

PHP Version

8.1.25

Laravel Version

10.26.2

Which operating systems does with happen with?

Linux

Notes

Here's a possible fix:

    public function comment(Request $request, Response $response): ?string
    {
        if (! $response instanceof LaravelResponse) {
            return null;
        }

        $viewName = null;

        if ($response->original instanceof View) {
            $viewName = $response->original->name();
        } elseif ($response->original instanceof Mailable) {
            $viewName = $response->original->view;
        }

        return $viewName ? "<!-- View: {$viewName} -->" : null;
    }

I don't know if $response->original->view can be null in practice, but it seems like a good idea to handle that case as the Mailable rendering code is complex!

Thanks!

spatie-bot commented 6 months ago

Dear contributor,

because this issue seems to be inactive for quite some time now, I've automatically closed it. If you feel this issue deserves some attention from my human colleagues feel free to reopen it.