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

Doctrine Resource Bundle Laravel Package

anh/doctrine-resource-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require anh/doctrine-resource-bundle
    

    Add the bundle to config/bundles.php in Symfony:

    Anh\DoctrineResourceBundle\AnhDoctrineResourceBundle::class => ['all' => true],
    
  2. First Use Case: Basic CRUD with Doctrine Extensions

    • Ensure anh/doctrine-extensions-resource is installed (dependency).
    • Configure a Doctrine entity with lifecycle callbacks (e.g., Sluggable, Timestampable).
    • Example entity (src/Entity/Article.php):
      use Gedmo\Mapping\Annotation as Gedmo;
      
      /**
       * @Gedmo\Slug(fields={"title"})
       */
      class Article { ... }
      
    • Run migrations:
      php bin/console doctrine:migrations:diff
      php bin/console doctrine:migrations:migrate
      
  3. Symfony Integration

    • Use the bundle’s services (e.g., anh.doctrine_resource.manager) to handle Doctrine extensions via Symfony’s DI container.
    • Example in a controller:
      use Anh\DoctrineResourceBundle\Manager\ResourceManager;
      
      class ArticleController {
          public function __construct(private ResourceManager $resourceManager) {}
      
          public function update(Article $article) {
              $this->resourceManager->update($article); // Triggers extensions (e.g., slug update)
          }
      }
      

Implementation Patterns

Workflows

  1. Lifecycle-Centric Development

    • Pre-Persist/Update: Use extensions like Timestampable or Blameable (via anh/doctrine-extensions-resource).
      // src/Entity/User.php
      use Gedmo\Mapping\Annotation as Gedmo;
      
      /**
       * @Gedmo\Timestampable(on="create")
       */
      class User { ... }
      
    • Post-Load: Hydrate fields dynamically (e.g., Translatable).
      $user = $entityManager->find(User::class, 1);
      $this->resourceManager->refresh($user); // Ensures translations are loaded
      
  2. Symfony Form Integration

    • Bind Doctrine extensions to forms for seamless UX.
    • Example with Sluggable:
      // src/Form/ArticleType.php
      use Symfony\Bridge\Doctrine\Form\Type\EntityType;
      use Anh\DoctrineResourceBundle\Form\Extension\ResourceTypeExtension;
      
      $builder->add('title', TextType::class);
      $builder->add('slug', TextType::class, [
          'mapped' => false, // Slug is auto-generated
      ]);
      
    • Register the ResourceTypeExtension in services.yaml:
      services:
          Anh\DoctrineResourceBundle\Form\Extension\ResourceTypeExtension:
              tags: [form.type_extension]
      
  3. Event-Driven Extensions

    • Subscribe to Doctrine events to customize behavior.
    • Example: Log changes via Auditable extension.
      // src/EventListener/AuditListener.php
      use Anh\DoctrineResourceBundle\Event\ResourceEvent;
      use Symfony\Component\EventDispatcher\EventSubscriberInterface;
      
      class AuditListener implements EventSubscriberInterface {
          public static function getSubscribedEvents() {
              return [
                  ResourceEvent::PRE_PERSIST => 'logChange',
                  ResourceEvent::PRE_UPDATE  => 'logChange',
              ];
          }
      
          public function logChange(ResourceEvent $event) {
              // Custom audit logic
          }
      }
      

Integration Tips

  • Doctrine Configuration: Ensure orm.xml or annotations are properly configured for extensions.
    <!-- config/doctrine/orm.xml -->
    <doctrine-mapping
        xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
            http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
        <driver name="annotations" path="src/Entity"/>
    </doctrine-mapping>
    
  • Symfony Cache: Clear cache after adding new entities/extensions:
    php bin/console cache:clear
    
  • Testing: Use ResourceManager in functional tests to verify extensions:
    $this->getContainer()->get('anh.doctrine_resource.manager')->update($entity);
    $this->assertEquals('expected-slug', $entity->getSlug());
    

Gotchas and Tips

Pitfalls

  1. Extension Conflicts

    • Issue: Multiple extensions (e.g., Sluggable + Translatable) may override each other.
    • Fix: Order matters. Use @Gedmo\OrderBy or custom event listeners to prioritize logic.
      // src/EventListener/SlugPriorityListener.php
      use Anh\DoctrineResourceBundle\Event\ResourceEvent;
      
      class SlugPriorityListener {
          public function onPrePersist(ResourceEvent $event) {
              if ($event->getEntity() instanceof Article) {
                  $this->resourceManager->generateSlug($event->getEntity());
              }
          }
      }
      
  2. Missing Dependencies

    • Issue: Forgetting to install anh/doctrine-extensions-resource (required by the bundle).
    • Fix: Verify composer.json includes:
      "require": {
          "anh/doctrine-extensions-resource": "^0.4"
      }
      
  3. Cache Invalidation

    • Issue: Changes to entity mappings aren’t reflected due to cached metadata.
    • Fix: Clear metadata cache:
      php bin/console doctrine:cache:clear-metadata
      
  4. Form Mapping Quirks

    • Issue: mapped => false fields (e.g., auto-generated slugs) may still appear in forms.
    • Fix: Exclude them explicitly in ArticleType:
      $builder->remove('slug'); // If auto-generated
      

Debugging

  • Enable SQL Logging: Check if extensions are firing queries.
    # config/packages/dev/doctrine.yaml
    doctrine:
        dbal:
            logging: true
            profiling: true
    
  • Event Dispatcher: Verify events are subscribed:
    php bin/console debug:event-dispatcher
    
  • Entity Metadata: Dump loaded metadata to debug extensions:
    $metadata = $entityManager->getClassMetadata(Article::class);
    dump($metadata->getLifecycleCallbacks());
    

Extension Points

  1. Custom Events

    • Extend ResourceEvent for domain-specific logic:
      class CustomResourceEvent extends ResourceEvent {
          public function setCustomData($data) { ... }
      }
      
    • Dispatch in a listener:
      $dispatcher->dispatch(new CustomResourceEvent($entity, $eventName));
      
  2. Dynamic Configuration

    • Override bundle defaults via config/packages/anh_doctrine_resource.yaml:
      anh_doctrine_resource:
          extensions:
              slug:
                  fields: ['title', 'subtitle'] # Custom slug fields
      
  3. Performance Optimization

    • Batch operations for bulk updates:
      $this->resourceManager->bulkUpdate([$entity1, $entity2]);
      
    • Lazy-load translations:
      $this->resourceManager->setLazyLoading(true);
      
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