mmoreram/simple-doctrine-mapping
Add Doctrine entity mapping to Symfony bundles without relying on Doctrine auto_mapping. Define entity class, mapping file path, and manager via a simple CompilerPass, enabling clean, per-bundle configuration and easy overrides/customization.
Installation:
composer require mmoreram/simple-doctrine-mapping
Add the CompilerPass to your bundle's Kernel.php or DependencyInjection/Extension:
use Mmoreram\SimpleDoctrineMapping\DependencyInjection\Compiler\MappingPass;
$container->addCompilerPass(new MappingPass());
Define Mappings:
Create a YAML/XML/JSON mapping file (e.g., Resources/config/doctrine/mapping.yml) for your entities:
App\Entity\User:
type: entity
table: users
fields:
id: ~
name: { type: string, length: 255 }
Register Mappings in DI:
Override load() in your bundle's Extension to register mappings:
public function load(array $configs, ContainerBuilder $container) {
$mapping = new Mapping();
$mapping->addMapping(
new Mapping\EntityMapping('App\Entity\User', 'App/Resources/config/doctrine/mapping.yml')
);
$container->setParameter('mmoreram_simple_doctrine_mapping.mappings', [$mapping]);
}
First Use Case: Use the mapped entities in your services/controllers as usual:
$user = $entityManager->find('App\Entity\User', 1);
Bundle-Specific Mappings:
Each bundle manages its own entities via Mapping\EntityMapping. Example:
$mapping->addMapping(new Mapping\EntityMapping(
'App\Entity\Post',
'App/Resources/config/doctrine/mapping.yml',
'default' // EntityManager name
));
Dynamic Configuration: Use compiler passes to dynamically register mappings based on bundle config:
public function load(array $configs, ContainerBuilder $container) {
$config = $this->processConfiguration($configuration, $configs);
foreach ($config['entities'] as $entity => $mappingFile) {
$mapping->addMapping(new Mapping\EntityMapping($entity, $mappingFile));
}
}
Integration with BaseBundle:
For advanced use, integrate with BaseBundle to centralize mappings:
# config/packages/mmoreram_base.yaml
mmoreram_base:
entity_mapping:
enabled: true
mappings:
App\Entity\User: 'App/Resources/config/doctrine/user_mapping.yml'
Overriding Mappings: Allow users to override mappings via bundle config:
// In your bundle's Extension
$container->setParameter('mmoreram_simple_doctrine_mapping.overrides', [
'App\Entity\User' => 'vendor/path/to/custom_mapping.yml'
]);
EntityManager-Specific Mappings: Assign mappings to specific EntityManagers:
# mapping.yml
App\Entity\LegacyUser:
manager: legacy_em
table: legacy_users
CompilerPass Timing:
MappingPass runs. If using Extension, ensure load() is called early in the DI process.dump($container->hasParameter('mmoreram_simple_doctrine_mapping.mappings')) to verify registration.Circular Dependencies:
Avoid circular references in mapping files (e.g., ManyToMany with bidirectional associations). Use lazy loading or separate mapping files.
Namespace Conflicts:
Ensure entity FQCNs in mappings match the actual class names. Use get_class($entity) to verify.
Outdated Doctrine: The package was last updated in 2016 and may not support Doctrine 2.8+. Test with your version or fork for updates.
Missing MappingPass:
Forgetting to add the MappingPass to the container will silently fail. Check Kernel.php or Extension for the pass.
Dump Mappings:
Add this to your Extension to log mappings:
$mappings = $container->getParameter('mmoreram_simple_doctrine_mapping.mappings');
file_put_contents(__DIR__.'/../var/mappings.log', print_r($mappings, true));
Validate YAML:
Use Symfony’s YamlFileLoader to validate mapping files:
$loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('doctrine/mapping.yml'); // Throws exception on invalid YAML
Check EntityManager: Verify the correct EntityManager is used:
$em = $container->get('doctrine')->getManager('default');
$metadata = $em->getMetadataFactory()->getMetadataFor('App\Entity\User');
Custom Mapping Types:
Extend Mapping\MappingInterface to support new formats (e.g., PHP arrays):
class ArrayMapping implements MappingInterface {
public function load(MappingBuilder $builder, ContainerBuilder $container) {
// Parse array and build mappings
}
}
Post-Compile Hooks:
Use Symfony’s kernel.request event to validate mappings after compilation:
$eventDispatcher->addListener('kernel.request', function() {
$mappings = $container->getParameter('mmoreram_simple_doctrine_mapping.mappings');
// Custom validation logic
});
Dynamic Mapping Generation: Generate mapping files at runtime (e.g., from database schema):
$schemaManager = $em->getConnection()->createSchemaManager();
$tables = $schemaManager->listTables();
foreach ($tables as $table) {
$mapping->addMapping(new Mapping\EntityMapping(
'App\Entity\\'.ucfirst($table->getName()),
'generated/mapping_'.$table->getName().'.yml'
));
}
Override Resolution: Implement a custom resolver for mapping overrides:
$container->setParameter('mmoreram_simple_doctrine_mapping.override_resolver', function($entity, $defaultPath) {
return 'custom/path/to/'.$entity.'.yml';
});
How can I help you explore Laravel packages today?