edudobay / doctrine-symfony-serializer
Map fields in Doctrine ORM using Symfony Serializer
Installs: 6 953
Dependents: 0
Suggesters: 0
Security: 0
Stars: 3
Watchers: 3
Forks: 1
Open Issues: 0
Requires
- php: ^8.0
- doctrine/dbal: ^2.10 || ^3.2 || ^4.0
- doctrine/event-manager: ^1.1 || ^2.0
- doctrine/orm: ^2.12 || ^3.0
- phpdocumentor/reflection-docblock: ^5.3
- symfony/property-info: ^6.0 || ^7.0
- symfony/serializer: ^5.4 || ^6.0 || ^7.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.4
- phpstan/phpstan: ^1.3
- phpunit/phpunit: ^9.5 || ^10
- psr/cache: ^3.0
- symfony/cache: ^6.0 || ^7.0
- symfony/filesystem: ^6.0 || ^7.0
- symfony/property-access: ^6.0 || ^7.0
- vimeo/psalm: ^5.0
Suggests
- psr/cache: To support metadata caching
README
This is a proof of concept for a mapping fields with Doctrine ORM so they can be serialized with the Symfony Serializer component, without the need to create a mapping type for each possible data type.
Sometimes you just need to store a complex data type (generally a Value Object) in a JSON field and not worry about database schemas, extra columns or tables, Doctrine embeddables, custom mappings.
Installation
This library requires PHP 8.0 or later.
composer require edudobay/doctrine-symfony-serializer
Usage
See the examples directory for a working code example.
Abridged example
Add this to your application setup:
use Edudobay\DoctrineSerializable\ReflectionClassMetadataFactory; use Edudobay\DoctrineSerializable\SerializationHandler; use Edudobay\DoctrineSerializable\PersistenceEventSubscriber; $serializer = ...; // Symfony Serializer $entityManager = ...; // Doctrine ORM EntityManager $subscriber = new PersistenceEventSubscriber(new SerializationHandler( $serializer, // You might want to cache this. See Psr6CacheClassMetadataFactory new ReflectionClassMetadataFactory() )); $entityManager->getEventManager()->addEventSubscriber($subscriber);
In your entities, have your domain object as you like, and introduce a private backing field that will make it persistent:
use Doctrine\ORM\Mapping as ORM; use Edudobay\DoctrineSerializable\Attributes\Serializable; #[ORM\Entity] class User { // Backing field #[ORM\Column('address', type: 'json')] private array $_address = []; // The actual domain object #[Serializable] public Address $address; // For arrays: #[ORM\Column('badges', type: 'json')] private array $_badges = []; #[Serializable] /** @var Badge[] */ public array $badges; // OPTIONAL: use arrayItemType instead of docblock array types #[Serializable(arrayItemType: Badge::class)] public array $badges; }