Persistent settings in Laravel

Overview

Laravel Settings

Build Status Latest Stable Version License

Persistent, application-wide settings for Laravel.

Despite the package name, this package works with Laravel 4, 5, 6, 7 and 8!

Common problems

Installation - Laravel >= 5.5

  1. composer require anlutro/l4-settings
  2. Publish the config file by running php artisan vendor:publish --provider="anlutro\LaravelSettings\ServiceProvider" --tag="config". The config file will give you control over which storage engine to use as well as some storage-specific settings.

Installation - Laravel < 5.5

  1. composer require anlutro/l4-settings
  2. Add anlutro\LaravelSettings\ServiceProvider to the array of providers in config/app.php.
  3. Publish the config file by running php artisan config:publish anlutro/l4-settings (Laravel 4.x) or php artisan vendor:publish (Laravel 5.x). The config file will give you control over which storage engine to use as well as some storage-specific settings.
  4. Optional: add 'Setting' => 'anlutro\LaravelSettings\Facade' to the array of aliases in config/app.php.

Usage

You can either access the setting store via its facade or inject it by type-hinting towards the abstract class anlutro\LaravelSettings\SettingStore.

<?php
Setting::set('foo', 'bar');
Setting::get('foo', 'default value');
Setting::get('nested.element');
Setting::forget('foo');
$settings = Setting::all();
?>

Call Setting::save() explicitly to save changes made.

You could also use the setting() helper:

// Get the store instance
setting();

// Get values
setting('foo');
setting('foo.bar');
setting('foo', 'default value');
setting()->get('foo');

// Set values
setting(['foo' => 'bar']);
setting(['foo.bar' => 'baz']);
setting()->set('foo', 'bar');

// Method chaining
setting(['foo' => 'bar'])->save();

Auto-saving

In Laravel 4.x, the library makes sure to auto-save every time the application shuts down if anything has been changed.

In Laravel 5.x, if you add the middleware anlutro\LaravelSettings\SaveMiddleware to your middleware list in app\Http\Kernel.php, settings will be saved automatically at the end of all HTTP requests, but you'll still need to call Setting::save() explicitly in console commands, queue workers etc.

Store cache

When reading from the store, you can enable the cache.

You can also configure flushing of the cache when writing and configure time to live.

Reading will come from the store, and then from the cache, this can reduce load on the store.

// Cache usage configurations.
'enableCache' => false,
'forgetCacheByWrite' => true,
'cacheTtl' => 15,

JSON storage

You can modify the path used on run-time using Setting::setPath($path).

Database storage

Using Migration File

If you use the database store you need to run php artisan migrate --package=anlutro/l4-settings (Laravel 4.x) or php artisan vendor:publish --provider="anlutro\LaravelSettings\ServiceProvider" --tag="migrations" && php artisan migrate (Laravel 5.x) to generate the table.

Example

For example, if you want to store settings for multiple users/clients in the same database you can do so by specifying extra columns:

<?php
Setting::setExtraColumns(array(
	'user_id' => Auth::user()->id
));
?>

where user_id = x will now be added to the database query when settings are retrieved, and when new settings are saved, the user_id will be populated.

If you need more fine-tuned control over which data gets queried, you can use the setConstraint method which takes a closure with two arguments:

  • $query is the query builder instance
  • $insert is a boolean telling you whether the query is an insert or not. If it is an insert, you usually don't need to do anything to $query.
<?php
Setting::setConstraint(function($query, $insert) {
	if ($insert) return;
	$query->where(/* ... */);
});
?>

Custom stores

This package uses the Laravel Manager class under the hood, so it's easy to add your own custom session store driver if you want to store in some other way. All you need to do is extend the abstract SettingStore class, implement the abstract methods and call Setting::extend.

<?php
class MyStore extends anlutro\LaravelSettings\SettingStore {
	// ...
}
Setting::extend('mystore', function($app) {
	return $app->make('MyStore');
});
?>

Contact

Open an issue on GitHub if you have any problems or suggestions.

License

The contents of this repository is released under the MIT license.

