Documentação do Symfony - versão 3.1
Renderizada do repositório symfony-docs-pt-BR no Github
Ao construir um bundle que pode ser utilizado não somente com o ORM Doctrine, mas também o ODM CouchDB, o ODM MongoDB ou o ODM PHPCR, você ainda deve escrever somente uma classe de modelo. Os bundles do Doctrine fornecem um compiler pass para registrar os mapeamentos para as suas classes de modelo.
Note
Para bundles não reutilizáveis, a opção mais fácil é colocar suas classes de modelo
nos locais padrão: Entity
para o ORM Doctrine ou Document
para os ODMs. Para bundles reutilizáveis, em vez de duplicar as classes de modelo
apenas para obter o auto-mapping, use o compiler pass.
Em sua classe do bundle, escreva o código seguinte para registrar o compiler pass. Esse foi escrito para o CmfRoutingBundle, por isso partes dele devem ser adaptadas para o seu caso:
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\DoctrineOrmMappingsPass;
use Doctrine\Bundle\MongoDBBundle\DependencyInjection\Compiler\DoctrineMongoDBMappingsPass;
use Doctrine\Bundle\CouchDBBundle\DependencyInjection\Compiler\DoctrineCouchDBMappingsPass;
use Doctrine\Bundle\PHPCRBundle\DependencyInjection\Compiler\DoctrinePhpcrMappingsPass;
class CmfRoutingBundle extends Bundle
{
public function build(ContainerBuilder $container)
{
parent::build($container);
// ...
$modelDir = realpath(__DIR__.'/Resources/config/doctrine/model');
$mappings = array(
$modelDir => 'Symfony\Cmf\RoutingBundle\Model',
);
$ormCompilerClass = 'Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\DoctrineOrmMappingsPass';
if (class_exists($ormCompilerClass)) {
$container->addCompilerPass(
DoctrineOrmMappingsPass::createXmlMappingDriver(
$mappings,
array('cmf_routing.model_manager_name'),
'cmf_routing.backend_type_orm',
array('CmfRoutingBundle' => 'Symfony\Cmf\RoutingBundle\Model')
));
}
$mongoCompilerClass = 'Doctrine\Bundle\MongoDBBundle\DependencyInjection\Compiler\DoctrineMongoDBMappingsPass';
if (class_exists($mongoCompilerClass)) {
$container->addCompilerPass(
DoctrineMongoDBMappingsPass::createXmlMappingDriver(
$mappings,
array('cmf_routing.model_manager_name'),
'cmf_routing.backend_type_mongodb',
array('CmfRoutingBundle' => 'Symfony\Cmf\RoutingBundle\Model')
));
}
$couchCompilerClass = 'Doctrine\Bundle\CouchDBBundle\DependencyInjection\Compiler\DoctrineCouchDBMappingsPass';
if (class_exists($couchCompilerClass)) {
$container->addCompilerPass(
DoctrineCouchDBMappingsPass::createXmlMappingDriver(
$mappings,
array('cmf_routing.model_manager_name'),
'cmf_routing.backend_type_couchdb',
array('CmfRoutingBundle' => 'Symfony\Cmf\RoutingBundle\Model')
));
}
$phpcrCompilerClass = 'Doctrine\Bundle\PHPCRBundle\DependencyInjection\Compiler\DoctrinePhpcrMappingsPass';
if (class_exists($phpcrCompilerClass)) {
$container->addCompilerPass(
DoctrinePhpcrMappingsPass::createXmlMappingDriver(
$mappings,
array('cmf_routing.model_manager_name'),
'cmf_routing.backend_type_phpcr',
array('CmfRoutingBundle' => 'Symfony\Cmf\RoutingBundle\Model')
));
}
}
}
Note a verificação class_exists
. Isso é crucial, pois você não quer que seu
bundle tenha uma dependência em todos os bundles do Doctrine, mas sim permitir que o usuário
decida qual usar.
O compiler pass fornece métodos factory para todos os drivers fornecidos pelo Doctrine: Anotações, XML, YAML, PHP e StaticPHP. Os argumentos são:
cmf_routing.model_manager_name
. O compiler pass irá acrescentar o parâmetro Doctrine que está
usando para especificar o nome do gerenciador padrão. O primeiro parâmetro encontrado é
utilizado e os mapeamentos são registrados com aquele gerenciador;$om->getRepository('CmfRoutingBundle:Route')
.Note
O método factory está usando o SymfonyFileLocator
do Doctrine, significando
que ele só vai ver os arquivos de mapeamento XML e YML se eles não contêm o
namespace completo como nome do arquivo. Isso ocorre por concepção: o SymfonyFileLocator
simplifica as coisas, assumindo que os arquivos são apenas a versão “curta”
da classe como o seu nome de arquivo (por exemplo, BlogPost.orm.xml
)
Se você também precisa mapear uma classe base, você pode registrar um compiler pass
com o DefaultFileLocator
como abaixo. Este código é retirado do
DoctrineOrmMappingsPass
e adaptado para usar o DefaultFileLocator
ao invés do SymfonyFileLocator
:
private function buildMappingCompilerPass()
{
$arguments = array(array(realpath(__DIR__ . '/Resources/config/doctrine-base')), '.orm.xml');
$locator = new Definition('Doctrine\Common\Persistence\Mapping\Driver\DefaultFileLocator', $arguments);
$driver = new Definition('Doctrine\ORM\Mapping\Driver\XmlDriver', array($locator));
return new DoctrineOrmMappingsPass(
$driver,
array('Full\Namespace'),
array('your_bundle.manager_name'),
'your_bundle.orm_enabled'
);
}
Note que você não precisa fornecer um alias de namespace a menos que espera-se que seus usuários perguntem ao Doctrine pelas classes base.
Agora coloque o seu arquivo de mapeamento em /Resources/config/doctrine-base
com o
nome completo da classe, separado por .
ao invés de \
, por exemplo
Other.Namespace.Model.Name.orm.xml
. Você não pode misturar os dois pois
o SymfonyFileLocator
ficará confuso.
Ajuste em conformidade com as outras implementações Doctrine.