PHPackages                             agroezinger/filament-app-settings - 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. agroezinger/filament-app-settings

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

agroezinger/filament-app-settings
=================================

Flexible polymorphic settings for Laravel with Multi-Tenancy and fallback support.

v1.0.7(yesterday)04↑2900%MITPHPPHP ^8.4

Since Jun 22Pushed todayCompare

[ Source](https://github.com/agroezinger/filament-app-settings)[ Packagist](https://packagist.org/packages/agroezinger/filament-app-settings)[ Docs](https://github.com/agroezinger/filament-app-settings)[ RSS](/packages/agroezinger-filament-app-settings/feed)WikiDiscussions main Synced today

READMEChangelog (1)Dependencies (6)Versions (3)Used By (0)

agroezinger/filament-app-settings
=================================

[](#agroezingerfilament-app-settings)

Flexible, polymorphic key-value settings for Laravel with multi-tenancy and cascading fallback support.

Features
--------

[](#features)

- **Polymorphic scope** — attach settings to any Eloquent model (department, user, …) or store them tenant- or system-wide
- **Three-level fallback** — model-specific → tenant-wide → system-wide
- **Filament multi-tenancy** — tenant ID is resolved automatically via `filament()->getTenant()`
- **Cache** — all reads are cached forever; writes flush the relevant cache key
- **`app_setting()` helper** — ergonomic global shortcut

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

[](#requirements)

- PHP 8.4+
- Laravel 11 or 12
- Optional: Filament v3+ (for automatic tenant resolution)

Installation
------------

[](#installation)

### 1. Require the package

[](#1-require-the-package)

```
composer require agroezinger/filament-app-settings
```

### 2. Publish and run the migration

[](#2-publish-and-run-the-migration)

```
php artisan vendor:publish --tag="app-settings-migrations"
php artisan migrate
```

This creates the `app_settings` table. The package registers itself automatically via Laravel's package auto-discovery — no manual provider registration needed.

### 3. Done

[](#3-done)

```
// Write a setting
app_setting()->set('site.name', 'My App');

// Read it back
$name = app_setting('site.name', 'Default');
```

Database schema
---------------

[](#database-schema)

```
app_settings
  id            bigint unsigned auto_increment
  key           varchar
  value         json nullable
  model_id      bigint unsigned  default 0
  model_type    varchar          default 'system'
  tenant_id     bigint unsigned  default 0
  created_at / updated_at
  unique (key, model_id, model_type, tenant_id)

```

Basic usage
-----------

[](#basic-usage)

```
use Agroezinger\FilamentAppSettings\AppSettings;

$settings = app(AppSettings::class);

// Write
$settings->set('invoice.footer', 'All prices include VAT.');

// Read (with optional default)
$footer = $settings->get('invoice.footer', '');

// Check existence
$settings->has('invoice.footer'); // true

// Delete by setting to null or ''
$settings->set('invoice.footer', null);
```

### Global helper

[](#global-helper)

```
// Returns the value directly
$value = app_setting('invoice.footer', 'default');

// Returns the AppSettings instance when called without arguments
app_setting()->set('foo', 'bar');
app_setting()->setMany([...]);
```

Model-scoped settings
---------------------

[](#model-scoped-settings)

```
$department = Department::find(1);

$settings->set('color', '#ff0000', model: $department);
$settings->get('color', null, model: $department);
```

Bulk write
----------

[](#bulk-write)

```
$settings->setMany([
    ['key' => 'site.name',    'value' => 'My Club'],
    ['key' => 'site.tagline', 'value' => 'Together we win'],
    // Attach to a model:
    ['key' => 'color', 'value' => '#336699', 'model' => $department],
    // Delete by passing null or '':
    ['key' => 'old.key', 'value' => null],
]);
```

Explicit tenant ID
------------------

[](#explicit-tenant-id)

Useful in seeders or console commands where no Filament tenant is active:

```
$settings->set('welcome.text', 'Hello!', explicitTenantId: $team->id);

$settings->setMany([
    ['key' => 'foo', 'value' => 'bar'],
], explicitTenantId: $team->id);
```

Model-scoped bulk read
----------------------

[](#model-scoped-bulk-read)

Retrieve all settings for a given key across every model of a type:

```
// Returns Collection keyed by model_id
$configs = $settings->getScopedConfigs('color', Department::class);
// ['1' => '#ff0000', '2' => '#336699']
```

Fallback chain
--------------

[](#fallback-chain)

`get()` resolves settings in this order, returning the first non-null match:

1. **Model-specific** in current tenant (if `$model` is provided)
2. **Tenant-wide** (`model_id = 0`, `model_type = 'system'`, current tenant)
3. **System-wide** (`tenant_id = 0`) — only checked when inside a tenant context

This lets you define global defaults at system level and override them per tenant or per model.

Multi-tenancy
-------------

[](#multi-tenancy)

The tenant ID is resolved automatically:

- Inside a Filament panel — uses `filament()->getTenant()->getKey()`
- Anywhere else — falls back to `0` (system / single-tenant)

No configuration required if you use Filament. For custom tenant resolution, extend `AppSettings` and override `getTenantId()`.

Extending
---------

[](#extending)

```
class MyAppSettings extends \Agroezinger\FilamentAppSettings\AppSettings
{
    protected function getTenantId(): int
    {
        return auth()->user()?->team_id ?? 0;
    }
}

// Rebind in a ServiceProvider:
$this->app->singleton(\Agroezinger\FilamentAppSettings\AppSettings::class, fn() => new MyAppSettings());
```

Stored value types
------------------

[](#stored-value-types)

`value` is a native JSON column. Eloquent's `json` cast handles encoding and decoding automatically:

PHP value storedMySQL JSONPHP value retrieved`'true'` (string)`"true"``'true'` (string)`true` (bool)`true``true` (bool)`42` (int)`42``42` (int)`['a', 'b']` (array)`["a","b"]``['a', 'b']` (array)`null``null``null`> **Note:** Avoid querying the `app_settings` table with raw `DB::table()` and `->where('value', 'some-string')` — MySQL's JSON column comparison does not match SQL strings against JSON-encoded strings directly. Use the `AppSettings` service instead, or apply `JSON_UNQUOTE(value) = ?` in raw queries.

Changelog
---------

[](#changelog)

See [CHANGELOG.md](CHANGELOG.md).

License
-------

[](#license)

MIT — see [LICENSE.md](LICENSE.md).

###  Health Score

43

—

FairBetter than 90% of packages

Maintenance100

Actively maintained with recent releases

Popularity5

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity52

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% 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 ~0 days

Total

2

Last Release

1d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/c280c25a4609fb0911955b27ed40e70b9028dd8c1fcfad03beaa87a95c96a2bc?d=identicon)[agroezinger](/maintainers/agroezinger)

---

Top Contributors

[![agroezinger](https://avatars.githubusercontent.com/u/12061647?v=4)](https://github.com/agroezinger "agroezinger (3 commits)")

---

Tags

laravelfilamentapp settingsagroezinger

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/agroezinger-filament-app-settings/health.svg)

```
[![Health](https://phpackages.com/badges/agroezinger-filament-app-settings/health.svg)](https://phpackages.com/packages/agroezinger-filament-app-settings)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3345.1M337](/packages/psalm-plugin-laravel)[spatie/laravel-health

Monitor the health of a Laravel application

87411.3M152](/packages/spatie-laravel-health)[laracraft-tech/laravel-useful-additions

A collection of useful Laravel additions!

58122.8k](/packages/laracraft-tech-laravel-useful-additions)[simplestats-io/laravel-client

Analytics for Laravel. Track visitors, registrations, and payments. Discover which channels actually drive revenue, not just traffic. Server-side, GDPR compliant, ad-blocker proof.

5019.3k](/packages/simplestats-io-laravel-client)[wearepixel/laravel-cart

A cart implementation for Laravel

1355.6k](/packages/wearepixel-laravel-cart)[promethys/revive

A 'RecycleBin' page where users can restore or delete permanently soft-deleted models.

162.5k](/packages/promethys-revive)

PHPackages © 2026

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