algolia search

Tìm thấy x bài viết trong xms.

Trong các ứng dụng, sẽ rất là có ích khi có một cách  nào đó để lưu trữ một số cài đặt chung cho toàn hệ thống. Các cài đặt này không liên quan đến một Model cụ thể nào, chẳng hạn như người dùng, nhưng lại cần cho toàn bộ hệ thống. Dĩ nhiên, bạn có thể làm được điều này với Eloquent (lưu trong cơ sở dữ liệu), nhưng đối với tôi chưa bao giờ cảm thấy đó là cách tiếp cận đúng khi mà cơ sở dữ liệu phi quan hệ trong một hệ thống dữ liệu quan hệ.

Tôi đã tìm thấy gói Valuestore của Spatie hoàn toàn phù hợp để tạo kho lưu trữ cài đặt cho một ứng dụng.

Gói này sẽ thực hiện lưu trữ cài đặt của bạn dưới dạng tệp JSON trên hệ thống tệp cục bộ. Chúng ta hãy cùng đi vào một ví dụ cụ thể thử xem nhé:

Ở đầu website của bạn có một thông báo gì đó (một tấm ảnh thông báo). Thông báo biểu ngữ này hiển thị trên mọi trang và quản trị viên có thể cập nhật văn bản chứa thông báo.

Cài đặt Valuestore

Để bắt đầu, bạn sẽ phải cài đặt gói này

composer require spatie/valuestore

Bây giờ bạn có thể tạo một Valuestore bằng cách chỉ định đường dẫn trên ổ đĩa (disk) bạn muốn các thiết lập được đọc và ghi vào. Tôi muốn tập tin cài đặt của tôi được lưu ở storage/app/settings.json

// tạo route trong file routes/web.php
Route::post('banner-notification/update', 'BannerNotificationController@update');

// tạo một controller BannerNotificationController class
// và trong function update
public function update(Request $request)
{
    $settings = Valuestore::make(storage_path('app/settings.json'));

    $settings->put('banner_notification', $request->banner_notification);

    return redirect()->back()->with(['notice' => 'Settings updated']);
}

Như bạn có thể thấy trong đoạn mã này, tôi sẽ thêm yêu cầu nhập banner_notification vào Valuestore. Phía bên dưới, gói Valustore sẽ encoding JSON các giá trị và lưu trữ chúng trên hệ thống tập tin trong tập tin settings.json. Gói này sẽ quản lý tệp này cho chúng ta, vì vậy nếu nó không tồn tại, nó sẽ tạo tệp đó và nếu ta xóa tất cả các giá trị, tệp sẽ tự xóa tệp để dọn dẹp.

API của package Valuestore này có dạng gần giống với cách sử dụng Cache trong Laravel, vì vậy tôi nghĩ rằng bạn sẽ dễ dàng làm quen với nó nhanh thôi.

Bạn hiện có thể truy cập các cài đặt này ở những nơi khác trong ứng dụng của mình. Để làm như vậy, bạn sẽ cần phải khởi tạo Valuestore với cùng một đường dẫn mà chúng ta đã chỉ định trước đó. (xem thêm: Laravel: __invoke trong Controller)

// trong controller...

public function __invoke()
{
    $settings = Valuestore::make(storage_path('app/settings.json'));

    return view('homepage', ['settings' => $settings]);
}

// ở ngoài view...

@if($settings->has('banner_notification'))
    <div class="banner-notification">
        {{ $settings->get('banner_notification') }}
    </div>
@endif

Valuestore là một cách thực sự tốt để lưu trữ một số giá trị lỏng lẻo mà không cần phải được lưu giữ lâu dài vào cơ sở dữ liệu. Không có migration, không có model, chỉ là tệp JSON chứa cài đặt của bạn. Sự phù hợp hoàn hảo cho một số cặp key/value cơ bản. Chỉ cần đảm bảo bạn đặt tệp cài đặt của mình ở vị trí không thể truy cập công khai (như thư mục public - đặt trong /storages/... sẽ là ok nhất).

