【问题标题】:Laravel 5.4 vendor publish component not workingLaravel 5.4 供应商发布组件不起作用
【发布时间】:2019-07-17 14:07:14
【问题描述】:

我正在尝试在运行 Laravel 5.4 的旧网站上修改电子邮件模板

我最终确实计划至少更新到 Laravel 5.5,并且可能会更新到 Laravel 5.7 - 但我现在不想这样做,除非绝对必要(这将涉及对我的一些控制器和很多额外测试)

我跑了:

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

这在resources/views/vendor/mail中创建了文件

然后我编辑了这些文件并尝试发送消息。没有变化。

然后我编辑了vendor/laravel/framework/src/Illuminate/Mail/resources/views/ 中的文件并发送了一条消息 - 新模板出现了。

因此,尽管存在 resources/views/vendor/mail 文件夹,但 Laravel 在运行 php artisan vendor:publish 后仍在读取 vendor/ 文件夹。我该如何解决?我做错了什么?

更新

一些附加信息,以防万一。这是我的邮件模板 (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

这是排队电子邮件的控制器(app/http/Controllers/AjaxController.php - 只是相关功能):

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);
}

这是可邮寄的 (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'
                        ]
                    );
    }
}

出于测试目的,我使用了sync QueueDriver,因此它会在发出 AJAX 请求后立即发送。在生产中,我使用database QueueDriver。

更新 2

组件:

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

这两个和默认组件(vendor/laravel/framework/src/Illuminate/Mail/resources/views/html/message.blade.php 和 markdown 等效项)之间的区别在于标题:

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

我试图用他们的徽标替换公司名称。当我进入vendor/laravel/framework/src/Illuminate/Mail/resources/views/markdown/message.blade.php 并直接编辑此文件时,我确实在生成的电子邮件中看到了徽标。因此,尽管存在已发布的组件,它仍然从 vendor/ 目录读取(编辑 vendor/ 目录不好,因为这样更改不会在生产中持续存在)

【问题讨论】:

  • 我将从非常基本的清空视图缓存开始,你可以试试php artisan view:clear吗?
  • 另外当你说你自定义了组件时,你是否同时更新了markdown和html?
  • @MihirBhende 希望这是一个简单的修复方法,但没有这样的运气。它仍在从vendor 目录而不是resources/views/vendor 目录读取。是的,我确实自定义了 HTML 和 markdown 组件。我会将这些附加到我的帖子中。
  • config/mail.php有修改吗?
  • @MihirBhende 我没有对config/mail.php 进行任何更改。事实上,config/mail.php 的大部分内容都被忽略了,因为我正在使用 .env 覆盖 MAIL_DRIVERMAIL_HOSTMAIL_PORTMAIL_USERNAMEMAIL_PASSWORDMAIL_ENCRYPTIONMAIL_FROM_ADDRESS 和 @ 987654358@.

标签: php laravel laravel-5


【解决方案1】:

所以在挖掘 Laravel 源代码一个多小时后,我终于弄明白了。

  1. Markdown 渲染器从其componentPaths 变量加载组件
  2. componentPaths 变量由loadComponentFrom() 设置
  3. 在 Markdown 渲染器的构造函数中调用loadComponentsFrom 并传递$options['paths']

知道这一点后,我开始研究“Laravel 降价选项路径”并发现以下内容:https://stackoverflow.com/a/44264874/436976

我更新了config/mail.php 并添加了推荐的行,效果很好!我觉得 vendor:publish 应该为我做这件事,或者至少应该在 official Laravel documentation 中提到这一步,但幸运的是我在一天之内就解决了这个问题 - 所以这总是很好

注意(进一步研究)

事实证明,这个在 Laravel 官方文档中被提及,只是没有达到我的预期。

我的网站最初是一个 Laravel 5.1 网站,在上线之前升级到 5.2,然后升级到 5.3,最后升级到 5.4(我从未更新到 5.5,因为一旦网站上线,我想尽量减少对底层的更改框架)

在每次 Laravel 升级时,我都会从 config/ 目录中前滚旧文件,显然我在遵循升级指南方面做得很差,因为它们非常清楚:

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

新的配置选项

为了支持 Laravel 5.4 的新 Markdown 邮件组件,您应该在邮件配置文件的底部添加以下配置块:

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

如果我按照指示更新了我的配置文件,我将永远不会遇到这些问题。

【讨论】:

    猜你喜欢
    • 2016-12-10
    • 2019-01-25
    • 1970-01-01
    • 2016-10-05
    • 2017-10-17
    • 2016-02-08
    • 2015-04-21
    • 2018-01-27
    • 2017-11-04
    相关资源
    最近更新 更多