effiana/doctrine-extensions-bundle
Installation Add the bundle via Composer:
composer require effiana/doctrine-extensions-bundle
Register the bundle in config/bundles.php:
return [
// ...
Effiana\DoctrineExtensionsBundle\EffianaDoctrineExtensionsBundle::class => ['all' => true],
];
Enable Extensions
Configure Doctrine extensions in config/packages/doctrine.yaml:
doctrine:
orm:
mappings:
gedmo_loggable: ~
gedmo_translatable: ~
gedmo_tree: ~
gedmo_timestampable: ~
# Add other extensions as needed
First Use Case: Timestampable
Apply the Timestampable trait to an entity:
use Gedmo\Mapping\Annotation as Gedmo;
/**
* @Gedmo\Timestampable(on="create")
*/
class Post
{
// ...
}
Run migrations to add created_at column:
php bin/console doctrine:mapping:import App\Entity --force
php bin/console doctrine:migrations:diff
php bin/console doctrine:migrations:migrate
Logging Entity Changes
Use Loggable for tracking entity modifications:
use Gedmo\Loggable\Entity\MappedSuperclass\AbstractLogEntry;
use Gedmo\Loggable\Entity\Repository\LogEntryRepository;
/**
* @Gedmo\Loggable
*/
class Product
{
// ...
}
Query logs via repository:
$logEntries = $this->logEntryRepository->findBy(['objectClass' => Product::class]);
Translatable Entities
Implement Translatable for multilingual support:
use Gedmo\Translatable\Entity\Translation;
/**
* @Gedmo\TranslationEntity(class="App\Entity\ProductTranslation")
*/
class Product
{
// ...
}
Define translation entity:
class ProductTranslation extends Translation
{
// Custom fields (e.g., language-specific attributes)
}
Tree Structures (Nested Sets)
Use Tree for hierarchical data:
/**
* @Gedmo\Tree(type="nested")
*/
class Category
{
// ...
}
Manage tree via repository methods:
$category->getChildren(); // Get child nodes
$category->getParent(); // Get parent node
prePersist, preUpdate).@Gedmo\Timestampable(on="update")).GEDMO\Tree\TreeQueryBuilder).Migration Conflicts
doctrine:mapping:import before generating migrations to avoid column mismatches.created_at, updated_at) without explicit schema updates.Circular References
Tree extension can cause infinite loops if parent-child relationships are bidirectional. Use @ORM\BackedMap or @ORM\BackedTarget to optimize.Translation Overwrites
Translatable entities have a unique translationKey to avoid duplicate translations.Log Entry Bloat
Loggable tracks every change by default. Filter logs in LogEntryRepository to avoid performance issues:
$logs = $this->logEntryRepository->createQueryBuilder('e')
->where('e.objectClass = :class')
->andWhere('e.changedFields LIKE :field')
->setParameter('class', Product::class)
->setParameter('field', '%name%')
->getQuery()
->getResult();
config/packages/dev/doctrine.yaml:
doctrine:
dbal:
logging: true
profiling: true
php bin/console debug:event-dispatcher
php bin/console cache:clear
Custom Log Entry Class
Override LogEntry in config/packages/doctrine_extensions.yaml:
gedmo_loggable:
log_entry_class: App\Entity\CustomLogEntry
Tree Type
Switch between nested (default) and materialized_path:
/**
* @Gedmo\Tree(type="materialized_path")
*/
class Category { ... }
Timestampable Fields Customize created/updated fields:
gedmo_timestampable:
timestamp_aware_entity_listener: true
timestampable_on_create:
enabled: true
field_name: custom_created_at
timestampable_on_update:
enabled: true
field_name: custom_updated_at
Translatable Fallback Configure fallback translations:
/**
* @Gedmo\Translatable(fallback=true)
*/
class Product { ... }
How can I help you explore Laravel packages today?