Comments
  • Publish config file fails

    Publish config file fails

    Im getting the following error when running the config publish command.

    php artisan config:publish anlutro/l4-settings

    exception 'Symfony\Component\Debug\Exception\FatalErrorException' with message 'Call to undefined method Illuminate\Config\Repository::package()' in /Users/Thomas/Documents/OAD/Projects/Project/vendor/anlutro/l4-settings/src/ServiceProvider.php:57 Stack trace: #0 /Users/Thomas/Documents/OAD/Projects/Project/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php(116): Illuminate\Foundation\Bootstrap\HandleExceptions->fatalExceptionFromError(Array) #1 [internal function]: Illuminate\Foundation\Bootstrap\HandleExceptions->handleShutdown() #2 {main}

    opened by tlorentzen 13
  • DatabaseSettingsStore  results caching help

    DatabaseSettingsStore results caching help

    Trying to extend the DatabaseSettingStore class to caching the database results but i don't have any idea how to extend & use the extended class in app. Any help will be appreciated.

    MY Store Class

    use anlutro\LaravelSettings\DatabaseSettingStore;
    class MyStore extends DatabaseSettingStore {
    	protected function write(array $data){
    			cache()->forget('settings');
    			parent::write();
    	}
    	protected function read(){
    		return cache()->rememberForever('settings', function() {
    			return parent::read();
    		});
    	}
    }
    

    Don't no where i have to place the below code in laravel. Whether i have to place the below code in Laravel AppServiceProvider?

    Setting::extend('mystore', function($app) {
    	return $app->make('MyStore');
    });
    
    opened by rajasekar-d 11
  • Support arrays in ::get

    Support arrays in ::get

    It would be cool to be able to get multiple settings like:

    $settings = Setting::get(['finance.vat_rate', 'app_name']);
    

    Return:

    [
        'finance' => [
            'vat_rate' => 20,
        ],
        'app_name' => 'My App'
    ]
    
    opened by garygreen 9
  • Settings::fake() and Settings::assertSaved() for testing?

    Settings::fake() and Settings::assertSaved() for testing?

    Hello. I have my app with a few settings. I want to test the route admin.settings.update: I am currently using the json store.

        public function testSettingsUpdate() 
        {
            $user = factory(User::class)->create();
    
            // It should mock internally the "save" method
            Settings::fake(); 
    
            $this->actingAs($user)
                ->post(route('admin.settings.update'), [
                    'collections' => [123, 456, 789] 
                ]))
                ->assertOk();
    
            // Should assert if the Settings::saved() was called
            Settings::assertSaved();
            $this->assertEquals(Settings::get('home.collections.0'), 123);
            $this->assertEquals(Settings::get('home.collections.1'), 456);
            $this->assertEquals(Settings::get('home.collections.2'), 789);
        }
    

    Yes... this could be done with dependency injection. But... The spirit of Laravel is to test easily, do you think?

    So... It would be great to have those two methods:

    Setting::fake();
    Settings::assertSaved();
    
    discussion 
    opened by jhm-ciberman 8
  • Settings are not saving into database

    Settings are not saving into database

    I have installed this repo to my laravel 5.6.12 and write this code

            setting()->set('foo', 'my value');
            setting()->save();
    

    But my I didn't get anything in my settings table. Is there any thing I am missing?

    question 
    opened by manojrhr 7
  • Every setting is saved multiple times in every request

    Every setting is saved multiple times in every request

    Laravel version: 5.5.40 PHP version: 7.0

    I added this code in a controller to save some settings in database:

    `$key = $request->key; $value = $request->value;

        $setting->set($key, $value);
    
        $setting->setExtraColumns([
            'display_name' => $key,
            'type' => 'text',
        ]);
    
        $setting->save();
    
        return $setting->all();`
    

    The problem is that when I save a new setting all the previous settings are resaved in database, making table growing so fast. Please someone tell me what I am doing wrong. Thank you.

    duplicate 
    opened by carlost89 7
  • Running the built-in migration is optional

    Running the built-in migration is optional

    Before, the built-in migration run when you run php artisan migrate in Laravel ≥ 5.3 regardless, you couldn't even change the migration. Now you can install the migration to the database/migrations directory if you need it by running php artisan vendor:publish --provider="anlutro\LaravelSettings\ServiceProvider" --tag="migrations" and change the migration.

    Resolves #91 and #81.

    Also I've fixed the php artisan vendor:publish command syntax in the readme (in Laravel 5.* you need to specify the service class name, not the package name).

    enhancement 
    opened by Finesse 7
  • Problem with reserved word in oracle

    Problem with reserved word in oracle

    I have a problem when try to save a setting using oracle, because the table column is called "key" which is a Oracle reserved word. It's possible in some way set a custom name for package table columns?

    bug help wanted 
    opened by alancherosr 7
  • [Laravel 4.2] Not getting the correct setting for individual user

    [Laravel 4.2] Not getting the correct setting for individual user

    Hi, thank you for this amazing package.

    I have 1 problem though. Even though I have setExtraColumns, I am not getting the correct value from setting for each user with Setting::all()

    What could be the reason?

    I'm using Cartalyst/Sentry for authentication. Thank you for your help.

    opened by 2eddy 7
  • add ability to load default values from config file 'defaults' array…

    add ability to load default values from config file 'defaults' array…

    … that will be used before any settings are set, this avoids all settings being set to false to begin with and avoids hardcoding the same defaults in all 'Settings::get()' calls, raises minimum php version to 5.4

    enhancement 
    opened by robbielove 6
  • Configuration File

    Configuration File

    In Laravel 5.5, when I run

    php artisan vendor:publish --provider="anlutro/l4-settings" --tag="config"

    I expect a local configuration file in config/

    I see a config file in vendor folder, but this folder is in my .gitignore

    Running php artisan vendor:publish publishes the file as expected to config/

    opened by egknight 6
  • Add support for NULL setting value to DatabaseSettingStore

    Add support for NULL setting value to DatabaseSettingStore

    Hello,

    Recently i've encountered a problem with storing null as a setting value: a new non-null value isnt stored into database if such a key already exists and have a null value.

    // This will create a new setting with nullable value
    settings()->set([
        'key' => null,
    ]);
    settings()->save();
    
    // That new value will not be stored into database, the actual value will remain "null"
    settings()->set([
        'key' => 'value',
    ]);
    settings()->save();
    

    The cause of this problem is that DatabaseSettingStore uses the isset() function to determine if a specific key exists, but that function does not consider null values. I would suggest to use the array_key_exists() function instead:

    class DatabaseSettingStore extends SettingStore
    {
        protected function write(array $data): void {
            // ...
    
            foreach ($keys as $key) {
                if (
                    array_key_exists($key, $updatedData)
                    && array_key_exists($key, $persistedData)
                    && (string) $updatedData[$key] !== (string) $persistedData[$key]
                ) {
                    $updateData[$key] = $updatedData[$key];
                } elseif (!array_key_exists($key, $insertData)) {
                    $deleteKeys[] = $key;
                }
    
                unset($insertData[$key]);
            }
    
            // ...
        }
    }
    

    A use-case for this improvement is that sometimes (my case :)) you have a single form for the project settings and some of them may not have a value (null by default) and it is handy to just save all validated settings into database, event if some values are null:

    $settings = $request->validated();
    
    settings()->set($settings);
    settings()->save();
    
    opened by quallrum 0
  • Custom setting store doesn't use cache (or incorrect instructions)

    Custom setting store doesn't use cache (or incorrect instructions)

    I had to extend the DatabaseSettingStore for some unimportant reasons. So I followed the instructions in the readme and added the a new class:

    class CustomDatabaseSettingStore extends Base
    {
        public function __construct(Connection $connection)
        {
            parent::__construct(
                $connection,
                config('settings.table'),
                config('settings.keyColumn'),
                config('settings.valueColumn')
            );
        }
        // more code here
    }
    

    and I added the following to my AppServiceProvider:

    Setting::extend('customDatabaseSettingStore', function ($app) {
        return $app->make(CustomDatabaseSettingStore::class);
    });
    

    I have caching enabled, but I found the setting cache suspiciously empty. So I checked, and it turns out that caching settings are never set in the custom store, and I think defaults also don't work. These are usually set in SettingsManager::wrapDriver() which is never called.

    I had to add the code from wrapDriver() to my custom store:

    class CustomDatabaseSettingStore extends Base
    {
        public function __construct(Connection $connection)
        {
            parent::__construct(
                $connection,
                config('settings.table'),
                config('settings.keyColumn'),
                config('settings.valueColumn')
            );
    
            $this->setDefaults(config('settings.defaults'));
    
            if (config('settings.enableCache')) {
                $this->setCache(
                    app()['cache'],
                    config('settings.cacheTtl'),
                    config('settings.forgetCacheByWrite')
                );
            }
        }
    // more code
    }
    

    I think, at the very least, the readme should be updated. I was very surprised that this was needed, especially because it is usually handled by the SettingsManager, which I wouldn't have expected to have to look at. I would prefer if wrapDriver() was somehow called for custom drivers, but it would already be helpful if it were public and easily accessible.

    opened by bjhijmans 4
  • Settings to not save when using DB transactions

    Settings to not save when using DB transactions

    Thanks for this great library.

    I current have my settings stored in the database.

    I am having a problem where I am using a Database transaction, and the setting does not save, it will only save if I do it outside of the transaction.

    Is this a limitation with this package that you cannot save settings (in database) using a DB Transaction?

    Thanks

    opened by mrdigitalau 1
  • set empty array will throw Exception

    set empty array will throw Exception

    run:setting(['financial' => [] ])->save();

    result:throw ErrorException: Array to string conversion in file

    I think if set key a empty array ,dont save this key will better ?

    opened by miaotiao 0
Releases(v1.2.0)
Owner
Andreas Lutro
Software, systems, cloud, devops engineer. Living in Amsterdam, originally from Norway.
Andreas Lutro
Persistent Fakes for Laravel Dusk

Laravel Dusk Fakes Support this package! ❤️ We proudly support the community by developing Laravel packages and giving them away for free. If this pac

Protone Media 3 Sep 5, 2022
Per-user settings repository system for Laravel

Laraconfig Per-user settings repository system for Laravel. This package allows users to have settings that can be queried, changed and even updated,

Italo 170 Oct 26, 2022
Store and retrieve settings generally or for model objects in Laravel.

Store and retrieve settings generally or for model objects in Laravel. Documentation You can find the detailed documentation here in Laravel Settings

Pharaonic 7 Dec 19, 2022
Add settings to any Laravel model.

Laravel Property Bag Simple settings for Laravel apps. Easily give multiple resources settings Simple to add additional settings as your app grows Set

Zach Leigh 80 Aug 8, 2022
Simple Arabic Laravel Dashboard , has basic settings and a nice layout . to make it easy for you to create fast dashboard

Simple Arabic Laravel Dashboard ✅ Auto Seo ✅ Optimized Notifications With Images ✅ Smart Alerts ✅ Auto Js Validations ✅ Front End Alert ✅ Nice Image V

Peter Tharwat 254 Dec 19, 2022
Model Settings for your Laravel app

Model Settings for your Laravel app The package requires PHP 7.3+ and follows the FIG standards PSR-1, PSR-2, PSR-4 and PSR-12 to ensure a high level

Lorand Gombos 611 Dec 15, 2022
⚙️Simple key/value typed settings for your Laravel app with synchronized json export

Simple key/value typed settings for your Laravel app Create, store and use key/value settings, typed from numbers over dates to array, cached for quic

elipZis 8 Jan 7, 2023
Strongly typed settings for Laravel, includes built-in encryption and friendly validation.

Strongly Typed Laravel Settings Install composer require bogdankharchenko/typed-laravel-settings Model Setup namespace App\Models\User; use Illuminat

Bogdan Kharchenko 10 Aug 31, 2022
Store your Laravel application settings in an on-disk JSON file

Store your Laravel application settings in an on-disk JSON file. This package provides a simple SettingsRepository class that can be used to store you

Ryan Chandler 24 Nov 16, 2022
An interface for the administrator to easily change application settings. Uses Laravel Backpack

Backpack\Settings An interface for the administrator to easily change application settings. Uses Laravel Backpack. Works on Laravel 5.2 to Laravel 8.

Backpack for Laravel 207 Dec 6, 2022
This Laravel Nova settings tool based on env, using nativ nova fields and resources

Nova Settings Description This Laravel Nova settings tool based on env, using nativ nova fields and resources Features Using native Nova resources Ful

Artem Stepanenko 21 Dec 28, 2022
Kalibrant - a package that provides a simple way to manage your models settings

Introduction For your laravel 9.x applications, Kalibrant is a package that provides a simple way to manage your models settings. It is a simple way t

Starfolk 3 Jun 18, 2022
Bootstrap Theme Generator inside of a Wordpress-Settings-Page. Includes live compilation of SCSS!

Bootstrap-Theme-Generator Bootstrap Theme Generator enables you to choose which components of Bootstrap you want to load. It also gives you the possib

null 3 Aug 15, 2022
List of 77 languages for Laravel Framework 4, 5, 6, 7 and 8, Laravel Jetstream , Laravel Fortify, Laravel Breeze, Laravel Cashier, Laravel Nova and Laravel Spark.

Laravel Lang In this repository, you can find the lang files for the Laravel Framework 4/5/6/7/8, Laravel Jetstream , Laravel Fortify, Laravel Cashier

Laravel Lang 6.9k Jan 2, 2023
⚡ Laravel Charts — Build charts using laravel. The laravel adapter for Chartisan.

What is laravel charts? Charts is a Laravel library used to create Charts using Chartisan. Chartisan does already have a PHP adapter. However, this li

Erik C. Forés 31 Dec 18, 2022
Laravel Kickstart is a Laravel starter configuration that helps you build Laravel websites faster.

Laravel Kickstart What is Laravel Kickstart? Laravel Kickstart is a Laravel starter configuration that helps you build Laravel websites faster. It com

Sam Rapaport 46 Oct 1, 2022
Laravel User Activity Log - a package for Laravel 8.x that provides easy to use features to log the activities of the users of your Laravel app

Laravel User Activity Log - a package for Laravel 8.x that provides easy to use features to log the activities of the users of your Laravel app

null 9 Dec 14, 2022
Laravel Segment is an opinionated, approach to integrating Segment into your Laravel application.

Laravel Segment Laravel Segment is an opinionated, approach to integrating Segment into your Laravel application. Installation You can install the pac

Octohook 13 May 16, 2022
Laravel Sanctum support for Laravel Lighthouse

Lighthouse Sanctum Add Laravel Sanctum support to Lighthouse Requirements Installation Usage Login Logout Register Email Verification Forgot Password

Daniël de Wit 43 Dec 21, 2022