简体   繁体   中英

Laravel 5.4 vendor publish component not working

I'm attempting to modify the template for e-mails on an older website I did, running Laravel 5.4

I do eventually plan to update to at least Laravel 5.5, and possibly Laravel 5.7 - but I don't want to do that right now unless strictly necessary (it would involve some significant re-writes to some of my controllers and a lot of extra testing)

I ran:

php artisan vendor:publish --tag=laravel-mail

This created files in resources/views/vendor/mail

I then edited these files and tried sending a message. No change.

I then edited the files in vendor/laravel/framework/src/Illuminate/Mail/resources/views/ and sent a message - the new template showed up.

So despite the existence of the resources/views/vendor/mail folder, Laravel is still reading from the vendor/ folder after running php artisan vendor:publish . How do I fix this? What am I doing wrong?

Update

Some additional info, in case it helps. Here's my mail template ( resources/views/mail/email-a-friend.blade.php ):

@component('mail::message')

Your friend, {{ $senderName }}, has sent you information about a property they feel you might be interested in.


This property is listed by {{ config('app.name') }}. To view this property and more like it, please click the link below.


@if($agent->id !== $property->agent->id)
[{{ url($property->url()) }}?agent={{ $agent->first_name }}-{{ $agent->last_name }}]({{ url($property->url()) }}?agent={{ $agent->first_name }}-{{ $agent->last_name }})
@else
[{{ url($property->url()) }}]({{ url($property->url()) }})
@endif
@if($text != "")


They also sent this message:


@component('mail::panel')
{{ $text }}
@endcomponent
@endif
@endcomponent

Here's the controller that queues up the e-mail ( app/http/Controllers/AjaxController.php - just the relevant function):

public function emailAFriend(Request $request)
{
    $property = \App\Models\Property\Property::find($request->input('property-id'));
    $agent = $property->agent;
    if ($request->input('agent-id') !== $agent->id) {
        $agent = \App\User::find($request->input('agent-id'));
    }

    Mail::to($request->input('send-to'))
        ->queue(new \App\Mail\EmailAFriend($property, $agent, $request->input('name'), $request->input('reply-to'), $request->input('text')));

    return Response::json("success", 200);
}

Here's the Mailable ( app/Mail/EmailAFriend.php ):

<?php

namespace App\Mail;

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

use App\Models\Property\Property;
use App\User;

class EmailAFriend extends Mailable
{
    use Queueable, SerializesModels;

    public $subject = "Someone sent you a property!";

    public $property;
    public $agent;
    public $senderName;
    public $senderEmail;
    public $text;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct(Property $property, User $agent, $name, $email, $text)
    {
        $this->subject = "$name sent you information about a property";

        $this->property = $property;
        $this->agent = $agent;
        $this->senderName = $name;
        $this->senderEmail = $email;
        $this->text = $text;
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this->markdown('emails.email-a-friend')
                    ->replyTo($this->senderEmail, $this->senderName)
                    ->attachData(
                        $this->property->generatePdf(['agent' => $this->agent])->inline(),
                        "{$this->property->details->lot_size} acres in {$this->property->location->county} county.pdf",
                        [
                            'mime' => 'application/pdf'
                        ]
                    );
    }
}

For testing purposes I'm using the sync QueueDriver, so this sends immediately upon the AJAX request being made. In production I use the database QueueDriver.

Update 2

The components:

resources/views/vendor/mail/html/message.blade.php :

@component('mail::layout')
    {{-- Header --}}
    @slot('header')
        @component('mail::header', ['url' => config('app.url')])
            <img src="{{ url('/img/layout/logo.png') }}" alt="{{ config('app.name') }}" />
        @endcomponent
    @endslot

    {{-- Body --}}
    {{ $slot }}

    {{-- Subcopy --}}
    @if (isset($subcopy))
        @slot('subcopy')
            @component('mail::subcopy')
                {{ $subcopy }}
            @endcomponent
        @endslot
    @endif

    {{-- Footer --}}
    @slot('footer')
        @component('mail::footer')
            &copy; {{ date('Y') }} {{ config('app.name') }}. All rights reserved.
        @endcomponent
    @endslot
@endcomponent

resources/views/vendor/mail/markdown/message.blade.php :

@component('mail::layout')
    {{-- Header --}}
    @slot('header')
        @component('mail::header', ['url' => config('app.url')])
            ![{{ config('app.name') }}]({{ url('/img/layout/logo.png') }})
        @endcomponent
    @endslot

    {{-- Body --}}
    {{ $slot }}

    {{-- Subcopy --}}
    @if (isset($subcopy))
        @slot('subcopy')
            @component('mail::subcopy')
                {{ $subcopy }}
            @endcomponent
        @endslot
    @endif

    {{-- Footer --}}
    @slot('footer')
        @component('mail::footer')
            © {{ date('Y') }} {{ config('app.name') }}. All rights reserved.
        @endcomponent
    @endslot
@endcomponent

The difference between these two and the default components ( vendor/laravel/framework/src/Illuminate/Mail/resources/views/html/message.blade.php and the markdown equivalent) is in the header:

{{ config('app.name') }}
replaced with:
<img src="{{ url('/img/layout/logo.png') }}" alt="{{ config('app.name') }}" />

I was attempting to replace the company name with their logo. When I go into vendor/laravel/framework/src/Illuminate/Mail/resources/views/markdown/message.blade.php and edit this file directly, I do see the logo in the resulting e-mail. So despite the existence of the published component, it's still reading from the vendor/ directory (and editing the vendor/ directory is no good, because then the change won't persist in production)

So after digging through the Laravel source for over an hour, I finally figured this out.

  1. The Markdown renderer loads components from its componentPaths variable
  2. The componentPaths variable gets set by loadComponentFrom()
  3. loadComponentsFrom is called in the constructor of the Markdown renderer and passed $options['paths']

Knowing this I started looking into "Laravel markdown options paths" and found the following: https://stackoverflow.com/a/44264874/436976

I updated config/mail.php and added the recommended lines and it worked perfectly! I feel like vendor:publish should have done this for me, or there should have at least been some mention of this step in the official Laravel documentation , but fortunately I figured this out in under a day - so that's always nice

Note (Further Research)

It turns out this was mentioned in the official Laravel documentation, just not where I expected.

My website was originally a Laravel 5.1 site that was upgraded to 5.2, then to 5.3, and then ultimately to 5.4 before it went live (I never updated to 5.5 because once the site was live I wanted to minimize changes to the underlying framework)

With each Laravel upgrade I kept rolling forward the old files from the config/ directory and I apparently did a poor job of following the upgrade guides, because they are pretty clear:

https://laravel.com/docs/5.4/upgrade

New Configuration Options

In order to provide support for Laravel 5.4's new Markdown mail components, you should add the following block of configuration to the bottom of your mail configuration file:

'markdown' => [
    'theme' => 'default',
    'paths' => [
        resource_path('views/vendor/mail'),
    ],
],

Had I updated my configuration file as directed, I would never have had these issues.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM