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

ali/doctrine-extensions-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the Bundle

    composer require ali/doctrine-extensions-bundle
    

    Ensure your composer.json aligns with the package's PHP (^7.1.3) and Symfony (^4.3 || ^5.0) requirements.

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

    return [
        // ...
        Ali\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle::class => ['all' => true],
    ];
    
  3. Configure Doctrine Add to config/packages/doctrine.yaml:

    doctrine:
        orm:
            mappings:
                gedmo_loggable:
                    type: attribute
                    prefix: Gedmo\Loggable\Entity
                    dir: "%kernel.project_dir%/vendor/gedmo/doctrine-extensions/src/Loggable/Entity"
                    alias: GedmoLoggable
                # Add other extensions (e.g., translatable, sluggable) similarly
    
  4. First Use Case: Loggable Entity Annotate an entity to track changes:

    use Gedmo\Mapping\Annotation as Gedmo;
    
    #[ORM\Entity]
    class Product
    {
        #[Gedmo\Loggable]
        private $name;
    }
    

    Run migrations (php bin/console doctrine:migrations:diff + php bin/console doctrine:migrations:migrate).


Implementation Patterns

Common Workflows

1. Sluggable Entities

  • Use for SEO-friendly URLs (e.g., /products/awesome-widget).
  • Example:
    #[Gedmo\Slug(fields={"name"}, unique=true)]
    private $slug;
    
  • Generate slugs via:
    $product->setName('Awesome Widget');
    $slugger = $this->get('gedmo_slugger.slugger.product');
    $product->setSlug($slugger->slugify($product));
    

2. Translatable Fields

  • Store multilingual content.
  • Example:
    #[Gedmo\TranslationEntity(class: ProductTranslation::class)]
    class Product {}
    
  • Load translations:
    $product = $entityManager->getRepository(Product::class)->findOneBy(['id' => 1]);
    $translations = $product->getTranslations(); // Array of ProductTranslation
    

3. Uploadable Files

  • Handle file uploads with metadata (e.g., size, MIME type).
  • Example:
    use Stof\DoctrineExtensionsBundle\Uploadable\Uploadable;
    
    #[ORM\Entity]
    class Document implements Uploadable
    {
        #[ORM\Column(type: 'string', length: 255)]
        private $file;
    
        #[ORM\Column(type: 'string', length: 255, nullable: true)]
        private $fileName;
    
        #[ORM\Column(type: 'string', length: 255, nullable: true)]
        private $mimeType;
    
        #[ORM\Column(type: 'integer', nullable: true)]
        private $size;
    
        // Implement Uploadable methods (getters/setters for file, fileName, etc.)
    }
    
  • Upload logic:
    $document = new Document();
    $document->setFile($uploadedFile); // Symfony\Component\HttpFoundation\File\UploadedFile
    $uploadableManager = $this->get('stof_doctrine_extensions.uploadable.manager');
    $uploadableManager->upload($document);
    

4. Soft-Deletable Entities

  • Simulate record deletion without data loss.
  • Example:
    #[Gedmo\SoftDeleteable(fieldName: 'deletedAt')]
    class Product {}
    
  • "Delete" a record:
    $product->setDeletedAt(new \DateTime());
    $entityManager->flush();
    
  • Query soft-deleted records:
    $qb = $entityManager->createQueryBuilder();
    $qb->from(Product::class, 'p')
      ->where('p.deletedAt IS NULL');
    

5. Tree Structures (NestedSet)

  • Model hierarchical data (e.g., categories).
  • Example:
    #[Gedmo\Tree(type: 'nested')]
    class Category {}
    
  • Manipulate tree:
    $parent = $entityManager->getRepository(Category::class)->find(1);
    $child = new Category();
    $child->setParent($parent);
    $entityManager->persist($child);
    $entityManager->flush();
    

Integration Tips

  1. Event Listeners Use Doctrine lifecycle events to trigger extensions automatically:

    #[ORM\PrePersist]
    #[ORM\PreUpdate]
    public function updateTimestamps()
    {
        if (!$this->createdAt) {
            $this->createdAt = new \DateTime();
        }
        $this->updatedAt = new \DateTime();
    }
    
  2. Custom Slug Generation Override slug logic in a service:

    # config/services.yaml
    services:
        App\Service\CustomSlugger:
            arguments:
                $baseSlugger: '@gedmo_slugger.slugger.product'
    
    // src/Service/CustomSlugger.php
    class CustomSlugger
    {
        public function __construct(private Slugger $baseSlugger) {}
    
        public function slugify(Product $product): string
        {
            $slug = $this->baseSlugger->slugify($product);
            return strtolower($slug); // Custom logic
        }
    }
    
  3. Querying Extensions Filter soft-deleted records:

    $qb = $entityManager->createQueryBuilder();
    $qb->from(Product::class, 'p')
      ->where('p.deletedAt IS NULL');
    

    Or use DQL:

    $query = $entityManager->createQuery(
        'SELECT p FROM App\Entity\Product p WHERE p.deletedAt IS NULL'
    );
    
  4. Combining Extensions Example: Loggable + SoftDeletable:

    #[Gedmo\Loggable]
    #[Gedmo\SoftDeleteable(fieldName: 'deletedAt')]
    class Product {}
    

    Ensure deletedAt is not logged (add to loggable.ignored_fields in config).


Gotchas and Tips

Pitfalls

  1. Migration Order

    • Run migrations after enabling the bundle to avoid errors.
    • Extensions like Loggable require additional tables (e.g., AUDIT_ENTRY).
  2. Circular Dependencies

    • Avoid bidirectional relationships with Uploadable entities. Use lazy loading or custom upload logic.
  3. Slug Uniqueness Conflicts

    • Ensure unique: true in @Gedmo\Slug has a unique index in the database.
    • Debug conflicts with:
      php bin/console doctrine:schema:validate
      
  4. Translatable Performance

    • Use Gedmo\Translatable\TranslatableListener sparingly on large datasets. Consider denormalizing translations.
  5. SoftDelete + Loggable

    • Soft-deletions are not logged by default. Explicitly configure:
      # config/packages/gedmo_loggable.yaml
      gedmo_loggable:
          log_entry_class: App\Entity\AuditEntry
          ignored_fields: ['deletedAt']
      
  6. Uploadable File Paths

    • Validate uploadable.directories in config/packages/stof_doctrine_extensions.yaml:
      stof_doctrine_extensions:
          uploadable:
              directories:
                  product_images: '%kernel.project_dir%/public/uploads/products'
      
    • Ensure directories are writable (chmod -R 775 public/uploads).
  7. Doctrine Cache Invalidation

    • Clear cache after enabling the bundle:
      php bin/console cache:clear
      

Debugging Tips

  1. Loggable Issues

    • Check AUDIT_ENTRY table for missing logs. Verify loggable.enabled: true in config.
  2. Slug Generation

    • Override slugify() in a custom service to debug:
      public function slugify($string): string
      {
          $slug = parent::slugify($string);
          error_log("Generated slug: $slug"); // Debug
          return $slug;
      }
      
  3. Uploadable Errors

    • Validate file paths and permissions. Use:
      php bin/console debug:config stof_doctrine_extensions
      
    • Check Symfony profiler for UploadableListener exceptions.
  4. Tree (NestedSet) Errors

    • Ensure lft/rgt columns exist. Run:
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