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 Extensions Bundle Laravel Package

axstrad/doctrine-extensions-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require axstrad/doctrine-extensions-bundle
    

    Ensure your composer.json meets the package's PHP/Doctrine/Symfony version constraints (e.g., PHP ≥5.4, Doctrine ORM ~2.3, Symfony ≥2.3 <2.7).

  2. Enable the Bundle: Add to config/bundles.php:

    return [
        // ...
        Axstrad\DoctrineExtensionsBundle\AxstradDoctrineExtensionsBundle::class => ['all' => true],
    ];
    
  3. First Use Case: Use the Sluggable behavior to auto-generate SEO-friendly URLs for entities. Example:

    use Axstrad\DoctrineExtensions\Sluggable\Sluggable;
    use Doctrine\ORM\Mapping as ORM;
    
    /**
     * @ORM\Entity
     * @ORM\HasLifecycleCallbacks
     * @Sluggable(fields={"title"}, unique=true)
     */
    class Article
    {
        // ...
    }
    
    • Trigger slug generation via lifecycle callbacks or manually:
      $article = new Article();
      $article->setTitle("My Awesome Article");
      $em->persist($article);
      $em->flush(); // Slug auto-generated
      

Implementation Patterns

Common Workflows

  1. Sluggable Behavior:

    • Dynamic Slugs: Use fields to specify which fields generate the slug (e.g., fields={"title", "subtitle"}).
    • Custom Separator: Override the default - with separator="_" in the @Sluggable annotation.
    • Manual Updates: Call $entity->updateSlug() to regenerate slugs post-update.
  2. Timestampable Behavior:

    • Auto-track createdAt/updatedAt without manual updates:
      use Axstrad\DoctrineExtensions\Timestampable\Timestampable;
      
      /**
       * @Timestampable
       */
      class Product {}
      
    • Custom Fields: Use createdAt="customCreated" updatedAt="customUpdated" to map to custom properties.
  3. Soft-Deletable Behavior:

    • Enable soft deletes with a deletedAt field:
      use Axstrad\DoctrineExtensions\SoftDeletable\SoftDeletable;
      
      /**
       * @SoftDeletable(deletedAt="deletedAt")
       */
      class User {}
      
    • Query Filter: Automatically excludes soft-deleted records unless explicitly queried:
      $em->getRepository(User::class)->findAll(); // Excludes deleted
      $em->getRepository(User::class)->findAll(['withDeleted' => true]); // Includes deleted
      
  4. Integration with Forms:

    • Use Symfony\Component\Form\Extension\Core\Type\TextType for slug fields with validation:
      $builder->add('slug', TextType::class, [
          'required' => false,
          'error_bubbling' => true,
      ]);
      

Advanced Patterns

  • Custom Slug Logic: Extend Axstrad\DoctrineExtensions\Sluggable\SluggableListener to modify slug generation (e.g., add prefixes/suffixes).
  • Event Subscribers: Listen to prePersist/preUpdate to conditionally trigger behaviors (e.g., skip slug generation for drafts):
    $entity->getSlug() === null && $entity->updateSlug();
    

Gotchas and Tips

Pitfalls

  1. Version Conflicts:

    • The package targets Symfony 2.3–2.6 and Doctrine ORM 2.3. Ensure your doctrine/orm version aligns (e.g., ~2.3).
    • Fix: Pin versions in composer.json if using newer Symfony/Doctrine:
      "doctrine/orm": "2.3.*",
      "symfony/symfony": "2.6.*"
      
  2. Slug Uniqueness:

    • The unique=true option in @Sluggable may fail if the slug generator doesn’t handle collisions (e.g., appending -1, -2).
    • Workaround: Implement a custom slug generator or use a database trigger.
  3. Soft Deletes + Queries:

    • Forgetting withDeleted in queries returns no results for soft-deleted entities.
    • Tip: Use a repository method to toggle visibility:
      public function findAllWithDeleted($withDeleted = false) {
          return $this->createQueryBuilder('u')
              ->andWhere($withDeleted ? '' : 'u.deletedAt IS NULL')
              ->getQuery()
              ->getResult();
      }
      
  4. Lifecycle Callback Order:

    • Sluggable/Timestampable behaviors rely on Doctrine lifecycle callbacks. Manual flush() calls may bypass them.
    • Fix: Use prePersist/preUpdate events or ensure flush() is called after setting properties.

Debugging Tips

  • Enable SQL Logging:

    $em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger());
    

    Verify soft-deletes or slug updates appear in queries.

  • Check Listener Registration: Ensure the bundle’s listeners (e.g., SluggableListener) are registered. Debug with:

    $container->has('axstrad.doctrine_extensions.sluggable.listener');
    

Extension Points

  1. Custom Behaviors:

    • Extend Axstrad\DoctrineExtensions\AbstractBehavior to create reusable logic (e.g., Hashable for password hashing).
  2. Override Defaults:

    • Modify the bundle’s configuration in config/packages/axstrad_doctrine_extensions.yaml:
      axstrad_doctrine_extensions:
          sluggable:
              separator: '_'
              fields: ['title', 'subtitle'] # Global defaults
      
  3. Event Dispatching:

    • Listen to axstrad.doctrine_extensions.slug.generate to intercept slug generation:
      $dispatcher->addListener(
          'axstrad.doctrine_extensions.slug.generate',
          function ($event) {
              $event->setSlug(strtoupper($event->getSlug()));
          }
      );
      

Performance Notes

  • Batch Slug Updates: Avoid regenerating slugs for all entities on every save. Use a cron job or command:
    php bin/console doctrine:query-sql "UPDATE article SET slug = sluggable_generate('title') WHERE slug IS NULL"
    
  • Index Soft-Delete Fields: Add a database index to deletedAt for faster queries:
    ALTER TABLE user ADD INDEX idx_deleted_at (deletedAt);
    
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.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky