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

chaplean/doctrine-extensions-bundle

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Setup for Laravel (Adapted)
Since this bundle is Symfony-focused, Laravel developers must manually integrate its dependencies (`gedmo/doctrine-extensions`). Start here:

1. **Install Dependencies**
   ```bash
   composer require gedmo/doctrine-extensions
  1. Configure Doctrine ORM Add mappings to config/packages/doctrine.yaml (or config/doctrine.php in Laravel 8+):

    doctrine:
        orm:
            mappings:
                GedmoTranslatable:
                    type: annotation
                    prefix: Gedmo\Translatable\Entity
                    dir: "%kernel.project_dir%/vendor/gedmo/doctrine-extensions/lib/Gedmo/Translatable/Entity"
                GedmoLoggable:
                    type: annotation
                    prefix: Gedmo\Loggable\Entity
                    dir: "%kernel.project_dir%/vendor/gedmo/doctrine-extensions/lib/Gedmo/Loggable/Entity"
                GedmoTree:
                    type: annotation
                    prefix: Gedmo\Tree\Entity
                    dir: "%kernel.project_dir%/vendor/gedmo/doctrine-extensions/lib/Gedmo/Tree/Entity"
    
  2. First Use Case: Translatable Entities Annotate a model (e.g., Post) with @Gedmo\Translatable and define translatable fields:

    use Gedmo\Mapping\Annotation as Gedmo;
    
    class Post
    {
        /**
         * @Gedmo\Translatable
         */
        private $title;
    
        /**
         * @Gedmo\Locale
         */
        private $locale;
    }
    

    Use Translation listener in bootstrap/app.php:

    $app->make('doctrine')->getManager()->getEventManager()->addEventSubscriber(
        new \Gedmo\Translatable\TranslatableListener()
    );
    

Implementation Patterns

1. Entity Design Patterns

  • Translatable Entities:

    • Use @Gedmo\Translatable on fields needing translations (e.g., title, description).
    • Store translations in a separate table (default: translation).
    • Access translations via getTranslations() or getTranslation('en').
    • Workflow:
      $post = new Post();
      $post->setTitle('Titre'); // French
      $post->setLocale('fr');
      $entityManager->persist($post);
      $entityManager->flush();
      
      // Later, fetch English translation
      $englishTitle = $post->getTranslation('en')->getTitle(); // Returns NULL if missing
      
  • Loggable Entities:

    • Track changes to entities with @Gedmo\Loggable.
    • Logs are stored in log_entry table by default.
    • Workflow:
      $user = new User();
      $user->setEmail('old@example.com');
      $entityManager->persist($user);
      $entityManager->flush();
      
      $user->setEmail('new@example.com');
      $entityManager->flush();
      
      // Fetch logs
      $logs = $entityManager->getRepository(LogEntry::class)
          ->findBy(['objectClass' => User::class]);
      
  • Tree Entities:

    • Model hierarchical data (e.g., categories, menus) with @Gedmo\TreeType.
    • Methods like getChildren(), getParent(), and getRoot() simplify traversal.
    • Workflow:
      $category = new Category();
      $category->setName('Electronics');
      $entityManager->persist($category);
      
      $laptopCategory = new Category();
      $laptopCategory->setParent($category);
      $laptopCategory->setName('Laptops');
      $entityManager->persist($laptopCategory);
      
      // Fetch children
      $children = $category->getChildren(); // Returns Collection of Category
      

2. Querying Extensions

  • Translatable Queries: Use Gedmo\Translatable\Query\TreeWalker\TranslationWalker to filter by locale:

    $qb = $entityManager->createQueryBuilder();
    $qb->select('p')
       ->from(Post::class, 'p')
       ->where('p.translations LIKE :locale')
       ->setParameter('locale', '%en%');
    
  • Tree Queries: Query subtrees or siblings:

    // Get all descendants of a node
    $descendants = $entityManager->getRepository(Category::class)
        ->createQueryBuilder('c')
        ->where('c.lft BETWEEN :lft AND :rgt')
        ->setParameter('lft', $category->getLft())
        ->setParameter('rgt', $category->getRgt())
        ->getQuery()
        ->getResult();
    

3. Integration with Laravel

  • Service Providers: Register listeners in AppServiceProvider:

    public function boot()
    {
        $this->app->make('doctrine')->getManager()->getEventManager()->addEventSubscriber(
            new \Gedmo\Translatable\TranslatableListener()
        );
        $this->app->make('doctrine')->getManager()->getEventManager()->addEventSubscriber(
            new \Gedmo\Loggable\LoggableListener()
        );
        $this->app->make('doctrine')->getManager()->getEventManager()->addEventSubscriber(
            new \Gedmo\Tree\TreeListener()
        );
    }
    
  • Eloquent Compatibility: Use doctrine/orm alongside illuminate/database by configuring Laravel’s EntityManager in config/database.php:

    'doctrine' => [
        'entity_manager' => 'default',
    ],
    

Gotchas and Tips

1. Common Pitfalls

  • Locale Handling:

    • Always set the locale field when saving translatable entities. Missing locales will cause NULL translations.
    • Fix: Add a prePersist lifecycle callback:
      use Gedmo\Mapping\Annotation as Gedmo;
      
      class Post
      {
          /**
           * @Gedmo\Locale
           */
          private $locale;
      
          public function prePersist()
          {
              if (empty($this->locale)) {
                  $this->locale = app()->getLocale(); // Fallback to app locale
              }
          }
      }
      
  • Tree Entities:

    • Detached Entities: Modifying a tree entity (e.g., changing parent) outside Doctrine’s context will break the tree structure. Always use persist()/merge().
    • Performance: Deep trees (>1000 nodes) may cause performance issues. Use MaterializedPath or NestedSet strategies wisely.
    • Circular References: Avoid bidirectional relationships (e.g., parentchildren) that could cause infinite loops in serialization.
  • Loggable Entities:

    • Log Entry Table: Ensure the log_entry table exists and matches the schema (run doctrine:schema:update if needed).
    • Bulk Operations: Logging every field change in bulk operations (e.g., imports) can bloat the database. Disable logging temporarily:
      $entityManager->getEventManager()->removeEventSubscriber(
          $entityManager->getEventManager()->getEventSubscriber('gedmo_loggable')
      );
      

2. Debugging Tips

  • Translatable Debugging:

    • Check if translations are saved by querying the translation table directly:
      SELECT * FROM translation WHERE object_class = 'App\Entity\Post';
      
    • Verify the locale field is set correctly.
  • Tree Debugging:

    • Inspect lft/rgt or path values in the database to debug hierarchy issues.
    • Use Gedmo\Tree\TreeType::MATERIALIZED_PATH for easier debugging of paths.
  • Loggable Debugging:

    • Enable SQL logging to verify INSERT/UPDATE queries for log_entry:
      $entityManager->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger());
      

3. Configuration Quirks

  • Mapping Directories:

    • Hardcoded paths in the bundle’s config.yml may break if vendor paths change. Use %kernel.project_dir% (Symfony) or Laravel’s base_path():
      dir: "%kernel.project_dir%/vendor/gedmo/doctrine-extensions/lib/Gedmo/Translatable/Entity"
      
      Laravel equivalent:
      dir: base_path('vendor/gedmo/doctrine-extensions/lib/Gedmo/Translatable/Entity')
      
  • Event Subscribers:

    • Ensure subscribers are registered after the entity manager is initialized. In Laravel, use booted() in AppServiceProvider:
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