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

Setting Bundle Laravel Package

digipolisgent/setting-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation

    composer require digipolisgent/setting-bundle
    

    Enable the bundle in config/bundles.php:

    return [
        // ...
        DigipolisGent\SettingBundle\DigipolisGentSettingBundle::class => ['all' => true],
    ];
    
  2. Define an Entity Type Extend your entity with SettingImplementationTrait and implement getSettingImplementationName():

    use DigipolisGent\SettingBundle\Model\SettingImplementationTrait;
    
    class Product
    {
        use SettingImplementationTrait;
    
        public function getSettingImplementationName(): string
        {
            return 'product'; // Unique identifier for this entity type
        }
    }
    
  3. Create a Data Provider Define settings dynamically via a service tagged as setting.data_provider:

    # config/services.yaml
    services:
        App\Setting\ProductSettingsProvider:
            tags:
                - { name: 'setting.data_provider', entity: 'product' }
    

    Implement SettingDataProviderInterface:

    class ProductSettingsProvider implements SettingDataProviderInterface
    {
        public function getSettings(): array
        {
            return [
                'discount_rate' => [
                    'type' => 'integer',
                    'label' => 'Discount Rate (%)',
                    'required' => true,
                    'validation' => ['min' => 0, 'max' => 100],
                ],
                'is_featured' => [
                    'type' => 'boolean',
                    'label' => 'Featured Product',
                ],
            ];
        }
    }
    
  4. Access Settings in Forms Use the SettingType form field in your entity forms:

    $builder->add('settings', SettingType::class, [
        'entity' => new Product(), // or class name as string
    ]);
    

First Use Case: Dynamic Product Attributes

Add dynamic settings to a Product entity (e.g., discount rates, featured status) without modifying the database schema. Retrieve these settings anywhere in the app via the SettingManager service:

$product = $entityManager->getRepository(Product::class)->find(1);
$settings = $this->settingManager->getSettings($product);
// Returns: ['discount_rate' => 15, 'is_featured' => true]

Implementation Patterns

Workflows

1. Defining and Managing Settings

  • Centralized Configuration: Use data providers to define settings in one place (e.g., ProductSettingsProvider for all product-related settings).
  • Reusable Providers: Share providers across bundles by tagging them with the correct entity value.
  • Environment-Specific Settings: Override providers per environment (e.g., dev_product_settings_provider).

2. Form Integration

  • Automatic Form Generation: The SettingType field dynamically builds forms based on your data provider’s definitions.
  • Nested Settings: Support hierarchical settings (e.g., shipping.rules) by using dot notation in the provider:
    return [
        'shipping.rules' => [
            'type' => 'array',
            'label' => 'Shipping Rules',
            'entry_type' => 'text', // or custom form type
        ],
    ];
    
  • Validation: Leverage Symfony’s validation constraints via the validation key in the provider.

3. Retrieving Settings

  • Service-Based Access: Use SettingManager to fetch settings for any entity:
    $settings = $this->settingManager->getSetting($entity, 'discount_rate');
    
  • Default Values: Provide defaults in the provider or via SettingManager:
    $this->settingManager->getSetting($entity, 'is_featured', false);
    
  • Caching: Cache settings in the provider or use Symfony’s cache system for performance.

4. Extending Functionality

  • Custom Field Types: Create custom form types for complex settings (e.g., ColorPickerType) and reference them in the provider:
    'primary_color' => [
        'type' => 'custom_color_picker',
        'label' => 'Primary Color',
    ],
    
    Register the type as a service with the tag setting.form.type.

Integration Tips

Doctrine Integration

  • No Schema Changes: Settings are stored as JSON in a settings column (add this to your entity if missing):
    /**
     * @ORM\Column(type="json")
     */
    private $settings = [];
    
  • Migrations: Use Doctrine migrations to add the settings column if retrofitting to existing entities.

Twig Integration

  • Display Settings: Access settings in Twig templates via the setting filter:
    {% set discount = product|setting('discount_rate') %}
    Price: {{ product.price * (1 - discount/100)|round(2) }}€
    
  • Conditional Logic: Use settings for dynamic UI:
    {% if product|setting('is_featured') %}
        <div class="featured-badge">Featured</div>
    {% endif %}
    

API/REST Integration

  • Normalize Settings: Use Symfony’s Serializer to normalize settings in API responses:
    $serializer->normalize($product->getSettings());
    
  • PATCH Endpoints: Update settings via PATCH requests by targeting the settings field in your API resource.

Gotchas and Tips

Pitfalls

  1. Data Provider Registration

    • Issue: Forgetting to tag the provider with setting.data_provider or using the wrong entity value.
    • Fix: Verify tags in services.yaml and ensure getSettingImplementationName() matches the entity tag.
    • Debug: Check the digipolis_gent_setting.data_providers service container dump to confirm registration.
  2. Circular References in Settings

    • Issue: Using entities as setting values (e.g., related_products) can cause serialization errors.
    • Fix: Use IDs or DTOs instead of full entities. Normalize settings before storage:
      $settings['related_products'] = array_map(fn($p) => $p->getId(), $relatedProducts);
      
  3. Validation Overrides

    • Issue: Validation constraints in the provider may conflict with entity-level constraints.
    • Fix: Use validation keys sparingly or disable entity validation for the settings field:
      /**
       * @Assert\Valid
       * @ORM\Column(type="json")
       */
      private $settings;
      
      Then handle validation purely in the provider.
  4. Performance with Large Settings

    • Issue: Deeply nested or large arrays can bloat the database.
    • Fix: Denormalize frequently accessed settings into separate columns or use a dedicated Setting entity.
  5. Case Sensitivity

    • Issue: Setting keys are case-sensitive (e.g., Discount_Ratediscount_rate).
    • Fix: Standardize keys in the provider (e.g., snake_case) and document conventions.

Debugging

  1. Check Registered Providers Dump all registered providers to verify configuration:

    $providers = $container->getParameter('digipolis_gent_setting.data_providers');
    dump($providers);
    
  2. Inspect Stored Settings Query the database directly to verify settings are stored correctly:

    SELECT settings FROM product WHERE id = 1;
    
  3. Form Debugging Enable form debugging in config/packages/dev/debug.yaml:

    framework:
        form: { enabled: true }
    

    Then inspect the rendered form HTML for errors.

  4. Event Listeners Listen to SettingManagerEvents to debug setting retrieval:

    $eventDispatcher->addListener(SettingManagerEvents::SETTING_PRE_LOAD, function (SettingEvent $event) {
        error_log('Loading setting: ' . $event->getName());
    });
    

Tips

  1. Use Events for Side Effects Trigger actions when settings change by listening to SettingManagerEvents:

    $eventDispatcher->addListener(SettingManagerEvents::SETTING_POST_SAVE, function (SettingEvent $event) {
        if ($event->getName() === 'is_featured' && $event->getValue()) {
            $this->analyticsService->track('product_featured', $event->getEntity());
        }
    });
    
  2. Localization Localize setting labels dynamically:

    return [
        'discount_rate' => [
            'type' => 'integer',
            'label' => 'app.settings.discount_rate', // Translatable key
            'label_parameters' => ['%entity%' => $entity->getName()],
        ],
    ];
    

    Use Symfony’s translation system to manage labels.

  3. Soft Deletes Handle soft-deleted entities by overriding the provider’s supports() method or filtering in getSettings().

  4. Testing Mock the SettingManager in

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.
craftcms/url-validator
directorytree/privacy-filter-classifier
directorytree/privacy-filter
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
splash/scopes
splash/toolkit
testo/output-teamcity
testo/bridge-symfony