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

Sonata Attribute Bundle Laravel Package

dgarden/sonata-attribute-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation Run composer require dgarden/sonata-admin-attribute-bundle and ensure the bundle is enabled in config/bundles.php:

    DigitalGarden\SonataAttributeBundle\DigitalGardenSonataAttributeBundle::class => ['all' => true],
    
  2. First Use Case Add the [Admin] attribute to an entity class (e.g., Bank). Start with a basic configuration:

    use DigitalGarden\SonataAttributeBundle\Attribute\Admin;
    
    #[Admin(fields: ['name' => new AdminAttribute('name')])]
    class Bank {}
    

    Clear the cache (php bin/console cache:clear) and visit /admin to see the generated admin interface.

  3. Where to Look First

    • Entity Classes: Focus on decorating your existing entities with [Admin] attributes.
    • Sonata Admin Documentation: Familiarize yourself with Sonata’s ListMapper and CRUD concepts, as the bundle mirrors these patterns.
    • Bundle Configuration: Check config/packages/digital_garden_sonata_attribute.yaml for global overrides (if any).

Implementation Patterns

Core Workflows

  1. Attribute-Based Admin Generation Replace or supplement Sonata’s YAML/XML configuration with PHP attributes. Example:

    #[Admin(
        fields: [
            'name' => new AdminAttribute('name', ['label' => 'Bank Name']),
            'createdAt' => new AdminAttribute('createdAt', ['type' => 'datetime']),
        ],
        list: [
            new AdminAttribute(ListMapper::NAME_ID, ['type' => ListMapper::TYPE_ID]),
            'name' => new AdminAttribute('name'),
        ],
        form: [
            'name' => new AdminAttribute('name', ['required' => true]),
        ]
    )]
    class Bank {}
    
    • Fields: Define properties for all CRUD views (show, edit, etc.).
    • List: Customize the list view (e.g., batch actions, filters).
    • Form: Override form field types/options.
  2. Integration with Existing Sonata Admins Extend existing Sonata admin classes by combining attributes with traditional configuration:

    #[Admin(
        list: [
            new AdminAttribute(ListMapper::NAME_ACTIONS, [
                'type' => ListMapper::TYPE_ACTIONS,
                'actions' => ['delete' => ['template' => '@App/Admin/delete.html.twig']],
            ]),
        ]
    )]
    class Bank extends AbstractAdmin {}
    
  3. Dynamic Attribute Generation Use runtime logic to build attributes dynamically (e.g., for polymorphic entities):

    #[Admin(
        fields: function (Bank $entity) {
            return [
                'name' => new AdminAttribute('name'),
                'isActive' => new AdminAttribute('isActive', [
                    'editable' => $entity->isAdmin(),
                ]),
            ];
        }
    )]
    
  4. Reusing Attributes Across Entities Create a base trait or abstract class to share common admin configurations:

    trait CommonAdminConfig {
        public static function getCommonAdminAttributes(): array {
            return [
                'createdAt' => new AdminAttribute('createdAt', ['type' => 'datetime']),
            ];
        }
    }
    
    #[Admin(fields: [...CommonAdminConfig::getCommonAdminAttributes()])]
    class Bank {}
    
  5. Event Listeners for Post-Processing Hook into Sonata’s events to modify attributes dynamically:

    // src/EventListener/AdminAttributeListener.php
    public function onConfigureListFields(ListMapperEvent $event) {
        $attributes = $event->getAdmin()->getAttributes();
        if (isset($attributes['customField'])) {
            $attributes['customField']->setOption('label', 'Dynamic Label');
        }
    }
    

Gotchas and Tips

Pitfalls

  1. Cache Dependencies

    • Issue: Changes to attributes may not reflect immediately due to Symfony’s cache.
    • Fix: Clear the cache after modifying attributes:
      php bin/console cache:clear --env=prod
      
    • Tip: Use #[Cache(clear: true)] on entities to auto-clear cache on changes (if using Doctrine extensions).
  2. Attribute Overrides

    • Issue: Attributes on child classes may not override parent attributes as expected.
    • Fix: Explicitly merge configurations or use #[Admin(override: true)].
  3. Type Safety

    • Issue: Incorrect AdminAttribute types (e.g., ListMapper::TYPE_BATCH for a non-batch field) may cause runtime errors.
    • Fix: Validate types against Sonata’s supported types.
  4. Doctrine Metadata Conflicts

    • Issue: Attribute-based admins may conflict with Doctrine’s metadata if entity mappings are misconfigured.
    • Fix: Ensure #[ORM\Entity] and #[ORM\Table] are correctly defined before [Admin].
  5. Symfony 6+ Deprecations

    • Issue: The bundle may not fully support Symfony 6’s attribute changes (e.g., #[AsAdmin] vs. #[Admin]).
    • Fix: Check the bundle’s composer.json for Symfony version constraints and test thoroughly.

Debugging

  1. Dumping Attributes Use Sonata’s debug commands to inspect generated admins:

    php bin/console sonata:admin:debug
    

    Or dump attributes in a controller:

    $admin = $this->get('sonata.admin.bank');
    dump($admin->getAttributes());
    
  2. Twig Debugging Enable Sonata’s debug toolbar to inspect rendered admin templates:

    # config/packages/dev/sonata_admin.yaml
    sonata_admin:
        templates:
            layout: 'SonataAdminBundle::standard_layout.html.twig'
        debug: true
    
  3. Event Debugging Log events to trace attribute processing:

    public function onConfigureListFields(ListMapperEvent $event) {
        $this->logger->debug('Configuring list fields', ['admin' => $event->getAdmin()->getClass()]);
    }
    

Tips

  1. Gradual Migration Start by converting simple admins to attributes, then migrate complex ones incrementally. Use both YAML and attributes in parallel during transition:

    # config/packages/sonata_admin.yaml
    sonata_admin:
        options:
            attribute_bundle: true  # Enable attribute bundle
    
  2. Custom Attribute Classes Extend AdminAttribute to add domain-specific options:

    class CustomAdminAttribute extends AdminAttribute {
        public function __construct(string $property, array $options = []) {
            parent::__construct($property, $options + ['custom_option' => true]);
        }
    }
    
  3. Performance

    • Tip: For large entities, lazy-load attributes or use #[Admin(fields: [])] to exclude fields from admin generation.
    • Tip: Cache attribute configurations if they’re static:
      #[Admin(fields: static::getCachedAttributes())]
      class Bank {}
      
  4. Testing Use Symfony’s KernelTestCase to test attribute-based admins:

    public function testAdminAttributes() {
        $client = static::createClient();
        $client->request('GET', '/admin/app/bank');
        $this->assertSelectorTextContains('h1', 'Banks');
    }
    
  5. Documentation Gaps

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