Skip to content
This repository has been archived by the owner on Jul 16, 2021. It is now read-only.

Allow sending only text/plain via Mailables #1058

Closed
rask opened this issue Mar 13, 2018 · 12 comments
Closed

Allow sending only text/plain via Mailables #1058

rask opened this issue Mar 13, 2018 · 12 comments

Comments

@rask
Copy link

rask commented Mar 13, 2018

From what I understand Mailables require a HTML view in order to work. If you define only a text view as such

public function build()
{
    return $this->text('view.name');
}

Then the mailable fails with an error saying invalid view [] or similar. After adding a ->view('view.name') to build() the Mailable works OK.

Or is this intended and I'm asking for trouble here? Why can't I just send a text/plain email with a Mailable? I would prefer to have light emails for a light application and setting up HTML emails is a chore and maintaining those is tedious.

@drbyte
Copy link

drbyte commented Mar 13, 2018

You must have an error somewhere.

This works fine to send text-only emails for me:

    public function build()
    {
        return $this->text('emails.text_message_content')
            ->replyTo($this->sender->email, $this->sender->name)
            ->subject($this->subject);
    }

And the view:

@extends('emails.layout_textonly')

{!! $message_text !!}

@rask
Copy link
Author

rask commented Mar 13, 2018

Strange. When I'm testing rendering a mailable inside a TestCase class as such:

$mailable = new Mymailable();

$content = $mailable->render();

with a mailable with no ->view() I either receive an error stating [] is an invalid view or then the $content variable contains the view name similar to view.path.and.name. After I add ->view() then it works as it should.

I need to dig a bit deeper and see if this really is some user error on my end or if this needs a real fix.

@rask
Copy link
Author

rask commented Mar 13, 2018

OK going to paste my current setup (with dummy content) for brevity:

MyMailable

public function setSomeValue($string)
{
    $this->some_value = $string;
}

public function build()
{
    $some_value = (string) $this->some_value;

    return $this->subject('Hello World')
        ->text('mail.hello-world')
        ->with('value', $some_value);
}

resources/views/mail/hello-world.blade.php

Hello World, {{ $value }}!

This is an email from
{{ env('APP_NAME') }}

MyMailableTest

$m = new MyMailable();
$m->setSomeValue('foobar');

$m_content = $m->render();

$this->assertContains('foobar', $m_content);

With this setup when I run

vendor/bin/phpunit

I receive

InvalidArgumentException: View [] not found

But when I alter MyMailable::build() to include the view() call as follows

public function build()
{
    $some_value = (string) $this->some_value;

    return $this->subject('Hello World')
        ->view('mail.hello-world')
        ->text('mail.hello-world')
        ->with('value', $some_value);
}

Then everything works as expected and the assertion succeeds in my test case.

@AkenRoberts
Copy link

@rask You're not going crazy! The Mailer class appears to handle render() and send() differently, the latter of which has proper checks to skip the HTML view if it isn't defined. render() doesn't:

public function render($view, array $data = [])
{
    // First we need to parse the view, which could either be a string or an array
    // containing both an HTML and plain text versions of the view which should
    // be used when sending an e-mail. We will extract both of them out here.
    list($view, $plain, $raw) = $this->parseView($view);

    $data['message'] = $this->createMessage();

    return $this->renderView($view, $data);
}

In your case, $view is null, and $plain has your plain-text view name. It simply gets ignored.

Adding in this simple fallback would get your test passing:

list($view, $plain, $raw) = $this->parseView($view);
$view = $view ?: $plain;

I'll submit a PR fix for this momentarily. Appreciate the report! 👍

@rask
Copy link
Author

rask commented Mar 15, 2018

Neat, thanks and no problem! I'll be following update notes. :)

@AkenRoberts
Copy link

@rask Someone was finally able to submit a PR and this should be fixed in Laravel 5.6.18+.

@rask
Copy link
Author

rask commented May 2, 2018

@AkenRoberts Alrighty, good to hear!

@mbaierl
Copy link

mbaierl commented May 8, 2018

Thanks @AkenRoberts!
One question - a "update composer" only installs 5.6.6, but not 5.6.18?

$ composer info laravel/framework
name     : laravel/framework
descrip. : The Laravel Framework.
keywords : framework, laravel
versions : * v5.6.6
type     : library

When will 5.6.18 be available via composer?

@AkenRoberts
Copy link

@mbaierl Laravel 5.6.21 should be the current recent version available on Packagist.

composer info will tell you the version currently installed, not what's available. composer outdated laravel/framework should give you the latest version available.

If composer update isn't giving you anything new, check your composer.json file to see what the version constraint is. Post it here if you're still having issues. :)

@mbaierl
Copy link

mbaierl commented May 9, 2018

Thanks @AkenRoberts - learned something new :-)
Weird thing is - I had
"laravel/framework": "5.6.*",
which did not update to 5.6.21, but
"laravel/framework": "5.6.21",
did....

@acorncom
Copy link

Looks like this can be closed now

@rask
Copy link
Author

rask commented May 24, 2019

I guess so. Thanks everyone!

@rask rask closed this as completed May 24, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants