Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Model Settings Laravel Package

glorand/laravel-model-settings

Add per-model settings to Laravel Eloquent with an easy API to get/set/check/remove values. Choose storage via JSON field, separate settings table, or Redis. Supports defaults, validation, and persistence for user or entity preferences.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require glorand/laravel-model-settings
    

    Publish the config (optional):

    php artisan vendor:publish --provider="Glorand\LaravelModelSettings\ServiceProvider" --tag="config"
    
  2. First Use Case: Define a settings model (e.g., UserSettings):

    use Glorand\LaravelModelSettings\Traits\HasSettings;
    
    class User extends Authenticatable
    {
        use HasSettings;
    }
    

    Create a migration for settings (e.g., user_settings):

    php artisan make:migration create_user_settings_table
    

    Define a settings schema (e.g., app/Models/UserSettings.php):

    namespace App\Models;
    
    use Glorand\LaravelModelSettings\Contracts\SettingsSchema;
    
    class UserSettings implements SettingsSchema
    {
        public function schema(): array
        {
            return [
                'theme' => 'light',
                'notifications' => true,
                'language' => 'en',
            ];
        }
    }
    
  3. First Interaction:

    // Set settings for a user
    $user = User::find(1);
    $user->settings()->set([
        'theme' => 'dark',
        'language' => 'es',
    ]);
    
    // Get settings
    $theme = $user->settings->theme; // 'dark'
    

Implementation Patterns

Core Workflows

  1. Dynamic Settings Management: Use settings() to access a fluent interface for nested or complex settings:

    $user->settings()->set('preferences.email_notifications', true);
    $user->settings()->increment('preferences.unread_messages');
    
  2. Default Values & Fallbacks: Leverage the schema to enforce defaults:

    class UserSettings implements SettingsSchema
    {
        public function schema(): array
        {
            return [
                'privacy' => [
                    'share_location' => false,
                    'share_contacts' => false,
                ],
            ];
        }
    }
    

    Access with:

    $user->settings->privacy->share_location; // false (default)
    
  3. Validation & Sanitization: Extend the schema to include validation rules:

    class UserSettings implements SettingsSchema
    {
        public function schema(): array
        {
            return [
                'account' => [
                    'max_upload_size' => [
                        'value' => 10,
                        'rules' => ['integer', 'min:1', 'max:100'],
                    ],
                ],
            ];
        }
    }
    

    Validate before saving:

    $user->settings()->validate();
    
  4. Caching & Performance: Enable caching for frequently accessed settings:

    // In config/model-settings.php
    'cache' => [
        'enabled' => true,
        'driver' => 'redis',
        'prefix' => 'settings_',
    ],
    

    Clear cache manually when needed:

    $user->settings()->clearCache();
    
  5. Multi-Tenant Support: Use the tenant option to scope settings by tenant:

    $user->settings(['tenant' => 'acme'])->set('theme', 'dark');
    

Integration Tips

  • Events: Listen for settings.saved or settings.updated events:
    event(new SettingsSaved($user, $oldSettings, $newSettings));
    
  • API Responses: Serialize settings with toArray() or toJson():
    return response()->json($user->settings->toArray());
    
  • Admin Panels: Use the package with Laravel Nova/Panel for UI management:
    Nova::resources([
        \App\Nova\UserSettingsResource::class,
    ]);
    

Gotchas and Tips

Common Pitfalls

  1. Schema Mismatches:

    • Issue: Changing the schema after data exists can corrupt settings.
    • Fix: Use migrations to handle schema changes gracefully:
      // In a migration
      Schema::table('user_settings', function (Blueprint $table) {
          $table->json('settings')->nullable()->change();
      });
      
    • Tip: Use schemaVersion in the settings table to track changes.
  2. Caching Conflicts:

    • Issue: Stale cached settings after updates.
    • Fix: Always call clearCache() after manual updates or use touch():
      $user->settings()->set('theme', 'dark')->touch();
      
  3. Nested Array Overwrites:

    • Issue: set() overwrites entire nested arrays instead of merging.
    • Fix: Use merge() for nested updates:
      $user->settings()->merge('preferences', ['theme' => 'dark']);
      
  4. Mass Assignment Risks:

    • Issue: Unintended mass assignment vulnerabilities.
    • Fix: Explicitly whitelist allowed fields in the schema or use fillable:
      class UserSettings implements SettingsSchema
      {
          protected $fillable = ['theme', 'language'];
      
          public function schema(): array { ... }
      }
      

Debugging Tips

  • Inspect Raw Data:
    $user->settings()->getRaw(); // Returns the full JSON/array
    
  • Enable Logging:
    // In config/model-settings.php
    'debug' => env('APP_DEBUG', false),
    
  • Check for Serialization Issues:
    • Ensure all values are JSON-serializable. Use json_encode() checks:
      if (json_encode($value) === false) {
          throw new \InvalidArgumentException('Value must be JSON-serializable');
      }
      

Extension Points

  1. Custom Storage: Override the default storage (e.g., database) by binding a custom repository:

    $this->app->bind(
        \Glorand\LaravelModelSettings\Contracts\SettingsRepository::class,
        \App\Repositories\CustomSettingsRepository::class
    );
    
  2. Custom Serialization: Extend the Settings model to handle custom types:

    use Glorand\LaravelModelSettings\Models\Settings;
    
    class CustomSettings extends Settings
    {
        protected $casts = [
            'color_palette' => 'array',
            'last_login' => 'datetime',
        ];
    }
    
  3. Policy Integration: Attach policies to settings models:

    class UserSettingsPolicy
    {
        public function update(User $user, User $settingsOwner)
        {
            return $user->id === $settingsOwner->id;
        }
    }
    

    Register in AuthServiceProvider:

    $this->policy(Settings::class, UserSettingsPolicy::class);
    
  4. Observer Hooks: Extend the SettingsObserver for custom logic:

    use Glorand\LaravelModelSettings\Observers\SettingsObserver;
    
    class CustomSettingsObserver extends SettingsObserver
    {
        public function saving($settings)
        {
            // Custom logic before save
        }
    }
    

    Bind in ServiceProvider:

    $this->app->singleton(SettingsObserver::class, CustomSettingsObserver::class);
    

Configuration Quirks

  • Default Driver: The package defaults to database. For other drivers (e.g., cache, redis), ensure the driver is configured in config/model-settings.php:
    'driver' => env('SETTINGS_DRIVER', 'database'),
    
  • Table Naming: Customize the settings table name:
    // In config/model-settings.php
    'table' => 'custom_settings',
    
  • JSON vs. Array: The package uses JSON under the hood. For large settings, consider array columns instead:
    $table->json('settings')->nullable(); // Default
    $table->text('settings')->nullable(); // Alternative for large data
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
comsave/common
alecsammon/php-raml-parser
chrome-php/wrench
lendable/composer-license-checker
typhoon/reflection
mesilov/moneyphp-percentage
mike42/gfx-php
bookdown/themes
aura/view
aura/html
aura/cli
povils/phpmnd
nayjest/manipulator
omnipay/tests
psr-mock/http-message-implementation
psr-mock/http-factory-implementation
psr-mock/http-client-implementation
voku/email-check
voku/urlify
rtheunissen/guzzle-log-middleware