PHPackages                             metalinked/laravel-settings-kit - 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. [Caching](/categories/caching)
4. /
5. metalinked/laravel-settings-kit

ActiveLibrary[Caching](/categories/caching)

metalinked/laravel-settings-kit
===============================

A comprehensive Laravel package for managing global and user-specific settings, with role-based permissions, multi-language support, auto-creation, and a full REST API for headless and modern applications.

v1.1.0(7mo ago)0176MITPHPPHP ^8.1|^8.2|^8.3CI passing

Since Aug 12Pushed 7mo agoCompare

[ Source](https://github.com/metalinked/laravel-settings-kit)[ Packagist](https://packagist.org/packages/metalinked/laravel-settings-kit)[ Docs](https://github.com/metalinked/laravel-settings-kit)[ RSS](/packages/metalinked-laravel-settings-kit/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (5)Dependencies (8)Versions (7)Used By (0)

Laravel Settings Kit
====================

[](#laravel-settings-kit)

[![Tests](https://camo.githubusercontent.com/3d42c955bcbf60d19299922dd6d553aaaf044d60ebcfd9a0eed70792b5bfb334/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6d6574616c696e6b65642f6c61726176656c2d73657474696e67732d6b69742f74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/metalinked/laravel-settings-kit/actions/workflows/tests.yml)[![GitHub Release](https://camo.githubusercontent.com/b8927c4e1c2b899d7f413c194710561a555b09ad9faa2fafca83417f119ddf74/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f6d6574616c696e6b65642f6c61726176656c2d73657474696e67732d6b69743f7374796c653d666c61742d737175617265)](https://github.com/metalinked/laravel-settings-kit/releases)[![Total Downloads](https://camo.githubusercontent.com/d2a21c26c49241303e059e23452a1f89534dffdf0f4a6b6e6b51021d88a805d4/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6d6574616c696e6b65642f6c61726176656c2d73657474696e67732d6b69743f7374796c653d666c61742d737175617265)](https://packagist.org/packages/metalinked/laravel-settings-kit)[![License](https://camo.githubusercontent.com/6c321910620c72bdd25382dcab507a97c4ab47e6ac9e334e009e89169185bf8b/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6d6574616c696e6b65642f6c61726176656c2d73657474696e67732d6b69743f7374796c653d666c61742d737175617265)](https://github.com/metalinked/laravel-settings-kit/blob/main/LICENSE.md)

A comprehensive Laravel package for managing global and user-specific settings with role-based permissions, multi-language support, auto-creation capabilities, and a complete REST API for headless applications.

🚀 Quick Start
-------------

[](#-quick-start)

Install the package and get started in minutes:

```
# Install the package
composer require metalinked/laravel-settings-kit

# Publish and run migrations
php artisan vendor:publish --provider="Metalinked\LaravelSettingsKit\SettingsKitServiceProvider" --tag="migrations"
php artisan migrate
```

**Basic Usage:**

```
use Metalinked\LaravelSettingsKit\Facades\Settings;

// Get settings (with auto-creation if they don't exist)
$siteName = Settings::get('site_name') ?? 'My App';
$userTheme = Settings::get('theme', $userId) ?? 'light';

// Set settings (auto-creates if needed)
Settings::set('site_name', 'My Awesome App');           // Global setting
Settings::set('theme', 'dark', $userId);                // User setting

// Check boolean settings
if (Settings::isEnabled('maintenance_mode')) {
    // Show maintenance page
}
```

**That's it!** The package automatically creates settings as you use them.

📚 Table of Contents
-------------------

[](#-table-of-contents)

- [🚀 Quick Start](#-quick-start)
- [✨ Features](#-features)
- [📦 Installation](#-installation)
- [🎯 Basic Usage](#-basic-usage)
- [📊 Types of Settings](#-types-of-settings)
- [🌍 Multilingual Support](#-multilingual-support)
- [🔌 REST API](#-rest-api)
- [🚀 Advanced Features](#-advanced-features)
- [🔧 Configuration](#-configuration)
- [🔧 Troubleshooting](#-troubleshooting)
- [🧪 Testing](#-testing)
- [🤝 Contributing](#-contributing)
- [📄 License](#-license)

✨ Features
----------

[](#-features)

- 🌍 **Global and User-specific Settings** - Manage both application-wide and individual user preferences
- 👥 **Role-based Permissions** - Control which settings are visible/editable by user roles
- 🌐 **Multi-language Support** - Full multilingual support with automatic fallbacks
- 📊 **Multiple Data Types** - Support for string, boolean, integer, JSON, and select options
- 🚀 **Auto-Creation** - Automatically create settings on-the-fly with intelligent type detection
- 🔌 **REST API** - Complete API for headless applications and JavaScript frameworks
- 🔐 **Flexible Authentication** - Support for token, Sanctum, and Passport authentication
- ⚡ **Cache Support** - Built-in caching to reduce database queries
- 💾 **Database Agnostic** - Works with any Laravel-supported database

📦 Installation
--------------

[](#-installation)

### Requirements

[](#requirements)

- PHP 8.1 or higher
- Laravel 10.0 or higher

### Step 1: Install Package

[](#step-1-install-package)

```
composer require metalinked/laravel-settings-kit
```

### Step 2: Run Migrations

[](#step-2-run-migrations)

```
php artisan vendor:publish --provider="Metalinked\LaravelSettingsKit\SettingsKitServiceProvider" --tag="migrations"
php artisan migrate
```

### Step 3: Publish Config (Optional)

[](#step-3-publish-config-optional)

```
php artisan vendor:publish --provider="Metalinked\LaravelSettingsKit\SettingsKitServiceProvider" --tag="config"
```

🎯 Basic Usage
-------------

[](#-basic-usage)

### Simple Settings Management

[](#simple-settings-management)

```
use Metalinked\LaravelSettingsKit\Facades\Settings;

// Get a setting (returns null if not found)
$value = Settings::get('app_name');

// Set a setting (auto-creates if it doesn't exist)
Settings::set('app_name', 'My Application');

// Get user-specific setting
$userTheme = Settings::get('theme', $userId);

// Set user-specific setting
Settings::set('theme', 'dark', $userId);

// Check if setting is enabled (boolean check)
if (Settings::isEnabled('maintenance_mode')) {
    abort(503, 'Under maintenance');
}

// Get all settings
$allSettings = Settings::all();

// Get settings by category
$systemSettings = Settings::all(category: 'system');
```

### Auto-Creation with Type Detection

[](#auto-creation-with-type-detection)

The package automatically detects data types when creating settings:

```
Settings::set('maintenance_mode', false);              // Creates boolean
Settings::set('max_users', 100);                       // Creates integer
Settings::set('app_name', 'My App');                   // Creates string
Settings::set('config', ['key' => 'value']);           // Creates JSON
```

📊 Types of Settings
-------------------

[](#-types-of-settings)

The package supports two distinct types of settings:

### Global Unique Settings

[](#global-unique-settings)

Settings that apply to the entire application. When you change them, you're modifying the global default value.

```
// Examples: maintenance_mode, site_name, max_upload_size
Settings::set('maintenance_mode', true);    // Affects entire application
Settings::set('site_name', 'My Site');      // Changes site name for everyone
```

### User Customizable Settings

[](#user-customizable-settings)

Settings with global defaults that individual users can override.

```
// Global default (affects all users who haven't customized)
Settings::set('theme', 'light');            // Sets default theme to 'light'

// User customization (only affects specific user)
Settings::set('theme', 'dark', 123);        // User 123 prefers dark theme

// Results:
Settings::get('theme');                      // Returns 'light' (global default)
Settings::get('theme', 123);                // Returns 'dark' (user's preference)
Settings::get('theme', 456);                // Returns 'light' (inherits default)
```

### Creating Predefined Settings

[](#creating-predefined-settings)

For better control, create settings upfront using a seeder:

```
// database/seeders/SettingsSeeder.php
use Metalinked\LaravelSettingsKit\Models\Preference;

public function run(): void {
    $settings = [
        // Global unique settings
        [
            'key' => 'maintenance_mode',
            'type' => 'boolean',
            'default_value' => '0',
            'category' => 'system',
            'is_user_customizable' => false,
        ],
        [
            'key' => 'site_name',
            'type' => 'string',
            'default_value' => 'My Application',
            'category' => 'general',
            'is_user_customizable' => false,
        ],
        // User customizable settings
        [
            'key' => 'theme',
            'type' => 'select',
            'default_value' => 'light',
            'category' => 'appearance',
            'options' => ['light', 'dark', 'auto'],
            'is_user_customizable' => true,
        ],
        [
            'key' => 'notifications_enabled',
            'type' => 'boolean',
            'default_value' => '1',
            'category' => 'preferences',
            'is_user_customizable' => true,
        ],
    ];

    foreach ($settings as $setting) {
        Preference::firstOrCreate(['key' => $setting['key']], $setting);
    }
}
```

### Using Settings

[](#using-settings)

```
// Set a global setting (throws exception if preference doesn't exist)
Settings::set('allow_comments', true);

// Set a user-specific setting
Settings::set('email_notifications', false, $userId);

// Set a setting with auto-creation (creates preference if it doesn't exist)
Settings::setWithAutoCreate('new_feature_enabled', true);

// Check if a setting is enabled (boolean)
if (Settings::isEnabled('maintenance_mode')) {
    // Application is in maintenance mode
}

// Get translated label and description
$label = Settings::label('allow_comments');
$description = Settings::description('allow_comments');
```

### Creating Settings with Auto-Detection

[](#creating-settings-with-auto-detection)

```
// Automatically create settings with type detection
Settings::setWithAutoCreate('maintenance_mode', false); // Creates boolean preference
Settings::setWithAutoCreate('items_per_page', 20);      // Creates integer preference
Settings::setWithAutoCreate('theme_config', ['dark' => true]); // Creates JSON preference

// Check if a setting exists before using
if (Settings::has('feature_enabled')) {
    $value = Settings::get('feature_enabled');
}

// Create setting only if it doesn't exist
Settings::createIfNotExists('welcome_message', [
    'type' => 'string',
    'default_value' => 'Welcome to our app!',
    'category' => 'general'
]);
```

🌍 Multilingual Support
----------------------

[](#-multilingual-support)

Add translations to make your settings interface multilingual:

### Adding Translations

[](#adding-translations)

```
use Metalinked\LaravelSettingsKit\Facades\Settings;

// Create setting with translations
Settings::createWithTranslations('notification_email', [
    'type' => 'boolean',
    'default_value' => '1',
    'category' => 'notifications',
], [
    'en' => [
        'title' => 'Email Notifications',
        'description' => 'Receive notifications via email'
    ],
    'es' => [
        'title' => 'Notificaciones por Email',
        'description' => 'Recibir notificaciones por correo electrónico'
    ],
    'ca' => [
        'title' => 'Notificacions per Email',
        'description' => 'Rebre notificacions per correu electrònic'
    ]
]);
```

### Using Translations

[](#using-translations)

```
// Get translated labels and descriptions
$label = Settings::label('notification_email', 'es');          // "Notificaciones por Email"
$description = Settings::description('notification_email', 'ca'); // "Rebre notificacions per correu electrònic"

// Auto-fallback to English if translation missing
$label = Settings::label('notification_email', 'fr');          // "Email Notifications" (fallback)
```

### Bulk Translation Management

[](#bulk-translation-management)

```
// Add translations to existing settings
Settings::addTranslations('theme', [
    'en' => ['title' => 'Theme', 'description' => 'Choose your preferred theme'],
    'es' => ['title' => 'Tema', 'description' => 'Elige tu tema preferido'],
    'ca' => ['title' => 'Tema', 'description' => 'Tria el teu tema preferit']
]);

// Add translations with more data
Settings::addTranslations('newsletter_signup', [
    'es' => [
        'label' => 'Suscripción al Boletín',
        'description' => 'Habilita el formulario de suscripción al boletín'
    ]
]);

// Get all settings with translations for a specific locale
$settings = Settings::allWithTranslations('ca');

// This returns an array like:
[
    'maintenance_mode' => [
        'value' => false,
        'type' => 'boolean',
        'category' => 'system',
        'label' => 'Mode Manteniment',
        'description' => 'Activar el mode de manteniment...',
        'key' => 'maintenance_mode'
    ]
]
```

🔌 REST API
----------

[](#-rest-api)

The package provides a complete REST API for managing settings, perfect for headless Laravel applications, mobile apps, or frontend JavaScript frameworks.

### API Configuration

[](#api-configuration)

The API supports both development and production environments with different setup requirements.

#### 🛠️ Development Setup (Quick Start)

[](#️-development-setup-quick-start)

For local development and testing, you can bypass authentication entirely:

```
# Enable API
SETTINGS_KIT_API_ENABLED=true

# Bypass authentication in local/testing environments
SETTINGS_KIT_API_DISABLE_AUTH_DEV=true

# Auto-create missing settings (recommended for development)
SETTINGS_KIT_API_AUTO_CREATE=true

# Optional: Custom API prefix
SETTINGS_KIT_API_PREFIX=api/settings-kit
```

With this setup, you can immediately use the API without any authentication:

```
# Test endpoint
curl http://localhost/api/settings-kit

# Get specific setting
curl http://localhost/api/settings-kit/global/site_name
```

### Production Setup

[](#production-setup)

For production environments, configure proper authentication:

```
# Enable API
SETTINGS_KIT_API_ENABLED=true

# Development (no authentication)
SETTINGS_KIT_API_DISABLE_AUTH_DEV=true

# Production (require authentication)
SETTINGS_KIT_API_DISABLE_AUTH_DEV=false
SETTINGS_KIT_API_AUTH=token
SETTINGS_KIT_API_TOKEN=your-secure-token
```

### Global Settings Endpoints

[](#global-settings-endpoints)

```
# Get all global settings
GET /api/settings-kit/global

# Get specific global setting
GET /api/settings-kit/global/site_name

# Set global setting
POST /api/settings-kit/global/site_name
{
    "value": "My New Site Name"
}

# Update global setting
PUT /api/settings-kit/global/maintenance_mode
{
    "value": true
}

# Reset global setting to default
DELETE /api/settings-kit/global/site_name
```

### User Settings Endpoints

[](#user-settings-endpoints)

```
# Get user's settings
GET /api/settings-kit/user?user_id=123

# Get specific user setting
GET /api/settings-kit/user/theme?user_id=123

# Set user setting
POST /api/settings-kit/user/theme?user_id=123
{
    "value": "dark"
}

# Reset user setting (falls back to global default)
DELETE /api/settings-kit/user/theme?user_id=123
```

### API Response Format

[](#api-response-format)

```
{
    "success": true,
    "data": {
        "theme": {
            "value": "dark",
            "type": "select",
            "category": "appearance",
            "required": false,
            "options": ["light", "dark", "auto"],
            "label": "Theme",
            "description": "Choose your preferred theme",
            "key": "theme"
        }
    },
    "meta": {
        "count": 1,
        "locale": "en",
        "role": null,
        "user_id": 123,
        "category": "appearance"
    }
}
```

### Authentication Examples

[](#authentication-examples)

```
# Development (no token required)
curl http://localhost/api/settings-kit/global/site_name

# Production with token
curl -H "Authorization: Bearer your-token" \
     https://yourapp.com/api/settings-kit/global/site_name

# With Sanctum
curl -H "Authorization: Bearer sanctum-token" \
     https://yourapp.com/api/settings-kit/user/theme?user_id=123
```

**Sanctum Authentication** (User-based):

```
SETTINGS_KIT_API_AUTH=sanctum
```

```
curl -H "Authorization: Bearer user-sanctum-token" \
     http://your-app.com/api/settings-kit
```

**Passport Authentication** (OAuth2):

```
SETTINGS_KIT_API_AUTH=passport
```

### Auto-Creation via API

[](#auto-creation-via-api)

The API can automatically create missing settings when they're accessed. This is perfect for API-first applications:

**Global Configuration (affects all API requests):**

```
# Enable auto-creation for all API requests
SETTINGS_KIT_API_AUTO_CREATE=true
```

**Per-request Control:**

```
# Create setting on-the-fly with auto_create parameter
POST /api/settings-kit/new_setting
{
    "value": "some_value",
    "auto_create": true
}
```

**Behavior:**

- **Config enabled + no parameter**: Auto-creates missing settings
- **Config disabled + `auto_create=true`**: Auto-creates missing settings
- **Config disabled + no parameter**: Returns 404 for missing settings

### API Endpoints

[](#api-endpoints)

#### Core Endpoints

[](#core-endpoints)

- **GET** `/api/settings-kit` - Get all settings with optional filtering
- **GET** `/api/settings-kit/categories` - Get available categories
- **POST** `/api/settings-kit/preferences` - Create new preference

#### Global Settings (System-wide)

[](#global-settings-system-wide)

- **GET** `/api/settings-kit/global/{key}` - Get specific global setting
- **POST** `/api/settings-kit/global/{key}` - Create/update global setting
- **PUT** `/api/settings-kit/global/{key}` - Update global setting
- **DELETE** `/api/settings-kit/global/{key}` - Reset global setting to default

#### User Settings (User-specific)

[](#user-settings-user-specific)

- **GET** `/api/settings-kit/user/{key}` - Get specific user setting
- **POST** `/api/settings-kit/user/{key}` - Create/update user setting
- **PUT** `/api/settings-kit/user/{key}` - Update user setting
- **DELETE** `/api/settings-kit/user/{key}` - Reset user setting to default

#### Legacy Endpoints (Backwards Compatibility)

[](#legacy-endpoints-backwards-compatibility)

- **GET** `/api/settings-kit/{key}` - Get specific setting (auto-detects global/user)
- **POST** `/api/settings-kit/{key}` - Create/update setting value
- **PUT** `/api/settings-kit/{key}` - Update setting value
- **DELETE** `/api/settings-kit/{key}` - Reset setting to default

**Query Parameters:**

- `locale` - Language for translations (e.g., `ca`, `es`, `en`)
- `user_id` - Specify user ID (required for user endpoints)
- `category` - Filter by category
- `role` - Filter by role

**Example Usage:**

```
# Get all settings with Catalan translations
GET /api/settings-kit?locale=ca

# Get specific global setting
GET /api/settings-kit/global/site_name

# Get user-specific setting
GET /api/settings-kit/user/theme?user_id=123

# Update global setting
POST /api/settings-kit/global/maintenance_mode
{"value": true}

# Update user setting
POST /api/settings-kit/user/notifications?user_id=123
{"value": false}

# Set global setting (auto-created if SETTINGS_KIT_API_AUTO_CREATE=true)
POST /api/settings-kit/maintenance_mode
{
    "value": true
}

# Set global setting with explicit auto-creation
POST /api/settings-kit/new_feature_enabled
{
    "value": true,
    "auto_create": true
}

# Set user-specific setting (requires is_user_customizable=true)
POST /api/settings-kit/email_notifications
{
    "value": false,
    "user_id": 123
}
```

**?? Complete API Documentation:** See `examples/API_USAGE.md` for detailed examples, error handling, and JavaScript integration examples.

🎨 Multilingual Interface Examples
---------------------------------

[](#-multilingual-interface-examples)

The package includes practical examples for creating multilingual settings interfaces:

- **Admin Settings Panel** - `examples/admin-settings.blade.php`
- **User Preferences** - `examples/user-settings.blade.php`
- **Multilingual Admin Panel** - `examples/admin-multilingual-settings.blade.php`
- **Controller Examples** - `examples/SettingsControllerExample.php`

📚 API Reference
---------------

[](#-api-reference)

### Settings Facade

[](#settings-facade)

#### `get(string $key, int $userId = null)`

[](#getstring-key-int-userid--null)

Get a setting value. Returns user-specific value if `$userId` is provided and exists, otherwise returns global default.

#### `set(string $key, mixed $value, int $userId = null, bool $autoCreate = false)`

[](#setstring-key-mixed-value-int-userid--null-bool-autocreate--false)

Set a setting value:

- If `$userId` is provided: Sets user-specific value (only for `is_user_customizable = true` settings)
- If `$userId` is null:
    - For global unique settings (`is_user_customizable = false`): Modifies `default_value` directly
    - For user customizable settings (`is_user_customizable = true`): Modifies `default_value` directly (affects all users who haven't customized)
- Set `$autoCreate` to true to create the preference automatically if it doesn't exist

```
// Global setting change (modifies default_value directly)
Settings::set('maintenance_mode', true);

// User-specific setting (only for customizable settings)
Settings::set('theme', 'dark', $userId);
```

#### `setWithAutoCreate(string $key, mixed $value, int $userId = null)`

[](#setwithautocreatestring-key-mixed-value-int-userid--null)

Set a setting value, creating the preference automatically if it doesn't exist.

#### `has(string $key)` / `exists(string $key)`

[](#hasstring-key--existsstring-key)

Check if a preference exists in the database.

#### `isEnabled(string $key, int $userId = null)`

[](#isenabledstring-key-int-userid--null)

Check if a boolean setting is enabled.

#### `label(string $key, string $locale = null)`

[](#labelstring-key-string-locale--null)

Get the translated label for a setting.

#### `description(string $key, string $locale = null)`

[](#descriptionstring-key-string-locale--null)

Get the translated description for a setting.

#### `create(array $data)`

[](#createarray-data)

Create a new preference.

#### `createIfNotExists(string $key, array $data)`

[](#createifnotexistsstring-key-array-data)

Create a preference only if it doesn't already exist.

#### `createWithTranslations(string $key, array $preferenceData, array $translations = [])`

[](#createwithtranslationsstring-key-array-preferencedata-array-translations--)

Create a preference with translations in multiple languages.

#### `addTranslations(string $key, array $translations)`

[](#addtranslationsstring-key-array-translations)

Add or update translations for an existing preference.

#### `forget(string $key, int $userId = null)`

[](#forgetstring-key-int-userid--null)

Reset a setting:

- For **user settings**: Removes the user's custom value, reverting to the global default
- For **global unique settings** (`is_user_customizable = false`): Not applicable - these settings don't have user-specific values
- For **user customizable settings** (`is_user_customizable = true`): Only removes user-specific customizations

```
// Example: Reset user's custom theme back to global default
Settings::forget('theme', $userId);

// Note: Global unique settings cannot be "reset" as they modify default_value directly
```

🔄 Global Overrides vs Default Values
------------------------------------

[](#-global-overrides-vs-default-values)

The package uses a simple and efficient approach based on the setting type:

### 🌐 Global Unique Settings (`is_user_customizable = false`)

[](#-global-unique-settings-is_user_customizable--false)

These settings modify the default value directly and apply to everyone:

```
// Create a global unique setting
Preference::create([
    'key' => 'maintenance_mode',
    'default_value' => '0',
    'is_user_customizable' => false
]);

Settings::set('maintenance_mode', '1');  // Modifies default_value directly
Settings::get('maintenance_mode');       // Returns '1' for everyone
```

### 👤 User Customizable Settings (`is_user_customizable = true`)

[](#-user-customizable-settings-is_user_customizable--true)

These settings allow users to personalize their experience:

- **Global changes**: Modify the `default_value` directly - affects all users who haven't customized
- **User customization**: Creates entries in `user_preferences` table only when needed

### Practical Example

[](#practical-example)

```
// 1. Create user customizable preference
Preference::create([
    'key' => 'theme',
    'default_value' => 'light',
    'is_user_customizable' => true
]);

// 2. Change global default (modifies default_value to 'dark')
Settings::set('theme', 'dark');  // All users without custom preferences see 'dark'

// 3. User personalizes (creates UserPreference entry)
Settings::set('theme', 'custom', 123); // Only user 123 gets 'custom'

// 4. Results:
Settings::get('theme');        // 'dark' (global default)
Settings::get('theme', 123);   // 'custom' (user's preference)
Settings::get('theme', 456);   // 'dark' (global default)
```

### Benefits of This Architecture

[](#benefits-of-this-architecture)

- **⚡ Performance**: Users read directly from `preferences` table unless they have custom values
- **🧹 Clean Data**: `user_preferences` only contains actual user customizations
- **💡 Simple Logic**: Global changes update the default, user changes create personal preferences
- **🔒 Data Integrity**: Clear separation between global and personal settings

🔧 Data Types
------------

[](#-data-types)

The package supports the following data types:

- `string` - Text values
- `boolean` - True/false values
- `integer` - Numeric values
- `json` - JSON objects/arrays
- `select` - Predefined options (stored as JSON in options field)

🚀 Advanced Features
-------------------

[](#-advanced-features)

### Data Architecture

[](#data-architecture)

The package uses an efficient architecture that minimizes database queries:

- **Global Settings**: Stored in `preferences.default_value` - one row per setting
- **User Customizations**: Only stored in `user_preferences` when users actually customize settings
- **Multilingual**: Translations stored in `preference_contents` with fallback to default locale

### Controller Examples

[](#controller-examples)

#### User Settings Panel

[](#user-settings-panel)

```
class UserSettingsController extends Controller {
    public function index() {
        $userId = auth()->id();
        $settings = [
            'email_notifications' => Settings::get('email_notifications', $userId),
            'theme' => Settings::get('theme', $userId),
            'language' => Settings::get('language', $userId),
        ];

        return view('settings.user', compact('settings'));
    }

    public function update(Request $request) {
        $userId = auth()->id();

        foreach ($request->only(['email_notifications', 'theme', 'language']) as $key => $value) {
            Settings::set($key, $value, $userId);
        }

        return redirect()->back()->with('success', 'Settings updated!');
    }
}
```

#### Admin Global Settings

[](#admin-global-settings)

```
class AdminSettingsController extends Controller {
    public function update(Request $request) {
        // Global settings (affects all users)
        Settings::set('maintenance_mode', $request->has('maintenance_mode'));
        Settings::set('max_users', $request->input('max_users', 1000));

        // Auto-create settings
        Settings::setWithAutoCreate('new_feature_flag', $request->has('new_feature'));

        return redirect()->back()->with('success', 'Global settings updated!');
    }
}
```

### Advanced Data Types

[](#advanced-data-types)

#### JSON Settings

[](#json-settings)

```
// Store complex data structures
Settings::set('app_config', [
    'features' => ['darkMode', 'notifications'],
    'limits' => ['users' => 1000, 'storage' => '10GB'],
    'integrations' => ['stripe' => true, 'paypal' => false]
]);

$config = Settings::get('app_config'); // Returns array
```

#### Select Options

[](#select-options)

```
// Create setting with predefined options
Preference::create([
    'key' => 'notification_frequency',
    'default_value' => 'daily',
    'data_type' => 'select',
    'options' => json_encode(['hourly', 'daily', 'weekly', 'never'])
]);
```

### Bulk Operations

[](#bulk-operations)

```
// Set multiple settings at once
$bulkSettings = [
    'app_name' => 'My Application',
    'maintenance_mode' => false,
    'max_file_size' => 2048,
    'allowed_domains' => ['example.com', 'app.com']
];

foreach ($bulkSettings as $key => $value) {
    Settings::setWithAutoCreate($key, $value);
}
```

### Integration Examples

[](#integration-examples)

#### Laravel Livewire

[](#laravel-livewire)

```
class SettingsComponent extends Component {
    public $theme;
    public $notifications;

    public function mount() {
        $userId = auth()->id();
        $this->theme = Settings::get('theme', $userId);
        $this->notifications = Settings::get('email_notifications', $userId);
    }

    public function save() {
        $userId = auth()->id();
        Settings::set('theme', $this->theme, $userId);
        Settings::set('email_notifications', $this->notifications, $userId);

        $this->emit('settingsSaved');
    }
}
```

#### Vue.js Frontend

[](#vuejs-frontend)

```
// API integration example
export class SettingsAPI {
    async getUserSettings(userId) {
        const response = await fetch(`/api/settings-kit/user?user_id=${userId}`, {
            headers: { 'Authorization': `Bearer ${token}` }
        });
        return response.json();
    }

    async updateSetting(key, value, userId = null) {
        const endpoint = userId ? `/api/settings-kit/user/${key}` : `/api/settings-kit/global/${key}`;
        const body = userId ? { value, user_id: userId } : { value };

        return fetch(endpoint, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${token}`
            },
            body: JSON.stringify(body)
        });
    }
}
```

🔧 Configuration
---------------

[](#-configuration)

### Environment Variables

[](#environment-variables)

The package can be configured via your `.env` file:

```
# API Configuration
SETTINGS_KIT_API_ENABLED=true
SETTINGS_KIT_API_DISABLE_AUTH_DEV=false
SETTINGS_KIT_API_AUTH=token
SETTINGS_KIT_API_TOKEN=your-secure-api-token
SETTINGS_KIT_API_AUTO_CREATE=false

# Caching
SETTINGS_KIT_CACHE_ENABLED=true
SETTINGS_KIT_CACHE_TTL=3600

# Routes
SETTINGS_KIT_ROUTES_PREFIX=api/settings-kit
SETTINGS_KIT_ROUTES_MIDDLEWARE=api,auth:sanctum

# User Model
SETTINGS_KIT_USER_MODEL=App\Models\User
```

### Configuration File

[](#configuration-file)

Publish the configuration file to customize advanced settings:

```
php artisan vendor:publish --tag=settings-kit-config
```

This creates `config/settings-kit.php` with the following options:

```
return [
    'api' => [
        'enabled' => env('SETTINGS_KIT_API_ENABLED', true),
        'auth' => env('SETTINGS_KIT_API_AUTH', 'token'),
        'token' => env('SETTINGS_KIT_API_TOKEN', null),
        'auto_create' => env('SETTINGS_KIT_API_AUTO_CREATE', false),
        'disable_auth_dev' => env('SETTINGS_KIT_API_DISABLE_AUTH_DEV', false),
    ],

    'cache' => [
        'enabled' => env('SETTINGS_KIT_CACHE_ENABLED', true),
        'ttl' => env('SETTINGS_KIT_CACHE_TTL', 3600),
        'prefix' => 'settings_kit',
    ],

    'routes' => [
        'prefix' => env('SETTINGS_KIT_ROUTES_PREFIX', 'api/settings-kit'),
        'middleware' => ['api', 'auth:sanctum'],
    ],

    'models' => [
        'user' => env('SETTINGS_KIT_USER_MODEL', 'App\Models\User'),
    ],
];
```

### Authentication Options

[](#authentication-options)

#### 1. Token Authentication (Recommended for APIs)

[](#1-token-authentication-recommended-for-apis)

```
SETTINGS_KIT_API_AUTH=token
SETTINGS_KIT_API_TOKEN=your-secure-token
```

#### 2. Sanctum Authentication (For SPAs)

[](#2-sanctum-authentication-for-spas)

```
SETTINGS_KIT_API_AUTH=sanctum
```

#### 3. Passport Authentication (For OAuth2)

[](#3-passport-authentication-for-oauth2)

```
SETTINGS_KIT_API_AUTH=passport
```

#### 4. Development Bypass (Local/Testing Only)

[](#4-development-bypass-localtesting-only)

```
APP_ENV=local
SETTINGS_KIT_API_DISABLE_AUTH_DEV=true
```

### Custom Middleware

[](#custom-middleware)

You can customize the middleware stack:

```
// In config/settings-kit.php
'routes' => [
    'middleware' => ['api', 'auth:sanctum', 'custom.middleware'],
],
```

### Caching Configuration

[](#caching-configuration)

```
# Redis caching (recommended for production)
CACHE_DRIVER=redis
SETTINGS_KIT_CACHE_ENABLED=true
SETTINGS_KIT_CACHE_TTL=3600  # 1 hour

# File caching (development)
CACHE_DRIVER=file
SETTINGS_KIT_CACHE_ENABLED=true
SETTINGS_KIT_CACHE_TTL=1800  # 30 minutes

# Disable caching (not recommended)
SETTINGS_KIT_CACHE_ENABLED=false
```

🔧 Troubleshooting
-----------------

[](#-troubleshooting)

### Common Issues

[](#common-issues)

#### 🔐 Authentication Problems

[](#-authentication-problems)

**Symptom**: Getting 401/403 errors when accessing API endpoints

**Solutions**:

```
# For development/testing (bypass authentication)
APP_ENV=local
SETTINGS_KIT_API_DISABLE_AUTH_DEV=true

# For production (proper token auth)
SETTINGS_KIT_API_ENABLED=true
SETTINGS_KIT_API_AUTH=token
SETTINGS_KIT_API_TOKEN=your-secure-token

# For Sanctum authentication
SETTINGS_KIT_API_AUTH=sanctum
```

#### 💾 Settings Not Persisting

[](#-settings-not-persisting)

**Symptom**: Settings appear to save but revert after refresh

**Debugging Steps**:

```
# 1. Check database connection
php artisan tinker
>>> \Metalinked\LaravelSettingsKit\Models\Preference::count()

# 2. Verify migrations
php artisan migrate:status

# 3. Clear cache
php artisan cache:clear
php artisan config:clear

# 4. Check file permissions (if using file cache)
ls -la storage/framework/cache/
```

**Common Causes**:

- Database migration not run
- Cache driver misconfiguration
- File permission issues
- Wrong user model configuration

#### 🤖 Auto-Creation Not Working

[](#-auto-creation-not-working)

**Symptom**: New settings aren't created automatically

**Check Configuration**:

```
# Global auto-creation (affects all API requests)
SETTINGS_KIT_API_AUTO_CREATE=true
```

**Manual Auto-Creation**:

```
// Use auto-create methods
Settings::setWithAutoCreate('new_setting', 'value');

// Or with parameter
Settings::set('new_setting', 'value', $userId, true);
```

#### 🐌 Performance Issues

[](#-performance-issues)

**Symptom**: Slow settings retrieval or high database queries

**Optimization**:

```
# Enable caching
SETTINGS_KIT_CACHE_ENABLED=true
SETTINGS_KIT_CACHE_TTL=3600

# Use Redis for better performance
CACHE_DRIVER=redis
```

**Code Optimization**:

```
// Avoid N+1 queries - batch load settings
$userSettings = collect(['theme', 'language', 'notifications'])
    ->mapWithKeys(fn($key) => [$key => Settings::get($key, $userId)]);
```

#### 🌍 Multilingual Issues

[](#-multilingual-issues)

**Symptom**: Translations not loading or fallback not working

**Debugging**:

```
// Check available locales
Settings::addTranslations('setting_key', [
    'en' => ['label' => 'English Label'],
    'es' => ['label' => 'Spanish Label'],
]);

// Test specific locale
Settings::label('setting_key', 'es');
```

#### 🔄 Migration Problems

[](#-migration-problems)

**Symptom**: Migration fails or foreign key constraints

**Solutions**:

```
# Check migration order
php artisan migrate:status

# Rollback and re-run if needed
php artisan migrate:rollback --step=3
php artisan migrate

# Fix foreign key issues
php artisan migrate:fresh --seed
```

### Environment-Specific Issues

[](#environment-specific-issues)

#### Development Environment

[](#development-environment)

```
APP_ENV=local
APP_DEBUG=true
SETTINGS_KIT_API_DISABLE_AUTH_DEV=true
CACHE_DRIVER=file
```

#### Production Environment

[](#production-environment)

```
APP_ENV=production
APP_DEBUG=false
SETTINGS_KIT_API_DISABLE_AUTH_DEV=false
SETTINGS_KIT_API_TOKEN=secure-production-token
CACHE_DRIVER=redis
```

### Debug Commands

[](#debug-commands)

```
# Check package status
php artisan route:list | grep settings-kit

# Test API endpoints
curl -H "Authorization: Bearer your-token" \
     http://localhost/api/settings-kit

# Verify database structure
php artisan tinker
>>> Schema::hasTable('preferences')
>>> Schema::hasTable('preference_contents')
>>> Schema::hasTable('user_preferences')
```

🧪 Testing
---------

[](#-testing)

Run the test suite:

```
composer test
```

🤝 Contributing
--------------

[](#-contributing)

Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details.

🔒 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

37

—

LowBetter than 83% of packages

Maintenance64

Regular maintenance activity

Popularity10

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity55

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 80% 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 ~12 days

Total

5

Last Release

224d ago

### Community

Maintainers

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

---

Top Contributors

[![oskratch](https://avatars.githubusercontent.com/u/16107567?v=4)](https://github.com/oskratch "oskratch (20 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (5 commits)")

---

Tags

api-restcachinglaravelphppreferencessettingslaravelconfigurationSettingsmultilingualrolespreferencesuser settings

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/metalinked-laravel-settings-kit/health.svg)

```
[![Health](https://phpackages.com/badges/metalinked-laravel-settings-kit/health.svg)](https://phpackages.com/packages/metalinked-laravel-settings-kit)
```

###  Alternatives

[hasinhayder/tyro-dashboard

Tyro Dashboard - Beautiful admin dashboard for managing Tyro roles, privileges, users, and settings

5151.4k](/packages/hasinhayder-tyro-dashboard)[alexmg86/laravel-sub-query

Laravel subquery

7538.4k](/packages/alexmg86-laravel-sub-query)[dragon-code/laravel-cache

An improved interface for working with cache

6844.8k10](/packages/dragon-code-laravel-cache)[omaralalwi/lexi-translate

Laravel translation package with morph relationships and caching.

754.3k2](/packages/omaralalwi-lexi-translate)[nexxai/laravel-cfcache

A handful of Cloudflare cache helpers for Laravel

1317.7k](/packages/nexxai-laravel-cfcache)

PHPackages © 2026

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