Skip to content

TheDragonCode/laravel-model-settings

Repository files navigation

Laravel Model Settings

Laravel Model Settings

Stable Version Total Downloads License

Persist settings for individual Eloquent models, with defaults shared by each model type.

Requirements

  • PHP 8.3+
  • Laravel 12+

Installation

Install the package via Composer:

composer require dragon-code/laravel-model-settings

Publish the config and migration, then run the migration:

php artisan vendor:publish --tag="model_settings"
php artisan migrate

Usage

Add HasSettings to an Eloquent model:

use DragonCode\LaravelModelSettings\Concerns\HasSettings;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    use HasSettings;
}

Use settings on a saved model:

$user = User::query()->findOrFail(123);

$user->settings()->set('timezone', 'UTC');
$user->settings()->set('notifications', ['email' => true]);

$timezone = $user->settings()->get('timezone');      // UTC
$timezone = $user->settings()->get('notifications'); // ['email' => true]
$settings = $user->settings()->all();

$user->settings()->forget('timezone');
$user->settings()->get('timezone');      // null

Calling set() with a blank value removes the setting. Blank values include null, an empty string, and an empty array.

Default Settings

Default settings are fallback values shared by models of the same type:

$user->defaultSettings()->set('timezone', 'UTC');

$user->settings()->get('timezone'); // 'UTC'

$user->settings()->set('timezone', 'Europe/Paris');
$user->settings()->get('timezone'); // 'Europe/Paris'

$user->settings()->forget('timezone');
$user->settings()->get('timezone'); // 'UTC'

You can also set default settings by creating a model:

(new User)->defaultSettings()->set('timezone', 'UTC');

Model values take priority over defaults. Passing a blank value to set() removes the setting, exposing the default again. Settings support integer, UUID, and ULID model keys, string, integer, and PHP enum setting keys.

Default settings are stored with the model morph class and item_id = 0.

API

Method Returns Description
all() Collection Returns defaults merged with model settings.
get(UnitEnum|string|int $key) mixed Returns the model value, default, or null.
set(UnitEnum|string|int $key, mixed $value) void Creates, updates, or removes a setting.
forget(UnitEnum|string|int $key) void Removes a setting.

Setting Keys

Keys can be strings, integers, or PHP enums:

enum UserSetting: string { case Timezone = 'timezone'; }

$user->settings()->set(UserSetting::Timezone, 'UTC');

$timezone = $user->settings()->get(UserSetting::Timezone);

Payload Casts

Without a custom cast, payloads are decoded as arrays, scalar values, or null. Configure a cast per model in config/model_settings.php:

return ['casts' => [App\Models\User::class => App\Data\UserSettingsData::class]];

The class may implement Laravel's CastsAttributes contract. spatie/laravel-data Data classes are also supported when installed.

Configuration

Published config/model_settings.php accepts these options:

Option Default Purpose
model DragonCode\LaravelModelSettings\Models\Settings Eloquent model for persisted settings.
connection env('DATABASE_CONNECTION') Database connection.
table settings Settings table.
casts [] Payload casts by parent model class.

MODEL_SETTINGS_DATABASE_CONNECTION and MODEL_SETTINGS_DATABASE_TABLE override the connection and table. A payload cast may implement Laravel's CastsAttributes contract. Spatie Laravel Data classes are also supported when installed.

return [
    'model' => App\Models\Setting::class,
    'casts' => [
        App\Models\User::class => App\Data\UserData::class,
        App\Models\Post::class => App\Casts\PostCast::class,
    ],
];

Testing

composer test
composer test:coverage

Contributing

See CONTRIBUTING.

Security

Report security vulnerabilities to helldar@dragon-code.pro.

Credits

License

The MIT License (MIT). See License File.

About

Model Settings for your Laravel application

Resources

License

Contributing

Stars

1 star

Watchers

1 watching

Forks

Sponsor this project

Contributors