12/08/2018, 15:24

Laravel: Mail (Phần 1)

Laravel cung cấp API rất đơn giản thông qua thư viện [SwiftMailer](http://swiftmailer.org/) với drivers SMTP, Mailgun, SparkPost, Amazon SES, hàm ```mail``` của PHP, và ```sendmail```, cho phép bạn nhanh chóng bắt đầu gửi mail qua dịch vụ mail local hay cloud tuỳ theo lựa chọn của bạn. Driver ...


Laravel cung cấp API rất đơn giản thông qua thư viện [SwiftMailer](http://swiftmailer.org/) với drivers SMTP, Mailgun, SparkPost, Amazon SES, hàm ```mail``` của PHP, và ```sendmail```, cho phép bạn nhanh chóng bắt đầu gửi mail qua dịch vụ mail local hay cloud tuỳ theo lựa chọn của bạn.

Driver Prerequisites


Các API dựa trên driver như Mailgun và SparkPost thường đơn giản và nhanh hơn SMTP server. Nếu có thể, bạn nên sử dụng trong những dirver này. Tất cả các API driver yêu cầu sử dụng thư viện Guzzle HTTP có thể cài đặt thông qua Composer: ``` composer require guzzlehttp/guzzle ```
_**Mailgun Driver**_

Để sử dụng Mailgun driver, đầu tiên cần cài Guzzle, sau đó cấu hình driver trong file config/mail.php vào mailgun. Tiếp theo, xác định rằng file config/services.php của bạn cấu hình theo options:

'mailgun' => [
    'domain' => 'your-mailgun-domain',
    'secret' => 'your-mailgun-key',
]

_**SparkPost Driver**_

Để sử dụng SparkPost driver, đầu tiên cần phải cài đặt Guzzle, sau đó tùy chỉnh driver trong file cấu hình config/mail.php vào sparkpost. Tiếp theo, bạn phải cấu hình file config/services.php theo options sau:

'sparkpost' => [
    'secret' => 'your-sparkpost-key',
],

_**SES Driver**_

Để sử dụng Amazon SES driver bạn cần phải cài đặt Amazon AWS SDK cho PHP. Bạn có thể cài đặt thư viện này bằng cách thêm 1 dòng vào phần require trong file composer.json và chạy lệnh composer update:

"aws/aws-sdk-php": "~3.0"

Tiếp theo, đặt tùy chỉnh driver trong file config/mail.php vào ses và xác định file cấu hình config/services.php được cấu hình theo options:

'ses' => [
    'key' => 'your-ses-key',
    'secret' => 'your-ses-secret',
    'region' => 'ses-region',  // e.g. us-east-1
],

Generating Mailables


Trong Laravel, mỗi loại email được gửi đi bởi ứng dụng của bạn được đại diện như một class "mailable". Các class đó được lưu trong thư mục ```app/Mail```. Đừng lo lắng nếu bạn không nhìn thấy đường dẫn đó trong ứng dụng của bạn, vì nó sẽ được tạo ra khi bạn tạo class mailable lần đầu tiên bằng cách dùng lệnh ```make:mail```: ``` php artisan make:mail OrderShipped ```
# Writing Mailables
Tất cả của một class mailable đều được cấu hình trong phương thức ```build```. Bên trong hàm này, bạn có thể gọi nhiều phương thức như ```from```, ```subject```, ```view```, và ```attach``` để cấu hình mail nhận.
### Configuring The Sender
_**Using The ```from``` Method**_ Đầu tiên, hãy tìm hiểu cấu hình email của người gửi. Hoặc, theo một nghĩa khác, người gửi mail là "from". Có hai cách để cấu hình người gửi. Đầu tiên, bạn có thể sử dụng phương thức ```from``` cùng với phương thức ```build``` của class mailable của bạn: ``` /** * Build the message. * * @return $this */ public function build() { return $this->from('example@example.com') ->view('emails.orders.shipped'); } ```
_**Using A Global ```from``` Address**_ Tuy nhiên, nếu ứng dụng của bạn sử dụng địa chỉ "from" cho tất cả các mail, nó có thể trở lên dài dòng để gọi hàm ```from``` trong mỗi class mailable bạn tạo ra. Thay vì, bạn có thể chỉ định địa chỉ "from" trong file cấu hình ```config/mail.php```. Địa chỉ này sẽ được sử dụng nếu không có địa chỉ "from" được chỉ định của class mailable: ``` 'from' => ['address' => 'example@example.com', 'name' => 'App Name'], ```
**Configuring The View** Hàm ```build``` trong class mailable, bạn có thể sử dụng hàm ```view``` để chỉ định template được sử dụng khi render nội dung email. Vì mỗi email sử dụng [Blade template](https://laravel.com/docs/5.4/blade) để render nội dung, bạn có toàn quyền và thoải mái xây dựng Blade templating HTML: ``` /** * Build the message. * * @return $this */ public function build() { return $this->view('emails.orders.shipped'); } ```

Plain Text Emails Nếu bạn muốn định nghĩa một phiên bản plain-text cho email của bạn, bạn có thể sử dụng hàm text. Giống như hàm view, hàm text nhận một tên template sẽ được sử dụng để render nội dung của email. Nếu bạn định thoải mái nghĩa một HTML và một phiên bản plain-text cho message của bạn:

/**
 * Build the message.
 *
 * @return $this
 */
public function build()
{
    return $this->view('emails.orders.shipped')
                ->text('emails.orders.shipped_plain');
}

View Data
Via Public Properties Thông thường, bạn sẽ muốn truyền một số data vào trong view của bạn muốn sử dụng khi render ra HTML. Có hai cách bạn có thể hiển thị dữ liệu trong view. Thứ nhất, bất cứ thuộc tính public được định nghĩa trong class mailable sẽ được tự động tồn tại trong view. Vì vậy, ví dụ, bạn có thể truyền dữ liệu có thuộc tính public vào trong hàm khởi tạo của class mailable và đặt dữ liệu bạn muốn truyền vào trong đó:

<?php

namespace AppMail;

use AppOrder;
use IlluminateBusQueueable;
use IlluminateMailMailable;
use IlluminateQueueSerializesModels;

class OrderShipped extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * The order instance.
     *
     * @var Order
     */
    public $order;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct(Order $order)
    {
        $this->order = $order;
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this->view('emails.orders.shipped');
    }
}

Mỗi dữ liệu được set một thuộc tính public, nó sẽ tự động trở thành có sẵn trong view của bạn, vì vậy bạn có thể truy cập nó giống như bạn truy cập bất cứ dữ liệu nào khác trong Blade templates:

<div>
    Price: {{ $order->price }}
</div>

_**Via The ```with``` Method:**_

Nếu bạn muốn tùy biến định dạng data trước khi gửi nó vào template, bạn có thể tùy biến data của bạn vào view qua phương thức with. Thông thường, bạn sẽ vẫn truyền data qua hàm khởi tạo của class mailable; tuy nhiên, bạn nên đặt data thành thuộc tính protected hoặc privatevì data sẽ không tự động được tạo sẵn trong view template. Sau đó, khi gọi phương thức with, truyền một mảng data bạn muốn vào trong template:

<?php

namespace AppMail;

use AppOrder;
use IlluminateBusQueueable;
use IlluminateMailMailable;
use IlluminateQueueSerializesModels;

class OrderShipped extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * The order instance.
     *
     * @var Order
     */
    protected $order;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct(Order $order)
    {
        $this->order = $order;
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this->view('emails.orders.shipped')
                    ->with([
                        'orderName' => $this->order->name,
                        'orderPrice' => $this->order->price,
                    ]);
    }
}

Khi data đã được truyền vào phương thức with, nó sẽ tự động tồn tại ở trong view, bạn có thể truy cập bình thường như khi sử dụng dữ liệu với Blade templates:

<div>
    Price: {{ $orderPrice }}
</div>

**Attachments** Để đính kèm vào email, sử dụng phương thức ```attach``` cùng với phương thức ```build``` của class mailable. Phương thức ```attach``` chấp nhận đường dẫn đầy đủ của file là tham số thứ nhất: ``` /** * Build the message. * * @return $this */ public function build() { return $this->view('emails.orders.shipped') ->attach('/path/to/file'); } ``` Khi đính kèm các file vào một message, bạn cũng có thể ghi rõ display name và / hoặc MIME type bằng cách truyền vào ```array``` như là tham số thứ hai của phương thức ```attach```: ``` /** * Build the message. * * @return $this */ public function build() { return $this->view('emails.orders.shipped') ->attach('/path/to/file', [ 'as' => 'name.pdf', 'mime' => 'application/pdf', ]); } ```
_Raw Data Attachments_ Phương thức ```attachData``` có thể sử dụng để đính kèm một raw string của bytes như một đính kèm. Ví dụ, bạn có thể sử dụng phương thức này nếu bạn muốn sinh một PDF trong memory và muốn đính kèm nó vào email mà không cần viết nó vào ổ cứng. Phương thức ```attachData``` chấp nhận dữ liệu dạng raw data bytes là tham số thứ nhất, tên của file là tham số thứ hai, và một mảng tùy biến là tham số thứ ba: ``` /** * Build the message. * * @return $this */ public function build() { return $this->view('emails.orders.shipped') ->attachData($this->pdf, 'name.pdf', [ 'mime' => 'application/pdf', ]); } ```
_**Inline Attachments**_ Nhúng inline images vào emails thường không đơn giản; tuy nhiên, Laravel cung cấp một cách khá thuận tiện để bạn đính kèm ảnh vào emails và nhận CID thích hợp. Để nhúng một ảnh inline images, sử dụng phương thức ```embed``` trên biến ```$message``` cùng với email template. Laravel tự động tạo biến ```$message``` tồn tại cho tất cả email templates, vì vậy bạn không cần phải truyền nó một cách thủ công: ``` <body> Here is an image:
<img src="{{ $message->embed($pathToFile) }}">
</body> ```
_Embedding Raw Data Attachments_ Nếu bạn có một raw data string bạn muốn nhúng vào email template, bạn có thể sử dụng phương thức ```embedData``` trên biến ```$message```: ``` <body> Here is an image from raw data:
<img src="{{ $message->embedData($data, $name) }}">
</body> ```
**Customizing The SwiftMailer Message** Phương thức ```withSwiftMessage``` của class ```Mailable``` cho phép bạn đăng ký 1 callback sẽ được gọi với raw SwiftMailer message instance trước khi gửi message. Điều này sẽ cho bạn một cơ hội để tùy chỉnh message trước khi nó được gửi: ``` /** * Build the message. * * @return $this */ public function build() { $this->view('emails.orders.shipped');
    $this->withSwiftMessage(function ($message) {
        $message->getHeaders()
                ->addTextHeader('Custom-Header', 'HeaderValue');
    });
}

0