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 Settings Laravel Package

spatie/laravel-settings

Store strongly typed app settings in Laravel using dedicated Settings classes backed by databases, Redis, and more. Inject settings via the container, read and update properties, then save—keeping configuration structured, testable, and easy to manage.

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Steps to Begin
1. **Installation**
   ```bash
   composer require spatie/laravel-settings
   php artisan vendor:publish --provider="Spatie\LaravelSettings\LaravelSettingsServiceProvider" --tag="migrations"
   php artisan vendor:publish --provider="Spatie\LaravelSettings\LaravelSettingsServiceProvider" --tag="config"
   php artisan migrate
  1. Create a Settings Class

    php artisan make:setting GeneralSettings --group=general
    

    This generates a class in app/Settings/GeneralSettings.php:

    class GeneralSettings extends Settings {
        public string $site_name = 'Default Site';
        public bool $site_active = true;
    
        public static function group(): string {
            return 'general';
        }
    }
    
  2. Register the Settings Class Add the class to config/settings.php under the settings array:

    'settings' => [
        Spatie\LaravelSettings\Settings\GeneralSettings::class,
    ],
    
  3. Create a Migration

    php artisan make:settings-migration CreateGeneralSettings
    

    Define defaults in database/settings/YYYY_MM_DD_CreateGeneralSettings.php:

    public function up(): void {
        $this->migrator->add('general.site_name', 'My App');
        $this->migrator->add('general.site_active', true);
    }
    

    Run migrations:

    php artisan migrate
    
  4. Use in Code Inject the settings class into a controller or service:

    public function index(GeneralSettings $settings) {
        return view('home', ['site_name' => $settings->site_name]);
    }
    

Implementation Patterns

Dependency Injection

  • Controllers/Views: Directly inject settings classes into controllers or pass them to views.
    public function show(GeneralSettings $settings) {
        return view('settings', compact('settings'));
    }
    
  • Services/Jobs: Use constructor injection for reusable logic.
    public function __construct(private GeneralSettings $settings) {}
    

Repository Selection

  • Default Repository: Configure default_repository in config/settings.php (e.g., database or redis).
  • Custom Repositories: Override the repository for a specific settings class:
    public static function repository(): ?string {
        return 'redis';
    }
    

Caching

  • Enable caching in config/settings.php:
    'cache' => [
        'enabled' => true,
        'store' => 'redis',
        'ttl' => 60, // Cache for 60 minutes
    ],
    
  • Cache Invalidation: Call $settings->save() to invalidate cached values.

Form Handling

  • Validation: Use Form Requests to validate input before updating:
    public function update(GeneralSettingsRequest $request, GeneralSettings $settings) {
        $settings->site_name = $request->validated('site_name');
        $settings->save();
    }
    
  • Mass Assignment: Use fill() for bulk updates:
    $settings->fill($request->validated());
    $settings->save();
    

Grouped Settings

  • Organize by Domain: Use distinct groups (e.g., auth, payment, notifications).
    class AuthSettings extends Settings {
        public static function group(): string {
            return 'auth';
        }
    }
    

Dynamic Defaults

  • Lazy Initialization: Set defaults in the class or migration:
    public string $api_key = env('API_KEY', 'default_key');
    

Gotchas and Tips

Pitfalls

  1. Missing Migrations

    • Issue: Forgetting to run migrations after adding new properties.
    • Fix: Always run php artisan migrate after creating/updating migrations.
  2. Incorrect Group Names

    • Issue: Typos in group() method or migration paths (e.g., general vs General).
    • Fix: Use consistent naming (e.g., snake_case) and validate with:
      $this->migrator->exists('general.site_name');
      
  3. Circular Dependencies

    • Issue: Settings classes depending on each other (e.g., AuthSettings using UserSettings).
    • Fix: Use lazy loading or resolve dependencies via the container.
  4. Type Mismatches

    • Issue: Storing a string as an int or vice versa.
    • Fix: Use explicit casts in global_casts or define casts in the settings class:
      use Spatie\LaravelSettings\SettingsCasts\Cast;
      
      public int $user_count;
      public static function casts(): array {
          return [
              'user_count' => Cast::asInt(),
          ];
      }
      
  5. Repository Misconfiguration

    • Issue: Settings not saving/loading due to incorrect repository settings.
    • Fix: Verify default_repository and per-class repository() methods.

Debugging Tips

  • Check Repository Contents:

    $repository = app('settings.repositories.database');
    $data = $repository->get('general');
    dd($data);
    
  • Enable Logging: Add to config/settings.php:

    'debug' => true,
    

    Logs will appear in storage/logs/laravel.log.

  • Validate Migrations: Use php artisan settings:list to inspect stored settings:

    php artisan settings:list general
    

Extension Points

  1. Custom Repositories

    • Implement Spatie\LaravelSettings\SettingsRepositories\SettingsRepository for custom storage (e.g., S3, DynamoDB).
  2. Custom Encoders/Decoders

    • Override encoder/decoder in config/settings.php for non-JSON storage (e.g., YAML):
      'encoder' => function ($value) { return yaml_emit([$value]); },
      'decoder' => function ($value) { return yaml_parse($value)[0]; },
      
  3. Event Listeners

    • Listen for settings.saved or settings.updated events:
      Event::listen(SettingsSaved::class, function (SettingsSaved $event) {
          Log::info("Settings updated: {$event->settingsClass}");
      });
      
  4. Dynamic Settings

    • Use Settings::make() for runtime-created settings (not recommended for production):
      $tempSettings = Settings::make('temp', [
          'value' => 'dynamic',
      ]);
      

Performance Tips

  • Cache Aggressively: Enable caching for frequently accessed settings:
    'cache' => [
        'enabled' => true,
        'ttl' => 3600, // 1 hour
    ],
    
  • Batch Updates: Use fill() to minimize database writes:
    $settings->fill($request->all());
    $settings->save();
    
  • Avoid Eager Loading: Only inject settings where needed (Laravel’s container handles lazy loading).

Security

  • Sensitive Data: Avoid storing secrets (use Laravel’s env() or vaults like Hashicorp Vault).
  • Authorization: Gate access to settings updates:
    public function update(Request $request, GeneralSettings $settings) {
        $this->authorize('update-settings');
        // ...
    }
    
  • Input Sanitization: Always validate input before updating settings.

Testing

  • Mock Repositories: Replace the default repository in tests:
    $this->app->bind(
        'settings.repositories.database',
        fn() => new MockRepository()
    );
    
  • Assertions: Use assertEquals to verify settings:
    $settings = app(GeneralSettings::class);
    $this->assertEquals('Expected', $settings->site_name);
    
  • Migration Tests: Test migrations with:
    $this->artisan('migrate:fresh')
         ->expectsQuestion('Do you really wish to...', 'yes')
         ->run();
    

---
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.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport