12/08/2018, 14:20

Một vòng Laravel (Part 2)

Nối tiếp lọat bài về Một vòng laravel, chúng ta sẽ đi tiếp các nội dung còn lại, bao gồm: Localization Authorization (Access Control List) Mail Schedule Event Job Inversion Of Control Service Provider Contracts Facade Localization Một tính năng khá hay mà laravel hỗ trợ, ...

Nối tiếp lọat bài về Một vòng laravel, chúng ta sẽ đi tiếp các nội dung còn lại, bao gồm:

  • Localization
  • Authorization (Access Control List)
  • Mail
  • Schedule
  • Event
  • Job
  • Inversion Of Control
  • Service Provider
  • Contracts
  • Facade

Localization

Một tính năng khá hay mà laravel hỗ trợ, giúp một website hỗ trợ cùng lúc nhiều ngôn ngữ. Với mỗi language, ta sẽ tạo 1 folder trong resource/language, hiện tại laravel tạo mặc định 1 folder en

/resource
    /language
        /en
            messages.php

file messages.php sẽ return một mảng gồm key string và text muốn show ra view

<?php
    return [
        'title': 'Title',
        'welcome': 'Welcome to our website',
    ];

default language sẽ được set mặc định trong config/app.php, ta có thể thay đổi default language này bằng facade App

App::setLocale($whateverYouWant);

Truy cập vào các string bằng cách dùng trans() method.

{{ trans('messages.welcome') }}
//Welcome to our website

Truyền tham số vào text, sử dụng cú pháp :param

    return [
        'title': 'Title',
        'welcome': 'Welcome to our website, :name',
    ];
{{ trans('messages.welcome', ['name' => 'James'] }}
//Welcome to our webste, James

Authorization

Laravel hỗ trợ 2 cách đẻ authorize user: Gates và Policies. Về căn bản thì 2 cách thức này là như nhau, ta define các rule (method) dùng để authorize, và khi cần thì call ra.

Gates Gates chủ yếu dùng cho việc authorize các action riêng lẻ. Ta sẽ define các rule này trong method boot của AuthServiceProvider, sử dụng facade Gate. Ví dụ ta muốn chỉ có admin mới có quyền udpate product, ta sẽ làm như sau:

public function boot()
{
    $this->registerPolicies();

    Gate::define('update-product', function ($user, $post) {
        return $user->type == 'admin';
    });
}

Sau khi define rule này, ta sẽ dùng nó ở bất cứ đâu ta muốn bằng lệnh call allow hoặc deny:

if (Gate::allows('update-product', $post)) {
    // The current user can update the product...
}

if (Gate::denies('update-product', $post)) {
    // The current user can't update the product...
}

Còn một cách nữa để sử dụng các rule, là dùng User::can hoặc User::cant, nhưng cách này sẽ ưu tiên sử dụng các rule từ Policies trước, nếu nó không tìm được thì mới tìm đến Gates, và sẽ được đề cập sau.

Policies Khác đôi chút với Gates, Policies sẽ tóm gọn các rule liên quan tới 1 model hoặc resource cụ thể vào thành 1 class. và thường áp dụng Policies với 1 model cụ thể nào đó. ok, giờ tạo 1 Policy để vọc nào:

php artisan make:policy ProductPolicy --model=Product

Khi make policies với --model=Product, thì laravel sẽ tạo sẵn cho ta 4 method: view, create, update và delete. Viết lại update cho giống với Gate

    public function update(User $user, Product $product)
    {
        return $user->type === 'admin';
    }

Sử dụng qua Model: như trên đã nói, Policies thường đi kèm với 1 model nào đó nhằm authorize các action trên model đó. Ta có thể sử dụng như sau:

if ($user->can('update', $product)) {
    //update product
}

Sử dụng qua Middleware (cách tôi hay dùng): mặc định thì middleware IlluminateAuthMiddlewareAuthorize được gán key, đó là lý do ta có thể dùng lệnh $this->authorize('update', $product); mà không gặp vấn đề gì. Ta sẽ dùng middleware can để authorize:

Route::put('/products/{id}', function (Product $product) {
    // The current user may update the product...
})->middleware('can:update,product');

Sử dụng qua template Blade

@can('update', $product)
     
@endcan

@cannot('update', $product)
     
@endcannot
0