2016-09-22 96 views
3

我想重写Laravels的Mail类的facade方法发送(只是拦截它强制一些检查,然后如果它通过触发parent :: send())如何覆盖Laravel Facade方法?

这样做的最佳方法是什么?

+1

你不应该有梅勒进行检查,这不是它的工作,它只是发送邮件。该逻辑应在外部执行,如果邮件应发送,请调用send方法。 – tam5

+0

@tam您正在谈论可维护性和结构,而且我知道,最好不要将责任交给邮件程序。但问题不在于此。 – naneri

回答

6

门面不能这样工作。它本质上就像一个包装类,它调用它所代表的基础类。

Mail外观实际上没有send方法。当您做Mail::send()时,引擎盖下的“外观访问器”用于引用在IoC容器中绑定的Illuminate\Mail\Mailer类的实例。正是在这个对象上调用了send方法。

你可以实现你所追求的方式实际上比看起来有点棘手。你可以做的是:

  • 写自己实现Mailer,延长Illuminate\Mail\Mailer,在其中您可以覆盖send方法,实现你的支票,并呼吁parent::send()
  • 写下您自己的服务提供商(扩展Illuminate\Mail\MailServiceProvider),特别是重新实施register方法。它应该创建一个你自己的实例来代替Laravel自己的实例Mailer。 (您可以从Laravel的register方法中复制大部分代码)。现在
  • ,在config/app.php文件时,providers阵列中,用自己的供应商更换Illuminate\Mail\MailServiceProvider::class,

这应该让你挂接到Laravel的邮件功能。


欲了解更多信息,你可以看看下面的问题/答案,实现类似的事情。它扩展了邮件功能以添加新的传输驱动程序,但它采用了类似的方法,因为它提供了自己的邮件程序实现和服务提供程序。

Add a new transport driver to Laravel's Mailer


应用程序/ MyMailer/Mailer.php

<?php 

namespace App\MyMailer; 

class Mailer extends \Illuminate\Mail\Mailer 
{ 
    public function send($view, array $data = [], $callback = null) 
    { 
     // Do your checks 

     return parent::send($view, $data, $callback); 
    } 
} 

应用程序/ MyMailer/MailServiceProvider.php(大部分从Laravel的MailServiceProvider类复制的代码的)

<?php 

namespace App\MyMailer; 

class MailServiceProvider extends \Illuminate\Mail\MailServiceProvider 
{ 
    public function register() 
    { 
     $this->registerSwiftMailer(); 

     $this->app->singleton('mailer', function ($app) { 
      // This is YOUR mailer - notice there are no `use`s at the top which 
      // Looks for a Mailer class in this namespace 
      $mailer = new Mailer(
       $app['view'], $app['swift.mailer'], $app['events'] 
      ); 

      $this->setMailerDependencies($mailer, $app); 


      $from = $app['config']['mail.from']; 

      if (is_array($from) && isset($from['address'])) { 
       $mailer->alwaysFrom($from['address'], $from['name']); 
      } 

      $to = $app['config']['mail.to']; 

      if (is_array($to) && isset($to['address'])) { 
       $mailer->alwaysTo($to['address'], $to['name']); 
      } 

      return $mailer; 
     }); 
    } 
} 

配置/ app.php(在供应商阵列)

//... 
// Illuminate\Mail\MailServiceProvider::class, 
App\MyMailer\MailServiceProvider::class, 
//... 
+0

如何从回叫中检索电子邮件? – naneri

+0

你是什么意思? – Jonathon

+0

查看我更新的答案,了解一些示例代码 – Jonathon