ik-oss / doctrine-dynamic-discriminator-map
Dynamic discriminator map for Doctrine ORM
Package info
github.com/INTERLIGENT-kommunzieren-GmbH/doctrine-dynamic-discriminator-map
pkg:composer/ik-oss/doctrine-dynamic-discriminator-map
Requires
- php: ~8.5.0
- doctrine/event-manager: ^2.1
- doctrine/orm: ^3.6
- psr/container: ^1.1.2 || ^2.0.2
Requires (Dev)
- laminas/laminas-coding-standard: ^3.1
- phpunit/phpunit: ^13.3
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-09-22 16:24:12 UTC
README
Adds the ability to declare a Doctrine ORM entity discriminator map from configuration,
instead of having to list every child entity in the parent's #[DiscriminatorMap] attribute.
Entries coming from configuration are merged on top of the ones declared via the
#[DiscriminatorMap] attribute, so configuration wins on key collisions.
Requirements
- PHP 8.5
- Doctrine ORM 3.6+
Installation
$ composer require ik-oss/doctrine-dynamic-discriminator-map
Usage
Entities
Declare the parent entity with an inheritance type, a discriminator column and (optionally) a discriminator map containing only itself:
<?php declare(strict_types=1); namespace My\Namespace\Entity; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity] #[ORM\Table(name: 'person')] #[ORM\InheritanceType('SINGLE_TABLE')] #[ORM\DiscriminatorColumn(name: 'type', type: 'string')] #[ORM\DiscriminatorMap(['person' => Person::class])] class Person { // ... }
The children need no discriminator entry of their own:
<?php declare(strict_types=1); namespace My\Namespace\Entity; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity] class Student extends Person { // ... } #[ORM\Entity] class Teacher extends Person { // ... }
Register the listener on the Doctrine event manager
<?php declare(strict_types=1); use Doctrine\Common\EventManager; use Doctrine\DBAL\DriverManager; use Doctrine\ORM\EntityManager; use Doctrine\ORM\ORMSetup; use Ikoss\DoctrineDDM\Factory\MetadataConfigFactory; use Ikoss\DoctrineDDM\MetadataListener; use My\Namespace\Entity; $metadataConfig = (new MetadataConfigFactory())->createMetadata([ Entity\Person::class => [ // parent class 'discriminator_map' => [ 'teacher' => Entity\Teacher::class, // child class 'student' => Entity\Student::class, // child class ], ], ]); $eventManager = new EventManager(); $eventManager->addEventSubscriber(new MetadataListener($metadataConfig)); $config = ORMSetup::createAttributeMetadataConfiguration([__DIR__ . '/src'], true); $config->enableNativeLazyObjects(true); $connection = DriverManager::getConnection(['driver' => 'pdo_sqlite', 'memory' => true]); $entityManager = new EntityManager($connection, $config, $eventManager);
That's it — Person now resolves student and teacher discriminator values:
$entityManager->getClassMetadata(Entity\Person::class)->discriminatorMap; // [ // 'person' => My\Namespace\Entity\Person::class, // from the attribute // 'teacher' => My\Namespace\Entity\Teacher::class, // from configuration // 'student' => My\Namespace\Entity\Student::class, // from configuration // ]
Note:
ORMSetuprequiressymfony/cacheto build its default metadata cache. Either add it to your project or pass your own PSR-6 pool as the fourth argument.enableNativeLazyObjects(true)uses PHP 8.4+ native lazy objects instead of requiringsymfony/var-exporter.
Framework integration
Invokable factories
Ikoss\DoctrineDDM\Factory\MetadataConfigFactory and Ikoss\DoctrineDDM\Factory\MetadataListenerFactory
both expose an __invoke(ContainerInterface $container) method usable with any PSR-11 container.
MetadataConfigFactory reads the config service and looks for a
Ikoss\DoctrineDDM\Factory\MetadataConfigFactory::class key holding the discriminator map
configuration, returning a Ikoss\DoctrineDDM\Configuration\Metadata instance.
MetadataListenerFactory reads the Ikoss\DoctrineDDM\Configuration\Metadata service and
returns a configured Ikoss\DoctrineDDM\MetadataListener.
Laminas and Mezzio
The package ships a ConfigProvider (Mezzio) and a Module (Laminas MVC), both registering
the factories above. With DoctrineORMModule:
<?php declare(strict_types=1); use Ikoss\DoctrineDDM\Configuration\Metadata; use Ikoss\DoctrineDDM\Factory\MetadataConfigFactory; use Ikoss\DoctrineDDM\Factory\MetadataListenerFactory; use Ikoss\DoctrineDDM\MetadataListener; use My\Namespace\Entity; return [ 'service_manager' => [ // or "dependencies" for Mezzio 'factories' => [ Metadata::class => MetadataConfigFactory::class, MetadataListener::class => MetadataListenerFactory::class, ], ], 'doctrine' => [ 'eventmanager' => [ 'orm_default' => [ 'subscribers' => [ MetadataListener::class, ], ], ], ], // discriminator map configuration read by MetadataConfigFactory MetadataConfigFactory::class => [ Entity\Person::class => [ // parent class 'discriminator_map' => [ 'teacher' => Entity\Teacher::class, // child class 'student' => Entity\Student::class, // child class ], ], ], ];
Development
$ composer install
$ composer test # PHPUnit
$ composer cs-check # phpcs
$ composer cs-fix # phpcbf
$ composer check # cs-check + test
Credits
This package is a continuation of facile-it/doctrine-dynamic-discriminator-map
by Thomas Vargiu, maintained by INTERLIGENT kommunizieren GmbH under the ik-oss namespace
as the upstream project is no longer maintained.
License
MIT — see LICENSE.md.