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

Settings Main Laravel Package

baks-dev/settings-main

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Steps to First Use
1. **Install the Package**
   ```bash
   composer require baks-dev/settings-main
  • Ensures baks-dev/settings-main and its dependencies (doctrine/dbal, symfony/console) are installed.
  1. Publish Configuration

    php artisan vendor:publish --provider="BaksDev\SettingsMain\SettingsServiceProvider" --tag="config"
    
    • Publishes the default config to config/settings-main.php. Edit this file to define your setting groups and default values.
  2. Run Migrations

    php artisan doctrine:migrations:diff
    php artisan doctrine:migrations:migrate
    
    • Creates the settings table (or updates schema if migrating from a previous version).
  3. First Setting Access Retrieve a setting in your code:

    use BaksDev\SettingsMain\Facades\Settings;
    
    $value = Settings::get('app.feature_flags.new_ui');
    // Returns the value from the database or config fallback.
    
  4. Update a Setting (Admin Flow) Use the package’s console command or build a custom admin controller:

    php artisan settings:update --key="app.feature_flags.new_ui" --value="true"
    
    • For a UI, create a form that calls:
      Settings::set('key', $value);
      

Implementation Patterns

Core Workflows

1. Defining Settings

  • Config-Driven: Define settings in config/settings-main.php:
    'groups' => [
        'app' => [
            'feature_flags' => [
                'new_ui' => [
                    'type' => 'boolean',
                    'default' => false,
                    'description' => 'Enable new UI for all users',
                ],
            ],
        ],
    ],
    
  • Dynamic Groups: Extend via service provider or migrations for runtime-defined settings.

2. Accessing Settings

  • Facade Pattern (recommended for simplicity):
    $isEnabled = Settings::get('app.feature_flags.new_ui', false);
    
  • Service Container Binding:
    $this->app->bind('settings', function () {
        return new SettingsManager();
    });
    

3. Admin Interface Integration

  • Console Commands:
    # Update a setting
    php artisan settings:update --key="app.feature_flags.new_ui" --value="true"
    
    # List all settings
    php artisan settings:list
    
  • Custom Controller:
    public function update(Request $request) {
        $request->validate(['key' => 'required', 'value' => 'required']);
        Settings::set($request->key, $request->value);
        return back()->with('success', 'Setting updated');
    }
    

4. Validation and Types

  • Type-Safe Access:
    // Returns `false` if not boolean
    $boolValue = Settings::get('app.feature_flags.new_ui', false, 'boolean');
    
  • Custom Validators: Override the Validator class in the package’s service provider:
    $this->app->bind('settings.validator', function () {
        return new CustomSettingsValidator();
    });
    

5. Multi-Tenant Support

  • Tenant-Aware Settings:
    Settings::forTenant($tenantId)->get('app.timezone');
    
  • Migration Hooks: Extend the SettingsMigration class to add tenant_id columns if needed.

Integration Tips

Laravel-Specific Patterns

  1. Config Fallback: Settings default to config/settings-main.php if not found in the database. Override in bootstrap/app.php:

    $app->singleton('settings', function () {
        return new SettingsManager(app('config')->get('settings-main'));
    });
    
  2. Event Listeners: Listen for setting changes:

    Settings::onUpdate(function ($key, $oldValue, $newValue) {
        Log::info("Setting {$key} changed from {$oldValue} to {$newValue}");
    });
    
  3. Caching Layer: Cache settings globally or per-tenant:

    Settings::remember('app.feature_flags', 60); // Cache for 60 seconds
    
  4. Testing: Use the --group=settings-main flag:

    phpunit --group=settings-main
    

    Mock settings in tests:

    Settings::shouldReceive('get')->andReturn(true);
    

Performance Optimizations

  • Batch Loading:
    $settings = Settings::getMultiple([
        'app.feature_flags.new_ui',
        'app.feature_flags.experimental_api',
    ]);
    
  • Database Indexing: Ensure the settings table has indexes on key and tenant_id (if multi-tenant).

Gotchas and Tips

Common Pitfalls

  1. Migration Conflicts

    • Issue: Running doctrine:migrations:diff after manual DB changes may cause conflicts.
    • Fix: Reset migrations or use --force:
      php artisan doctrine:migrations:execute --force
      
  2. Type Mismatches

    • Issue: Storing a string as a boolean setting may return unexpected results.
    • Fix: Use strict typing:
      Settings::get('key', false, 'boolean');
      
  3. Caching Stale Data

    • Issue: Laravel’s config cache may serve stale setting values.
    • Fix: Clear cache after updates:
      php artisan config:clear
      php artisan cache:clear
      
  4. Multi-Tenant Isolation

    • Issue: Forgetting to scope settings by tenant in a multi-tenant app.
    • Fix: Always use Settings::forTenant($id) or store tenant_id in the key (e.g., tenant_123.app.timezone).
  5. Console Command Overrides

    • Issue: Custom commands may conflict with the package’s built-in ones.
    • Fix: Rename or namespace your commands:
      php artisan myapp:settings:update
      

Debugging Tips

  1. Inspect Database

    php artisan tinker
    >>> \DB::table('settings')->get();
    
  2. Log Setting Access Add to SettingsServiceProvider:

    Settings::onAccess(function ($key) {
        \Log::debug("Setting accessed: {$key}");
    });
    
  3. Validate Migrations Check the generated migration SQL:

    php artisan doctrine:migrations:diff --dry-run
    
  4. Test Edge Cases

    • Empty Values: Settings::get('nonexistent_key') should return null or a default.
    • Concurrent Writes: Test race conditions with:
      php artisan tinker
      >>> Settings::set('key', 'value1');
      >>> Settings::set('key', 'value2'); // Should overwrite or fail?
      

Extension Points

  1. Custom Storage Backends Override the SettingsRepository interface to use Redis or a custom DB:

    $this->app->bind('settings.repository', function () {
        return new RedisSettingsRepository();
    });
    
  2. Dynamic Setting Groups Add groups via a migration or seeder:

    // In a seeder
    Settings::addGroup('dynamic_group', [
        'setting1' => ['type' => 'string', 'default' => 'value'],
    ]);
    
  3. Access Control Restrict setting updates by role:

    Settings::authorize(function ($key, $user) {
        return $user->can('update-settings');
    });
    
  4. Webhook Triggers Dispatch events on setting changes:

    Settings::onUpdate(function ($key, $value) {
        event(new SettingUpdated($key, $value));
    });
    

Configuration Quirks

  1. Default Values

    • Settings without database entries fall back to config/settings-main.php. Override globally:
      'defaults' => [
          'app.feature_flags.new_ui' => true,
      ],
      
  2. Key Naming

    • Use dot notation (e.g., app.feature_flags.new_ui) for nested settings.
    • Avoid reserved keys like settings.* or laravel.*.
  3. Environment Overrides

    • Override settings per environment in .env:
      SETTINGS_APP_FEATURE_FLAGS_NEW_UI=true
      
    • The package may auto-load these (check docs).
  4. Localization

    • If using Russian or non-ASCII keys, ensure your database uses UTF-8mb4 collation.

Pro Tips

  1. **Bulk
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.
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi