PHPackages                             nabcellent/laraconfig - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. nabcellent/laraconfig

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

nabcellent/laraconfig
=====================

Per-user settings repository system for Laravel

v2.0.4(1y ago)14292MITPHPPHP ^8.3

Since Jul 17Pushed 1y ago1 watchersCompare

[ Source](https://github.com/Nabcellent/laraconfig)[ Packagist](https://packagist.org/packages/nabcellent/laraconfig)[ Fund](https://paypal.me/Nabcellent)[ Fund](https://ko-fi.com/Nabcellent)[ RSS](/packages/nabcellent-laraconfig/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (9)Dependencies (9)Versions (22)Used By (0)

The origin of this package has been archived.

I am trying to keep it afloat.😃

---

[![Xavier von Erlach - Unsplash #ooR1jY2yFr4](https://camo.githubusercontent.com/e486fae09f3d0e5ae428bdac6c4e37890a00b814edc06d52fd6c7eb5c398e3e4/68747470733a2f2f696d616765732e756e73706c6173682e636f6d2f70686f746f2d313537303232313632323232342d3362623866303866313636633f69786c69623d72622d312e322e3126697869643d4d6e77784d6a4133664442384d48787761473930627931775957646c66487838664756756644423866487838266175746f3d666f726d6174266669743d63726f7026773d3132303026683d34303026713d3830)](https://camo.githubusercontent.com/e486fae09f3d0e5ae428bdac6c4e37890a00b814edc06d52fd6c7eb5c398e3e4/68747470733a2f2f696d616765732e756e73706c6173682e636f6d2f70686f746f2d313537303232313632323232342d3362623866303866313636633f69786c69623d72622d312e322e3126697869643d4d6e77784d6a4133664442384d48787761473930627931775957646c66487838664756756644423866487838266175746f3d666f726d6174266669743d63726f7026773d3132303026683d34303026713d3830)

[![Latest Version on Packagist](https://camo.githubusercontent.com/a309d4eb962f287b88bab03504ef27319c209c79e30cba0f52195d2c06b471ec/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6e616263656c6c656e742f6c617261636f6e6669672e737667)](https://packagist.org/packages/nabcellent/laraconfig) [![License](https://camo.githubusercontent.com/ac3764bdd4838c0215d7f9cbcedd186720bbeee560147d9928c0a5303569e6d1/68747470733a2f2f706f7365722e707567782e6f72672f6e616263656c6c656e742f6c617261636f6e6669672f6c6963656e7365)](https://packagist.org/packages/nabcellent/laraconfig) [![](https://camo.githubusercontent.com/275f21119183c607bbb61576e6aeac583c8f2b7ea7241520b5b198e3b0cc128f/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f6e616263656c6c656e742f6c617261636f6e6669672e737667)](https://camo.githubusercontent.com/275f21119183c607bbb61576e6aeac583c8f2b7ea7241520b5b198e3b0cc128f/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f6e616263656c6c656e742f6c617261636f6e6669672e737667) [![](https://github.com/Nabcellent/Laraconfig/workflows/PHP%20Composer/badge.svg)](https://github.com/Nabcellent/Laraconfig/workflows/PHP%20Composer/badge.svg) [![Coverage Status](https://camo.githubusercontent.com/2f216695b1eff91eceec82cd452f0444c6824e76a2ba540635780afcffd314a5/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f4e616263656c6c656e742f4c617261636f6e6669672f62616467652e7376673f6272616e63683d6d6173746572)](https://coveralls.io/github/Nabcellent/Laraconfig?branch=master) [![Laravel Octane Compatible](https://camo.githubusercontent.com/70359a356da237cd29561bc5d0bb80baae775b5ff62f288ed324755382858342/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2532304f6374616e652d436f6d70617469626c652d737563636573733f7374796c653d666c6174266c6f676f3d6c61726176656c)](https://github.com/laravel/octane)

Laraconfig
==========

[](#laraconfig)

Per-user settings repository system for Laravel.

This package allows users to have settings that can be queried, changed and even updated, effortlessly and quickly.

```
User::find(1)->settings->set('color', 'red');
```

Requirements
------------

[](#requirements)

- Laravel ^11
- PHP ^8.3

How it works
------------

[](#how-it-works)

Laraconfig works extending Laravel relations, and includes a migration system to easily manage them.

Each Setting is just a value, and references a parent "metadata" that contains the information like the type and name, while being linked to a user.

Since Laraconfig uses the Eloquent ORM behind the scenes, getting a one or all settings is totally transparent to the developer.

Quickstart
----------

[](#quickstart)

You can install the package via composer.

```
composer require nabcellent/laraconfig

```

First, publish and run the migrations. These will add two tables called `user_settings` and `user_settings_metadata`. One holds the values per user, the other the metadata of the setting, respectively.

```
php artisan vendor:publish --provider="Nabcellent\Laraconfig\LaraconfigServiceProvider" --tag="migrations"
php artisan migrate

```

> The migration uses a morph column to connect to the User. You can change it before migrating.

Second, add the `HasConfig` trait to the User models you want to have settings.

```
namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Nabcellent\Laraconfig\HasConfig;

class User extends Authenticatable
{
    use HasConfig;

    // ...
}
```

Finally, use the `settings:publish` artisan command. This will create a `settings` folder in the root of your project and a `users.php` file.

```
php artisan settings:publish

```

Now, let's create some settings.

Settings Manifest
-----------------

[](#settings-manifest)

Laraconfig makes managing user settings globally using a *manifest* of sorts, the `settings/users.php` file. You will see a sample setting already written.

```
use Nabcellent\Laraconfig\Facades\Setting;

Setting::name('color')->string();
```

### Creating a setting

[](#creating-a-setting)

To create a setting, use the `Setting` facade. You can start with setting the name, which must be unique, and then declare the type.

```
use Nabcellent\Laraconfig\Facades\Setting;

Setting::name('dark_mode')->boolean();
```

Laraconfig is compatible with 7 types of settings, mirroring their PHP native types, along the Collection and Datetime (Carbon) objects.

- `array()`
- `boolean()`
- `collection()`
- `datetime()`
- `float()`
- `integer()`
- `string()`

> Arrays and Collections are serialized in the database as JSON.

### Default value

[](#default-value)

All settings have a default value of `null`, but you can use the `default()` method to set a different initial value.

```
use Nabcellent\Laraconfig\Facades\Setting;

Setting::name('color')->string()->default('black');
```

> You can later revert the value back to the default using [`setDefault()`](#defaulting-a-setting).

### Enabled or Disabled

[](#enabled-or-disabled)

By default, all settings are [enabled by default](#disablingenabling-settings), but you can change this using `disabled()`.

```
Setting::name('color')->disabled();
```

> Enabled or disable is presentational; a disabled setting can still be updated. You can programmatically set a value using [`setIfEnabled()`](#disablingenabling-settings).

### Group settings

[](#group-settings)

You can set a group name to a setting. This can be handy when you want to display settings in the frontend in an ordered manner by [separating them in groups](https://laravel.com/docs/collections#method-groupby).

```
Setting::name('color')->group('theme');
```

### Bag

[](#bag)

When Laraconfig migrates the new settings, these are created to all models. You can filter a given set of settings through "bags".

By default, all settings are created under the `users` bag, but you can change the default bag for anything using the `bag()` method.

```
Setting::name('color')->group('theme')->bag('style');

Setting::name('notify_email')->boolean()->default(true)->bag('notifications');
Setting::name('notify_sms')->boolean()->default(false)->bag('notifications');
```

Later, in your model, you can filter the bags you want to work with using [`filterBags()`](#setting-bags) in your model.

Migrating settings
------------------

[](#migrating-settings)

Once you're done creating your settings, you should use `settings:migrate` to let Laraconfig add the settings metadata to your database.

```
php artisan settings:migrate

```

Behind the scenes, Laraconfig will look into your Models for those using the `HasConfig` trait, and populate the settings accordingly using the information on the manifest.

> Migration run only *forward*. There is no way to revert a migration once done. On production, removing settings needs confirmation.

### Adding new settings

[](#adding-new-settings)

Simply create a new setting and run `settings:migrate`. Existing settings won't be created again, as Laraconfig will check their existence before doing it.

```
use Nabcellent\Laraconfig\Facades\Setting;

Setting::name('color')->string()->default('black');

// This new setting will be created
Setting::name('notifications')->boolean()->default(true);
```

### Removing old settings

[](#removing-old-settings)

To remove old settings, simply remove their declaration and run `settings:migrate`. Laraconfig compares the settings declared to the ones created in the database, and removes those that no longer exist in the manifest at the end of the migration execution.

```
use Nabcellent\Laraconfig\Facades\Setting;

// Commenting this line will remove the "color" setting on migration.
// Setting::name('color')->string()->default('black');

// This new setting will be created
Setting::name('notifications')->boolean()->default(true);
```

> Since this procedure can be dangerous, **confirmation** will be needed on production environments.

### Upgrading settings

[](#upgrading-settings)

You don't need to get directly into the database to update a setting. Instead, just change the setting properties directly in the manifest. Laraconfig will update the metadata accordingly.

Let's say we have a "color" setting we wish to update from a string to an array of colors, with a default and a group.

```
Setting::name('color')->string()->bag('theme');

// This is the new declaration.
// Setting::name('color')
//    ->array()
//    ->default(['black'])
//    ->group('theme');
```

Laraconfig will detect the new changes, and update the metadata keeping the users value intact.

```
// This is the old declaration.
// Setting::name('color')->string()->bag('theme');

Setting::name('color')
    ->array()
    ->default(['black'])
    ->group('theme');
```

> Updating only occurs if the setting is different from before at migration time.

Once done, we can migrate the old setting to the new one using `settings:migrate`. Users will keep the same setting value they had, but... What if we want to also change the value for each user? We can use the `using()` method to feed each user setting to a callback that will return the new value.

```
Setting::name('color')
    ->array()
    ->default('black')
    ->group('theme')
    ->using(fn ($old) => $old->value ?? 'black'); // If the value is null, set it as "black".
```

> The `using()` method only runs if the setting is different from before at migration time.

Behind the scenes, Laraconfig will look for the "color" setting, update the metadata, and then use a [`lazy()` query](https://laravel.com/docs/queries#streaming-results-lazily) to update the value with the callback.

> Consider migrating directly on the database if you have hundreds of thousands of records, as this procedure is safer but slower than a direct SQL statement.

### Migrating to a new setting

[](#migrating-to-a-new-setting)

On other occasions, you may want to migrate a setting to a completely new one. In both cases you can use `from()` to get the old setting value to migrate from, and `using()` if you want to also update the value of each user.

Taking the same example above, we will migrate the "color" setting to a simple "dark theme" setting.

```
// This old declaration will be deleted after the migration ends.
// Setting::name('color')->string()->bag('theme');

// This is a new setting.
Setting::name('dark')
    ->boolean()
    ->default(false)
    ->group('theme')
    ->from('color')
    ->using(static fn ($old) => $old->value === 'black'); // If it's black, then it's dark.
```

> The `from` and `using` are executed only if the old setting exists at migration time.

Behind the scenes, Laraconfig creates the new "theme" setting first, and then looks for the old "color" setting in the database to translate the old values to the new ones. Since the old setting is not present in the manifest, it will be deleted from the database.

Managing Settings
-----------------

[](#managing-settings)

Laraconfig handles settings like any [Eloquent Morph-Many Relationship](https://laravel.com/docs/eloquent-relationships#one-to-many-polymorphic-relations), but supercharged.

Just simply use the `settings` property on your model. This property is like your normal [Eloquent Collection](https://laravel.com/docs/eloquent-collections), so you have access to all its tools.

```
$user = User::find(1);

echo "Your color is: {$user->settings->get('color')}.";
```

> Using `settings` is preferred, as it will load the settings only once.

### Initializing

[](#initializing)

By default, the `HasConfig` trait will create a new bag of Settings in the database after a User is successfully created through the Eloquent ORM, so you don't have to create any setting.

In case you want to handle initialization manually, you can use the `shouldInitializeConfig()` method and return `false`, which can be useful when programmatically initializing the settings.

```
// app/Models/User.php

/**
 * Check if the user should initialize settings automatically after creation.
 *
 * @return bool
 */
protected function shouldInitializeConfig(): bool
{
    // Don't initialize the settings if the user is not verified from the start.
    // We will initialize them only once the email is properly verified.
    return null !== $this->email_verified_at;
}
```

Since the user in the example above won't be initialized, we have to do it manually using `initialize()`.

```
// Initialize if not initialized before.
$user->settings()->initialize();

// Forcefully initialize, even if already initialized.
$user->settings()->initialize(true);
```

#### Checking settings initialization

[](#checking-settings-initialization)

You can check if a user configuration has been initialized or not using `isInitialized()`.

```
if ($user->settings()->isInitialized()) {
    return 'You have a config!';
}
```

### Retrieving settings

[](#retrieving-settings)

You can easily get a value of a setting using the name, which makes everything into a single beautiful *oneliner*.

```
return "Your favorite color is {$user->settings->color}";
```

Since this only supports alphanumeric and underscore characters, you can use `value()`.

```
return "Your favorite color is {$user->settings->value('color')}";
```

You can also get the underlying Setting model using `get()`. If the setting doesn't exist, it will return `null`.

```
$setting = $user->settings->get('theme');

echo "You're using the [$setting->value] theme.";
```

Since the `settings` is a [collection](https://laravel.com/docs/eloquent-collections), you have access to all the goodies, like iteration:

```
foreach ($user->settings as $setting) {
    echo "The [$setting->name] has the [$setting->value] value.";
}
```

You can also use the `only()` method to return a collection of settings by their name, or `except()` to retrieve all the settings except those issued.

```
$user->settings->only('colors', 'is_dark');

$user->settings->except('dark_mode');
```

#### Grouping settings

[](#grouping-settings)

Since the list of settings is a collection, you can use `groups()` method to group them by the name of the group they belong.

```
$user->settings->groups(); // or ->groupBy('group')
```

> Note that Settings are grouped into the `default` group by default (no pun intended).

### Setting a value

[](#setting-a-value)

Setting a value can be easily done by issuing the name of the setting and the value.

```
$user->settings->color = 'red';
```

Since this only supports settings with names made of alphanumeric and underscores, you can also set a value using the `set()` method by issuing the name of the setting.

```
$user->settings->set('color-default', 'red');
```

Or, you can go the purist mode directly in the model itself.

```
$setting = $user->settings->get('color');

$setting->value = 'red';
$setting->save();
```

You can also set multiple settings using an array when using `set()` in one go, which is useful when dealing with the [array returned by a validation](https://laravel.com/docs/validation#quick-writing-the-validation-logic).

```
$user->settings->set([
    'color' => 'red',
    'dark_mode' => false,
]);
```

When [using the cache](#cache), any change invalidates the cache immediately and queues up a regeneration before the collection is garbage collected.

> That being said, updating the settings directly into the database **doesn't regenerate the cache**.

### Defaulting a Setting

[](#defaulting-a-setting)

You can turn the setting back to the default value using `setDefault()` on both the setting instance or using the `settings` property.

```
$setting = $user->settings->get('color');

$setting->setDefault();

$user->settings->setDefault('color');
```

> If the setting has no default value, `null` will be used.

### Check if null

[](#check-if-null)

Check if a `null` value is set using `isNull()` with the name of the setting.

```
if ($user->settings->isNull('color')) {
    return 'The color setting is not set.';
}
```

### Disabling/Enabling settings

[](#disablingenabling-settings)

For presentational purposes, all settings are enabled by default. You can enable or disable settings with the `enable()` and `disable()`, respectively. To check if the setting is enabled, use the `isEnabled()` method.

```
$user->settings->enable('color');

$user->settings->disable('color');
```

> A disabled setting can be still set. If you want to set a value only if it's enabled, use `setIfEnabled()`.
>
> ```
> $user->settings->setIfEnabled('color', 'red');
> ```

Setting Bags
------------

[](#setting-bags)

Laraconfig uses one single bag called `default`. If you have declared in the manifest [different sets of bags](#bag), you can make a model to use only a particular set of bags with the `filterBags()` method, that should return the bag name (or names).

```
// app/Models/User.php
i
```

The above will apply a filter to the query when retrieving settings from the database. This makes easy to swap bags when a user has a different role or property, or programmatically.

> **All** settings are created for all models with `HasConfig` trait, regardless of the bags used by the model.

#### Disabling the bag filter scope

[](#disabling-the-bag-filter-scope)

Laraconfig applies a query filter to exclude the settings not in the model bag. While this eases the development, sometimes you will want to work with the full set of settings available.

There are two ways to disable the bag filter. The first one is relatively easy: simply use the `withoutGlobalScope()` at query time, which will allow to query all the settings available to the user.

```
use Nabcellent\Laraconfig\Eloquent\Scopes\FilterBags;

$allSettings = $user->settings()->withoutGlobalScope(FilterBags::class)->get();
```

If you want a more *permanent* solution, just simply return an empty array or `null` when using the `filterBags()` method in you model, which will disable the scope completely.

```
/**
 * Returns the bags this model uses for settings.
 *
 * @return array|string
 */
public function filterBags(): array|string|null
{
    return null;
}
```

Cache
-----

[](#cache)

Hitting the database each request to retrieve the user settings can be detrimental if you expect to happen a lot. To avoid this, you can activate a cache which will be regenerated each time a setting changes.

The cache implementation avoids data-races. It will regenerate the cache only for the last data changed, so if two or more processes try to save something into the cache, only the fresher data will be persisted.

### Enabling the cache

[](#enabling-the-cache)

You can easily enable the cache using the `LARACONFIG_CACHE` environment variable set to `true`, and use a non-default cache store (like Redis) with `LARACONFIG_STORE`.

```
LARACONFIG_CACHE=true
LARACONFIG_STORE=redis
```

> Alternatively, check the `laraconfig.php` file to customize the cache TTL and prefix.

#### Managing the cache

[](#managing-the-cache)

You can forcefully regenerate the cache of a single user using `regenerate()`. This basically saves the settings present and saves them into the cache.

```
$user->settings->regenerate();
```

You can also invalidate the cached settings using `invalidate()`, which just deletes the entry from the cache.

```
$user->settings->invalidate();
```

Finally, you can have a little peace of mind by setting `regeneratesOnExit` to `true`, which will regenerate the cache when the settings are garbage collected by the PHP process.

```
$user->settings->regeneratesOnExit = true;
```

> You can disable automatic regeneration on the config file.

#### Regenerating the Cache on migration

[](#regenerating-the-cache-on-migration)

If the [Cache is activated](#cache), the migration will invalidate the setting cache for each user after it completes.

Depending on the Cache system, forgetting each cache key can be detrimental. Instead, you can use the `--flush-cache` command to flush the cache store used by Laraconfig, instead of deleting each key one by one.

```
php artisan settings:migrate --flush-cache

```

> Since this will delete all the data of the cache, is recommended to use an exclusive cache store for Laraconfig, like a separate Redis database.

Validation
----------

[](#validation)

Settings values are *casted*, but not validated. You should validate in your app every value that you plan to store in a setting.

```
use App\Models\User;
use Illuminate\Http\Request;

public function store(Request $request, User $user)
{
    $settings = $request->validate([
        'age' => 'required|numeric|min:14|max:100',
        'color' => 'required|string|in:red,green,blue'
    ]);

    $user->settings->setIfEnabled($settings);

    // ...
}
```

Testing
-------

[](#testing)

Eventually you will land into the problem of creating settings and metadata for each user created. You can easily create Metadata directly into the database *before* creating a user, unless you have disabled [initialization](#initializing).

```
public function test_user_has_settings(): void
{
    Metadata::forceCreate([
        'name'    => 'foo',
        'type'    => 'string',
        'default' => 'bar',
        'bag'     => 'users',
        'group'   => 'default',
    ]);

    $user = User::create([
        // ...
    ]);

    // ...
}
```

Security
--------

[](#security)

If you discover any security related issues, please email  instead of using the issue tracker.

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

39

—

LowBetter than 86% of packages

Maintenance34

Infrequent updates — may be unmaintained

Popularity17

Limited adoption so far

Community16

Small or concentrated contributor base

Maturity75

Established project with proven stability

 Bus Factor1

Top contributor holds 65.9% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~59 days

Recently: every ~7 days

Total

20

Last Release

627d ago

Major Versions

v1.3.9 → v2.0.02024-07-24

PHP version history (4 changes)v1.0.0PHP &gt;=8.0

v1.3.6PHP ^8.0

v1.3.8PHP ^8.1

v2.0.0PHP ^8.3

### Community

Maintainers

![](https://www.gravatar.com/avatar/33e07419d7572a9f919990a3d01ff1177f69841d3ae5151f7afcb4f6e10533b2?d=identicon)[nabcellent](/maintainers/nabcellent)

---

Top Contributors

[![DarkGhostHunter](https://avatars.githubusercontent.com/u/5141911?v=4)](https://github.com/DarkGhostHunter "DarkGhostHunter (56 commits)")[![Nabcellent](https://avatars.githubusercontent.com/u/68481507?v=4)](https://github.com/Nabcellent "Nabcellent (21 commits)")[![greenspace10](https://avatars.githubusercontent.com/u/55725358?v=4)](https://github.com/greenspace10 "greenspace10 (2 commits)")[![ricventu](https://avatars.githubusercontent.com/u/3369838?v=4)](https://github.com/ricventu "ricventu (2 commits)")[![vanbosse](https://avatars.githubusercontent.com/u/606803?v=4)](https://github.com/vanbosse "vanbosse (1 commits)")[![eafarooqi](https://avatars.githubusercontent.com/u/3758194?v=4)](https://github.com/eafarooqi "eafarooqi (1 commits)")[![RenoLooijmans](https://avatars.githubusercontent.com/u/73367951?v=4)](https://github.com/RenoLooijmans "RenoLooijmans (1 commits)")[![szepeviktor](https://avatars.githubusercontent.com/u/952007?v=4)](https://github.com/szepeviktor "szepeviktor (1 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/nabcellent-laraconfig/health.svg)

```
[![Health](https://phpackages.com/badges/nabcellent-laraconfig/health.svg)](https://phpackages.com/packages/nabcellent-laraconfig)
```

###  Alternatives

[laravel/pulse

Laravel Pulse is a real-time application performance monitoring tool and dashboard for your Laravel application.

1.7k12.1M99](/packages/laravel-pulse)[psalm/plugin-laravel

Psalm plugin for Laravel

3274.9M308](/packages/psalm-plugin-laravel)[laravel-zero/framework

The Laravel Zero Framework.

3371.4M368](/packages/laravel-zero-framework)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

255.2k](/packages/aedart-athenaeum)[flarum/core

Delightfully simple forum software.

211.3M1.9k](/packages/flarum-core)[glhd/conveyor-belt

14797.0k](/packages/glhd-conveyor-belt)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
