framesnpictures/el-settings

There is no license information available for the latest version (0.2) of this package.

Laravel Settings Module

Maintainers

Package info

github.com/FramesNPictures/el-settings

pkg:composer/framesnpictures/el-settings

Statistics

Installs: 11

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

0.2 2026-04-13 15:47 UTC

This package is auto-updated.

Last update: 2026-04-13 15:49:57 UTC


README

A Laravel package for storing and retrieving typed application settings backed by a database, with transparent cache layering and Laravel config fallback.

Why

Laravel config values are read from files at boot time and cannot be changed at runtime. This package solves the problem by letting you override any config value with a value stored in the database — without a deployment or server restart. An admin panel, artisan command, or any other runtime code can call set() and the new value is live immediately across the application.

How it works

Settings are defined on a class that extends SettingsDefiniton using #[UseSetting] PHP attributes. Each setting has a key ( matching a Laravel config path), a type, and an optional description.

When a value is read with get(), it is resolved through a three-level chain:

  1. Cache — served from the cache if present
  2. Database — read from the app_settings table if not cached
  3. Config — falls back to config($key, $default) if no DB record exists, and caches the result

When a value is written with set(), it is persisted to the database and the cache is updated immediately.

Installation

composer require framesnpictures/el-settings

The package auto-discovers its service provider. Publish the config file and migration, then run the migration:

php artisan vendor:publish --provider="Fnp\Settings\ElSettingsModule" --tag=config
php artisan vendor:publish --provider="Fnp\Settings\ElSettingsModule" --tag=migrations
php artisan migrate

Configuration

The published config file is config/el-settings.php:

return [
    'table' => 'app_settings',
];

Change table to use a different database table name.

Usage

1. Define a settings class

Create a class extending SettingsDefiniton and annotate it with one #[UseSetting] attribute per setting:

use Fnp\Settings\Base\SettingsDefinition;
use Fnp\Settings\Attributes\UseSetting;
use Fnp\Settings\Enums\ESettingType;

#[UseSetting(config: 'app.name',     type: ESettingType::String,          description: 'Application name')]
#[UseSetting(config: 'app.debug',    type: ESettingType::Bool,            description: 'Debug mode')]
#[UseSetting(config: 'app.url',      type: ESettingType::EncryptedString,  description: 'Application URL')]
#[UseSetting(config: 'mail.port',    type: ESettingType::Number,           description: 'Mail port')]
#[UseSetting(config: 'app.options',  type: ESettingType::Array,            description: 'Feature flags')]
class AppSettings extends SettingsDefinition {}

The config parameter doubles as both the setting key and the Laravel config path used as a default value. The description parameter is stored alongside the value in the database, making it easy to identify and manage settings directly in a database client without needing to cross-reference the source code.

2. Initialize settings

init() syncs the settings class with the database:

  • New keys are inserted with the current value from Laravel config as their initial value.
  • Existing keys are left untouched — their stored value is never overwritten — but their description is updated to reflect any changes made in the attribute.
AppSettings::init();

Call init() from a database migration every time a #[UseSetting] attribute is added or its description is changed. This keeps the database in sync with the code automatically on each deployment:

public function up(): void
{
    AppSettings::init();
}

3. Read a value

$name = AppSettings::get('app.name');

// With a fallback default
$timeout = AppSettings::get('app.timeout', 30);

4. Write a value

AppSettings::set('app.name', 'My App');
AppSettings::set('app.url',  'https://example.com'); // encrypted at rest
AppSettings::set('mail.port', 587);
AppSettings::set('app.options', ['feature_x' => true]);

set() validates that the value matches the declared type and throws InvalidArgumentException otherwise.

5. Setting types

Type Constant Storage
Plain string ESettingType::String s column
Boolean ESettingType::Bool n column
Integer / float ESettingType::Number n column
Array ESettingType::Array e column (JSON)
Object ESettingType::Object e column (serialized, base64)
Encrypted string ESettingType::EncryptedString e column (encrypted, base64)

6. Registering settings classes

Add ModuleSettingsClasses to your module and implement defineSettingsClasses(). This lets the artisan commands discover available settings classes automatically without requiring a class name argument.

use Fnp\Settings\Features\ModuleSettingsClasses;

class AppModule extends ElModule
{
    use ModuleSettingsClasses;

    public function defineSettingsClasses(): array
    {
        return [AppSettings::class];
    }
}

Treat the above module as a normal Laravel service provider and register it in config/app.php.

See the el-module package for more details.

7. Artisan commands

The class argument is optional when settings classes are registered via ModuleSettingsClasses. If multiple classes are registered, the command will prompt you to choose one.

Get a value

# Class resolved from registry
php artisan settings:get app.name

# With explicit class
php artisan settings:get app.name --class="App\Settings\AppSettings"

Set a value

Pass the value directly on the command line:

php artisan settings:set app.name "My App"
php artisan settings:set mail.port 587
php artisan settings:set app.options '{"feature_x":true}'

Or read the value from a file (useful for long strings, certificates, or secrets):

php artisan settings:set app.url --file=/run/secrets/app_url

With an explicit class:

php artisan settings:set app.name "My App" --class="App\Settings\AppSettings"

Initialize settings

When called without --class, settings:init initializes every registered settings class:

# Init all registered classes
php artisan settings:init

# Init a specific class
php artisan settings:init --class="App\Settings\AppSettings"

7. Low-level access

// Read/write directly from cache (bypasses DB)
AppSettings::getCacheValue('app.name');
AppSettings::setCacheValue('app.name', 'value', ttl: 60);

// Read/write directly from the database (bypasses cache)
AppSettings::getDBValue('app.name');
AppSettings::setDBValue('app.name', 'value');

// Read from Laravel config
AppSettings::getConfigValue('app.name', 'default');

License

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