leeovery/laravel-settings

Laravel Settings - Package for handling user settings with file based defaults and DB custom values.

v2.0 2022-02-18 16:41 UTC

This package is auto-updated.

Last update: 2024-04-18 21:13:19 UTC


README

Latest Version on Packagist Build Status Quality Score Total Downloads

This package allows you to create one or many setting files which store default settings, but also expose an API to edit the settings, and store those edits in the DB. When the settings are fetched the custom values are merged into the defaults.

Most useful for user-based settings, but can be used for a multitude of other reasons.

Best to give a quick example...

Installation

You can install the package via composer:

composer require leeovery/laravel-settings
php artisan vendor:publish --provider="Leeovery\LaravelSettings\LaravelSettingsServiceProvider" --tag="config"

Usage

Given a settings file called /config/settings-user-notifications.php and with the following contents...

return [
    'orders' => [
        'general' => [
            'email'  => true,
            'alerts' => true,
        ],
        'status_change' => [
            'email'  => true,
            'alerts' => true,
        ],
    ],
    ...
];

You can do this to fetch the settings:

$userId = 100;

settings('user-notifications', $userId)->get();

// will return...
'orders' => [
    'general' => [
        'email'  => true,
        'alerts' => true,
    ],
    'status_change' => [
        'email'  => true,
        'alerts' => true,
    ],
],
...

As you can see, this will return all the above settings for user with the ID of 100.

Note that those settings won't be different from the defaults as at this point the user has not made any changes.

Lets change that now...

settings('user-notifications', $userId)->set(['orders.general.email' => false]);

The line above calls set() and passes the key and value. That value is persisted in the DB for that user. So that we can do the following...

settings('user-notifications', $userId)->get();

// will return...
'orders' => [
    'general' => [
        'email'  => false, // NOTE this is different!
        'alerts' => true,
    ],
    'status_change' => [
        'email'  => true,
        'alerts' => true,
    ],
],
...

Returned data now equals all the default values EXCEPT for the nested key orders.general.email where that will equal FALSE, as per the custom change above.

That's the most basic use-case...

But, you can do more...

Multiple Setting Files

You can setup multiple setting files in the config directory, just prepend the filename with settings- (or whatever you configure in the package config file.

Eg:

/config/settings-user-privacy.php /config/settings-social.php /config/settings-user-account-access.php

Now you can get() and set() the settings from those files...

$settings = settings('user-privacy', $userId)->get();
$settings = settings('social', $userId)->get();

Value Object Based Values

You can use objects as the values in the settings file, like this:

return [
    'orders' => [
        'general' => [
            'email'  => SettingStore::make(true, 'You can set a label here'), // option one
            'alerts' => LaravelSettings::setting(true, 'You can set a label here'), // option two
        ],
    ],
    ...
];

Access Subsets Rather Than All Settings

Sometimes you only need a subset of settings. You can do that by specifiying the key with dot notation. Note the package will still fully key the results so that you can use the keys for setting.

Eg:

Given a setting file /config/settings-email-notifications.php:

return [
    'orders' => [
        'general' => [
            'email'  => SettingStore::make(true),
            'alerts' => SettingStore::make(true),
        ],
        'digital' => [
            'status_change' => [
                'email'  => SettingStore::make(true),
                'alerts' => SettingStore::make(true),
            ],
        ],
    ],
    ...
];

You can store a user edit like this:

settings('user-notifications', $userId)->set([
    'orders.digital.status_change.email' => false // just store primitive value here not VO
]);

And... you can access the deep status_change subset like follows:

settings('email-notifications', $userId)->get('orders.digital.status_change');

// will return...
'orders' => [
    'digital' => [
        'status_change' => [
            'email'  => false, // note non-default value
            'alerts' => true,
        ],
    ],
],

As you can see we fully key the results but only return the requested subset.

TODO

  • Can access subsets
  • Caching to cut down on DB queries and general optimise
  • Driver based approach to allow user to change default system and caching layer.
  • SettingStore value validation

Testing

composer test

Changelog

Please see CHANGELOG for more information what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Credits

License

The MIT License (MIT). Please see License File for more information.

Laravel Package Boilerplate

This package was generated using the Laravel Package Boilerplate.