Toàn bộ cách sử dụng gói này ở đây, trước khi đến đoạn hay hơn dưới đây, bạn nên xem qua cách sử dụng nhé

Trói Valuestore vào container

Trong ví dụ ở trên, bạn có thể thấy rằng chúng ta phải tạo Valuestore một vài lần và chúng ta viết lại khởi tạo logic ở một vài nơi, vì vậy thay vì sao chúng ta không ràng buộc các thiết lập của chúng ta vào container để chúng ta có thể có sự khởi tạo logic được chỉ định ở một nơi. Điều này cũng sẽ cho chúng ta khả năng tiêm (inject) Valuestore vào controller của chúng ta.

Đầu tiên chúng ta sẽ tạo ra một lớp Settings của chúng ta để mở rộng Valuestore.

<?php

namespace App;

use Spatie\Valuestore\Valuestore;

class Settings extends Valuestore
{
    //
}

Tiếp theo, chúng ta sẽ bind đối tượng Setting vào Container như một singleton trong Provider nào đó chẳng hạn như AppServiceProvider.

Khúc này bạn phải có kiến thức về container - singleton - Dependency Injection mới hiểu, còn không copy làm theo nha, giải thích mấy cái kiến thức này là cả một series đó

// AppServiceProvider...

public function register()
{
    $this->app->singleton(Settings::class, function () {
        return Settings::make(storage_path('app/settings.json'));
    });
}

Bây giờ chúng ta có thể inject các thiết lập của chúng ta vào controller với Dependency Injection như cách dùng Request, ...

public function update(Request $request, Settings $settings)
{
    $settings->put('banner_notification', $request->banner_notification);

    return redirect()->back()->with(['notice' => 'Settings updated']);
}

Tinh chỉnh để sử dụng global helper

Tôi thấy việc thêm một setting() cũng rất hữu ích khi bạn muốn truy cập các setting này trong các views của bạn. Đến đây hẳn là bạn sẽ xem qua bài viết này Tạo helpers function tùy biến trong Laravel 5  (nếu chưa biết) trước khi đi xuống dưới nha

if (!function_exists('settings'))
{
    // helpers.php

    function settings($key = null, $default = null) {
        if ($key === null) {
            return app(App\Settings::class);
        }

        return app(App\Settings::class)->get($key, $default);
    }
}

Trong views, bạn có thể truy xuất setting thông qua global helper function. Điều này đặc biệt hữu ích chẳng hạn như thông báo biểu ngữ, là cần thiết trên mọi trang.

// ngoài view...

<div class="banner-notification">

    {{ settings()->get('banner_notification') }}

        {{-- or --}}

    {{ settings('banner_notification') }}

</div>

Tôi thực sự thích sự đơn giản mà gói này, và giới thiệu để cho bạn cách lưu trữ đơn giản không cần csdl. Tôi luôn cảm thấy lưu trữ loại dữ liệu này trong cơ sở dữ liệu với một số loại thiết lập cặp key/value chưa bao giờ hoàn toàn đúng (đang đá wordpress 😆). Nếu bạn cần một số cài đặt ứng dụng có sẵn trên toàn cục, tôi chắc chắn khuyên bạn nên xem gói Valuestore của Spatie.

Cảm ơn Spatie!

Chung Nguyễn cũng xin được gửi lời cảm ơn đến Laravel News

Đánh giá bài viết

Thích thì like
Laravel Global Application Settings (Cấu hình toàn cục)
3/5 2 votes

Bình luận

x2teamno1 avatar
x2teamno1
Bạn sử dụng cái gì mà click vào đánh giá nó bật cái hộp thoại ở góc trái màn hình vậy? bạn có bài hướng dẫn thiết lập sử dụng chức năng đó ko nhỉ? Hỳ
Chung Nguyễn avatar
Chung Nguyễn
Hiển thị bình luận Facebook