letkode / entity-traits-bundle
Doctrine entity traits, value objects, DTOs and DQL utilities for Symfony applications
Package info
github.com/letkode/entity-traits-bundle
Type:symfony-bundle
pkg:composer/letkode/entity-traits-bundle
Requires
- php: ^8.4
- doctrine/doctrine-bundle: ^3.0
- doctrine/orm: ^3.0
- gedmo/doctrine-extensions: ^3.0
- letkode/common-bundle: ^1.0
- symfony/serializer: ^7.0 || ^8.0
- symfony/uid: ^7.0 || ^8.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.95
- phpstan/phpstan: ^2
- phpunit/phpunit: ^11
README
Doctrine entity traits, repository traits, value objects, DTOs and DQL utilities for Symfony applications.
Installation
composer require letkode/entity-traits-bundle
Symfony Flex will register the bundle automatically. If not using Flex, add it manually:
// config/bundles.php return [ Letkode\EntityTraitsBundle\LetkodeEntityTraitsBundle::class => ['all' => true], ];
The bundle automatically registers the TRANSLATE_FIELD_VALUE Doctrine DQL function via PrependExtensionInterface.
Entity Traits
UuidTrait
Adds a uuid column (UUIDv7) with a PostgreSQL uuidv7() default. The UuidGeneratorSubscriber ensures PHP-side generation before persist so Gedmo Loggable captures the value.
use Letkode\EntityTraitsBundle\Trait\Entity\UuidTrait; #[ORM\Entity] class Product { use UuidTrait; }
HasTranslationsTrait
Adds a translations jsonb column for multi-locale field values.
$entity->setTranslation('es', 'name', 'Producto'); $entity->getTranslation('es', 'name'); // 'Producto'
ParameterTrait
Adds a parameters jsonb column with recursive merge support.
$entity->setParameter('color', 'red'); $entity->getParameter('color'); // 'red' $entity->setParameters(['size' => 'L'], force: false); // recursive merge
ObjectTrackNullableTrait / ObjectTrackRequiredTrait
Adds objectClass and objectId columns to track which object a record belongs to. Use the nullable variant when the relation is optional.
Repository Traits
BaseRepositoryTrait
$repo->save($entity); $repo->remove($entity); $repo->findByUuid($uuid); // returns T|null $repo->findOrFailByUuid($uuid); // throws EntityNotFoundException $repo->paginate($qb, $tableQuery, sortable: ['name'], searchable: ['name', 'email']);
TranslatableRepositoryTrait
$this->addTranslatedOrderBy($qb, 'p', 'name', $locale, 'ASC'); $this->addTranslatedSearch($qb, 'p', 'name', $searchTerm, $locale);
DTOs
TableQueryRequest
$query = TableQueryRequest::fromArray($request->query->all()); // $query->page, $query->perPage, $query->q, $query->sort, $query->dir
PaginatedResult
// Returned by BaseRepositoryTrait::paginate() $result->data; // array of entities $result->total; // int $result->page; // int $result->perPage; // int $result->totalPages; // int (computed)
Value Objects
All value objects are final readonly, normalize on construction and throw ValueObjectException on invalid input.
| Class | Validates |
|---|---|
Email |
Valid email, lowercased |
Phone |
E.164-compatible (strips spaces/dashes) |
Slug |
Lowercase, [a-z0-9-], 2–255 chars |
Username |
[a-zA-Z0-9_.-], 3–50 chars |
$email = new Email(' USER@Example.COM '); // 'user@example.com' $slug = new Slug('My Product Name'); // 'my-product-name'
DQL Function
TRANSLATE_FIELD_VALUE(column, 'field', :locale) maps to jsonb_extract_path_text(column, locale, field).
Useful for ordering and filtering on translated values stored in a jsonb translations column.
Requirements
- PHP
^8.4 - Symfony
^7.0 || ^8.0 doctrine/orm^3.0doctrine/bundle^2.0gedmo/doctrine-extensions^3.0letkode/common-bundle^1.0
License
MIT — see LICENSE.