2014-10-24 16 views
12

Tôi đã định cấu hình dịch vụ thư của laravel với trình điều khiển bắt buộc. Không có vấn đề ở đây!nhiều cấu hình thư

Bây giờ, tại thời điểm nhất định trong đơn đăng ký của tôi, tôi cần gửi thư qua gmail.

tôi đã làm một cái gì đó như:

// backup current mail configs 
$backup = Config::get('mail'); 

// rewrite mail configs to gmail stmp 
$new_configs = array(
    'driver' => 'smtp', 
    // ... other configs here 
); 
Config::set('mail', $new_configs); 

// send the email 
Mail::send(... 

// restore configs 
Config::set('mail', $backup); 

việc doens't này, laravel luôn luôn sử dụng các cấu hình giống phi phi. Có vẻ như anh ta khởi tạo dịch vụ thư lúc khởi động script và bỏ qua bất cứ điều gì bạn làm trong khi thực thi.

Làm cách nào để thay đổi cấu hình/hành vi dịch vụ thư trong khi thực thi?

Trả lời

24

Bạn có thể tạo một Swift_Mailer dụ mới và sử dụng rằng:

// Backup your default mailer 
$backup = Mail::getSwiftMailer(); 

// Setup your gmail mailer 
$transport = Swift_SmtpTransport::newInstance('smtp.gmail.com', 465, 'ssl'); 
$transport->setUsername('your_gmail_username'); 
$transport->setPassword('your_gmail_password'); 
// Any other mailer configuration stuff needed... 

$gmail = new Swift_Mailer($transport); 

// Set the mailer as gmail 
Mail::setSwiftMailer($gmail); 

// Send your message 
Mail::send(); 

// Restore your original mailer 
Mail::setSwiftMailer($backup); 
+3

nó hoạt động như một sự quyến rũ. cho những người có thể tìm kiếm, SmtpTransport đến từ việc sử dụng Swift_SmtpTransport như SmtpTransport; – cmancre

+0

Tôi đã sử dụng tính năng này để tạo sự khác biệt giữa e-mail "thông thường" và "hệ thống" e-mail. Hoạt động tuyệt vời, cảm ơn! – Jurgen

+0

Cảm ơn rất tốt. – EGurelli

1

Bạn có thể đặt trên các thiết lập ruồi mail:

Config::set('mail.encryption','ssl'); 
Config::set('mail.host','smtps.example.com'); 
Config::set('mail.port','465'); 
Config::set('mail.username','[email protected]'); 
Config::set('mail.password','password'); 
Config::set('mail.from', ['address' => '[email protected]' , 'name' => 'Your Name here']); 

Có lẽ bạn có thể lưu trữ các thiết lập giá trị trong config/customMail.php và lấy lại chúng bằng Config :: get ('customMail')

+1

Nhưng nó không phải lúc nào cũng hoạt động, bởi vì "$ app" có thể đã được xác định. Vì vậy, nó sẽ không ảnh hưởng đến dòng chảy. –

+0

Điều này có thể sẽ không hoạt động như mong đợi với người dùng đồng thời gửi email cùng một lúc hoặc đặc biệt là khi sử dụng hàng đợi để gửi email. – Yani

+0

@yani Bạn có thể giải thích nhận xét của bạn tại sao điều này sẽ không hoạt động như mong đợi với người dùng đồng thời và hàng đợi không? – developer34

1

Một chút muộn cho bữa tiệc nhưng chỉ muốn mở rộng câu trả lời được chấp nhận và ném vào 2 xu của tôi, trong trường hợp nó tiết kiệm e thời gian. Trong kịch bản của tôi, mỗi người dùng đã đăng nhập có cài đặt SMTP riêng của họ NHƯNG tôi đã gửi thư bằng hàng đợi, điều này khiến cài đặt trở về mặc định sau khi đặt chúng. Nó cũng tạo ra một số vấn đề email đồng thời. Nói tóm lại, vấn đề là

$transport = Swift_SmtpTransport::newInstance($user->getMailHost(), $user->getMailPort(), $user->getMailEncryption()); 
$transport->setUsername($user->getMailUser()); 
$transport->setPassword($user->getMailPassword()); 
$mailer = new Swift_Mailer($transport); 
Mail::setSwiftMailer($mailer); 
//until this line all good, here is where it gets tricky 

Mail::send(new CustomMailable());//this works 
Mail::queue(new CustomMailable());//this DOES NOT WORK 

Sau vài khoảnh khắc của bàn phím bashing tôi nhận ra rằng hàng đợi đang chạy trên một quá trình riêng biệt và do đó Thư :: setSwiftMailer không ảnh hưởng gì cả. Nó chỉ đơn giản là chọn lên các thiết lập mặc định. Do đó, thay đổi cấu hình phải xảy ra tại thời điểm gửi email thực tế chứ không phải khi xếp hàng.

Giải pháp của tôi là mở rộng Lớp có sẵn như sau.

app\Mail\ConfigurableMailable.php 

<?php 

namespace App\Mail; 

use Illuminate\Container\Container; 
use Illuminate\Contracts\Mail\Mailer; 
use Illuminate\Mail\Mailable; 
use Swift_Mailer; 
use Swift_SmtpTransport; 

class ConfigurableMailable extends Mailable 
{ 
    /** 
    * Override Mailable functionality to support per-user mail settings 
    * 
    * @param \Illuminate\Contracts\Mail\Mailer $mailer 
    * @return void 
    */ 
    public function send(Mailer $mailer) 
    { 
     $host  = $this->user->getMailHost();//new method I added on User Model 
     $port  = $this->user->getMailPort();//new method I added on User Model 
     $security = $this->user->getMailEncryption();//new method I added on User Model 

     $transport = Swift_SmtpTransport::newInstance($host, $port, $security); 
     $transport->setUsername($this->user->getMailUser());//new method I added on User Model 
     $transport->setPassword($this->user->getMailPassword());//new method I added on User Model 
     $mailer->setSwiftMailer(new Swift_Mailer($transport)); 

     Container::getInstance()->call([$this, 'build']); 
     $mailer->send($this->buildView(), $this->buildViewData(), function ($message) { 
      $this->buildFrom($message) 
       ->buildRecipients($message) 
       ->buildSubject($message) 
       ->buildAttachments($message) 
       ->runCallbacks($message); 
     }); 
    } 
} 

Và sau đó thay đổi CustomMail để mở rộng ConfigurableMailable thay vì Mailable:

class CustomMail extends ConfigurableMailable {}

Điều này đảm bảo rằng ngay cả gọi Mail::queue(new CustomMail()) sẽ thiết lập các thiết lập email cho mỗi người dùng ngay trước khi gửi. Tất nhiên bạn sẽ phải tiêm người dùng hiện tại vào CustomMail tại một số điểm tức là Mail::queue(new CustomMail(Auth::user()))

Mặc dù đây không phải là giải pháp lý tưởng (ví dụ: nếu gửi email hàng loạt thì tốt hơn là định cấu hình cho người gửi thư một lần chứ không phải trên mỗi email được gửi), tôi thích sự đơn giản của nó và thực tế là chúng tôi không cần thay đổi cài đặt toàn cầu Mail hoặc Config, chỉ có trường hợp $mailer bị ảnh hưởng.

Hy vọng bạn sẽ thấy nó hữu ích!

Các vấn đề liên quan