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 Behaviors Laravel Package

effiana/doctrine-behaviors

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require knplabs/doctrine-behaviors
    

    Ensure your Laravel project uses Doctrine ORM (e.g., via doctrine/dbal and doctrine/orm).

  2. First Use Case: Add a behavior to an entity. For example, to make an entity Timestampable:

    // src/Entity/Post.php
    namespace App\Entity;
    
    use Doctrine\ORM\Mapping as ORM;
    use Knp\DoctrineBehaviors\ORM\Timestampable\TimestampableTrait;
    
    #[ORM\Entity]
    class Post
    {
        use TimestampableTrait;
    
        // Your fields and methods...
    }
    

    Run migrations to add createdAt and updatedAt columns.

  3. Verify: Check if timestamps auto-populate when saving:

    $post = new Post();
    $entityManager->persist($post);
    $entityManager->flush();
    // createdAt and updatedAt should now have values.
    

Implementation Patterns

Common Workflows

  1. Entity Behaviors:

    • Blameable: Track who created/updated an entity.

      use Knp\DoctrineBehaviors\ORM\Blameable\BlameableTrait;
      use Knp\DoctrineBehaviors\ORM\Blameable\BlameableInterface;
      
      class Post implements BlameableInterface
      {
          use BlameableTrait;
      }
      

      Configure the user resolver in config/packages/knp_doctrine_behaviors.yaml:

      knp_doctrine_behaviors:
          blameable:
              user_provider: 'security.user.provider'
      
    • SoftDeletable: Add deletedAt and soft-delete logic.

      use Knp\DoctrineBehaviors\ORM\SoftDeletable\SoftDeletableTrait;
      use Knp\DoctrineBehaviors\ORM\SoftDeletable\SoftDeletableInterface;
      
      class Post implements SoftDeletableInterface
      {
          use SoftDeletableTrait;
      }
      

      Use SoftDeletableListener in your Doctrine config.

  2. Repository Behaviors:

    • Tree: Enable hierarchical data (e.g., categories).
      // src/Repository/CategoryRepository.php
      use Knp\DoctrineBehaviors\ORM\Tree\TreeTrait;
      use Knp\DoctrineBehaviors\ORM\Tree\TreeRepository;
      
      class CategoryRepository extends TreeRepository
      {
          use TreeTrait;
      }
      
      Add left and right columns to your table and configure the tree in orm.xml or annotations.
  3. Translatable:

    • Use for multilingual fields.
      use Knp\DoctrineBehaviors\ORM\Translatable\TranslatableTrait;
      use Knp\DoctrineBehaviors\ORM\Translatable\TranslatableInterface;
      
      class Product implements TranslatableInterface
      {
          use TranslatableTrait;
      
          #[ORM\Column(length: 255)]
          private ?string $name = null;
      
          #[ORM\Column(type: 'json')]
          private array $translations = [];
      }
      
      Configure locales in config/packages/knp_doctrine_behaviors.yaml:
      knp_doctrine_behaviors:
          translatable:
              locales: ['en', 'fr']
      
  4. Sluggable:

    • Auto-generate slugs from fields (e.g., titles).
      use Knp\DoctrineBehaviors\ORM\Slugable\SlugableTrait;
      use Knp\DoctrineBehaviors\ORM\Slugable\SlugableInterface;
      
      class BlogPost implements SlugableInterface
      {
          use SlugableTrait;
      
          #[ORM\Column(length: 255, unique: true)]
          private ?string $slug = null;
      }
      
      Configure slug fields in orm.xml or annotations:
      <field name="slug" type="string" length="255">
          <slug generator="slugify" fields="title" />
      </field>
      

Integration Tips

  • Doctrine Events: Listen for lifecycle events (e.g., prePersist) to customize behavior logic.
    $entityManager->getEventManager()->addEventListener(
        \Doctrine\ORM\Events::prePersist,
        function (LifecycleEventArgs $args) {
            $entity = $args->getObject();
            if ($entity instanceof BlameableInterface) {
                $entity->setCreatedBy($this->getCurrentUser());
            }
        }
    );
    
  • Custom Field Mappings: Extend behaviors by overriding methods (e.g., getSlugFields() in SlugableTrait).
  • QueryBuilder: Use repository methods like findBySlug() (for Slugable) or getTree() (for Tree).

Gotchas and Tips

Pitfalls

  1. Missing Columns:

    • Forgetting to add required columns (e.g., createdAt, updatedAt, deletedAt) will cause runtime errors. Run migrations after adding behaviors.
    • For Tree, ensure left and right columns exist and are indexed.
  2. Locale Configuration:

    • Translatable requires locales to be defined in the config. Missing locales will throw exceptions when saving translations.
  3. User Provider:

    • Blameable needs a user provider (e.g., Symfony’s security user provider). Configure it in knp_doctrine_behaviors.yaml; otherwise, createdBy/updatedBy will be null.
  4. Slug Conflicts:

    • Slugable assumes uniqueness by default. Handle duplicates gracefully (e.g., append a suffix like -2):
      knp_doctrine_behaviors:
          sluggable:
              unique_suffix: true
      
  5. SoftDelete Queries:

    • SoftDeletable modifies queries to exclude deleted records by default. Use findDeleted() or createQueryBuilder()->where(...) to query deleted items explicitly.
  6. UUID Collisions:

    • Uuidable generates UUIDs. Ensure your database supports UUID types (e.g., uuid in PostgreSQL or char(36) in MySQL).

Debugging

  • Enable SQL Logging:

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

    Helps verify if behaviors (e.g., SoftDeletable) are filtering queries correctly.

  • Check Event Listeners: Use debug:event-dispatcher (Symfony) or inspect Doctrine events to ensure behaviors are triggered:

    php bin/console debug:event-dispatcher
    
  • PHPStan: Install the PHPStan extension for type hints:

    composer require --dev knplabs/doctrine-behaviors-phpstan
    

    Configure in phpstan.neon:

    includes:
        - vendor/knplabs/doctrine-behaviors-phpstan/extension.neon
    

Extension Points

  1. Custom Traits: Extend existing traits to add domain-specific logic. For example:

    trait CustomTimestampableTrait extends TimestampableTrait
    {
        public function setCreatedAt(\DateTimeInterface $date): self
        {
            $this->createdAt = $date->setTime(0, 0); // Normalize to midnight
            return $this;
        }
    }
    
  2. Event Subscribers: Subscribe to Doctrine events to intercept behavior logic:

    use Doctrine\Common\EventSubscriber;
    use Doctrine\ORM\Event\LifecycleEventArgs;
    
    class CustomBlameableSubscriber implements EventSubscriber
    {
        public function getSubscribedEvents(): array
        {
            return ['prePersist', 'preUpdate'];
        }
    
        public function prePersist(LifecycleEventArgs $args): void
        {
            $entity = $args->getObject();
            if ($entity instanceof BlameableInterface) {
                $entity->setCreatedBy($this->getAdminUser());
            }
        }
    }
    
  3. Repository Methods: Override repository methods to add custom queries. For example, for Tree:

    public function findByParent(Category $parent): array
    {
        return $this->createQueryBuilder('c')
            ->where('c.lft BETWEEN :left AND :right')
            ->setParameter('left', $parent->getLeftValue())
            ->setParameter('right', $parent->getRightValue())
            ->getQuery()
            ->getResult();
    }
    
  4. Configuration Overrides: Override default behavior configurations in config/packages/knp_doctrine_behaviors.yaml:

    knp_doctrine_behaviors:
        timestampable:
            fields:
                created_at: createdAt
                updated_at: updated
    
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.
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver