bonsaicms/settings

Laravel 的设置管理器

2.0.0 2022-03-08 17:40 UTC

This package is auto-updated.

Last update: 2024-09-08 23:20:52 UTC


README

市面上有一些针对 Laravel 的“设置包”,例如 anlutro/laravel-settingsakaunting/setting,但我们认为我们可以做得更好。

例如,这个包可以保存设置中的任何值(数字、字符串、布尔值等,也可以是任何对象,例如 Eloquent 模型)。

工作原理

  1. 该包使用 PHP 的 serializebase64_encode 函数序列化设置值。
  2. 将值存储在 text 数据库列类型中(如果您使用 DatabaseSettingsRepository)。
  3. 读取设置值时,使用 PHP 的 base64_decode 函数解码序列化的值,然后使用 PHP 的 deserialize 函数反序列化。

安装

$ composer require bonsaicms/settings

发布配置文件

$ php artisan vendor:publish --tag=settings

运行迁移

$ php artisan migrate

自动加载中间件

在您的 app/Http/Kernel.php 文件中添加以下行。此中间件将自动在每次请求之前调用 Settings::all(),因此当您调用 Settings::get() 时,将不会执行 DB 查询,因为所有设置已经存在于缓存中。

protected $middleware = [
    ...
+   \BonsaiCms\Settings\Http\Middleware\LoadSettings::class,
];

自动保存中间件

在您的 app/Http/Kernel.php 文件中添加以下行。此中间件将自动在每次请求之后调用 Settings::save(),因此您不需要手动调用它。

protected $middleware = [
    ...
+   \BonsaiCms\Settings\Http\Middleware\SaveSettings::class,
];

用法

Settings::set('someting', 1);
Settings::get('someting'); // 1

Settings::set('someting', 1.2);
Settings::get('someting'); // 1.2

Settings::set('someting', true);
Settings::get('someting'); // true

Settings::set('someting', null);
Settings::get('someting'); // null

Settings::has('someting'); // true
Settings::has('sometingElse'); // false

// Eloquent models ...
$model = SomeEloquentModel::first();
Settings::set('model', $model);
Settings::get('model')->is($model); // true

// Mass...
Settings::set([
    'a' => 'A',
    'b' => 'B',
    'c' => 'C',
]);
Settings::get(['a', 'b', 'x']);
/* new Collection([
    'a' => 'A',
    'b' => 'B',
    'x' => null
]) */

设置/获取 Eloquent 模型

为了让它工作,您的模型需要实现我们的 BonsaiCms\Settings\Contracts\SerializationWrappable 接口。您可以自行实现序列化逻辑,也可以使用我们的 BonsaiCms\Settings\Models\SerializableModelTrait trait。

我们的 BonsaiCms\Settings\Models\SerializableModelTrait 不会 序列化模型属性!它只会序列化模型标识(模型名称 + ID),并在您调用 Settings::get(...) 时从数据库检索该模型。

// MyModel extends Eloquent
$model = MyModel::first(); // some model instance (not null)
Settings::set('model', $model);
$retrievedModel = Settings::get('model');
Settings::save();

// On the same or on the some future request as well...
$retrievedModel->is($model); // true

如果您需要不同的序列化行为,您需要通过实现我们的 BonsaiCms\Settings\Contracts\SerializationWrappable 接口来自行实现序列化逻辑。

模型类示例

use Illuminate\Database\Eloquent\Model as Eloquent;

class MyModel extends Eloquent implements \BonsaiCms\Settings\Contracts\SerializationWrappable
{
    use \BonsaiCms\Settings\Models\SerializableModelTrait;
    ...

拥有

Settings::set('someting', 1);

Settings::has('someting'); // true
Settings::has('sometingElse'); // false

保存

Settings::save(); // This will save changes into the repository (database)

删除

Settings::set('someting', 1);
Settings::has('someting'); // true
Settings::deleteAll();
Settings::has('someting'); // false
Settings::get('someting'); // null

用于删除设置的 Artisan 命令

这将在内部调用 Settings::deleteAll()

$ php artisan settings:delete-all

外观与辅助函数

还有一个可用的 settings() 辅助函数。

Settings::set('a', 'b');
settings('a', 'b');

Settings::set(['a' => 'A', 'b' => 'B']);
settings(['a' => 'A', 'b' => 'B']);

Settings::get('a');
settings('a');

Settings::has('a');
settings()->has('a');

Settings::save();
settings()->save();

Settings::deleteAll();
settings()->deleteAll();

在设置中保存自己的对象

您的任何类都可以实现我们的 BonsaiCms\Settings\Contracts\SerializationWrappable 接口。它应该实现这两个方法

interface SerializationWrappable
{
    static function wrapBeforeSerialization($wrappable);

    static function unwrapAfterSerialization($wrappedClass, $wrappedValue);
}

示例实现

use BonsaiCms\Settings\Contracts\SerializationWrappable;

class MyClass implements SerializationWrappable
{
    /*
     * You should map the $wrappable object to some "wrapped value" here and return it.
     * The returned value should describe the object so you can re-create it again in the method below.
     * This value should be just primitive (string, number, array ...) because it will be serialized
     * and persisted in settings repository.
     */
    static function wrapBeforeSerialization($wrappable)
    {
        return [
            'something' => 'some-wrapped-value'        
        ];
    }

    /*
     * This method should return the original `$wrappable` passed to method above.
     */
    static function unwrapAfterSerialization($wrappedClass, $wrappedValue)
    {
        /*
         * $wrappedClass; // MyClass::class
         * $wrappedValue; // ['something' => 'some-wrapped-value']
         */
        return new MyClass; // You can pass $wrappedValue to the constructor
    }
}

然后您可以简单地写下

$myObject = new MyClass;
Settings::set('obj', $myObject);
Settings::get('obj'); // same as $myObject (but probably not equal, depends on what you return in `unwrapAfterSerialization` method
Settings::save('obj');

设置和类似 JSON 的 API

您需要通过 API 与设置一起工作吗?请查看我们的 bonsaicms/settings-api 包。

测试

$ composer install
$ ./vendor/bin/phpunit