自定义捆绑包配置中的Doctrine resolve_target_entities

时间:2017-06-26 01:05:54

标签: php symfony doctrine-orm doctrine

我制作了一个Symfony 3软件包,它具有抽象模型以进一步扩展。类似于FOS \ UserBundle中的用户模型。但是,与FOS的Bundle不同,我还需要在这些Models \ Entities之间建立关系。我已经设法通过Interfaces和Doctrine做了一点点配置(几乎是字节)。所以,就目前而言,我必须做两件事来配置 - 比方说 - 我的\ CustomBundle。

在app / config / config.yml中我必须添加:

[...]
doctrine:
    orm:
[...]
        resolve_target_entities:
            My\CustomBundle\Model\Entity1Interface: AppBundle\Entity\Entity1
            My\CustomBundle\Model\Entity2Interface: AppBundle\Entity\Entity2
[...]

还有My \ CustomBundle配置:

my_custom:
    doctrine:
        entity_1_class: AppBundle\Entity\Entity1
        entity_2_class: AppBundle\Entity\Entity2

正如您所看到的,由于doctrine.orm部分,配置有点混乱和重复。我希望我可以通过在My \ CustomBundle中自动执行来避免它。有没有可能这样做?

1 个答案:

答案 0 :(得分:0)

您可以在编译器传递的帮助下完成它。添加将根据resolve_target_entities bundle config更改my_custom的编译器传递。

<强> CompilerPass:

namespace My\CustomBundle\DependencyInjection\Compiler;

use Doctrine\ORM\Version;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class DoctrineResolveTargetEntityPass implements CompilerPassInterface
{
    /**
     * {@inheritdoc}
     */
    public function process(ContainerBuilder $container)
    {
        // resolve_target_entities
        $definition = $container->findDefinition('doctrine.orm.listeners.resolve_target_entity');

        $definition->addMethodCall('addResolveTargetEntity', array(
            $container->getParameter('my_custom.doctrine.entity_1.resolve_from'), // My\CustomBundle\Model\Entity1Interface
            $container->getParameter('my_custom.doctrine.entity_1.resolve_to'), // AppBundle\Entity\Entity1
            array(),
        ));

        if (version_compare(Version::VERSION, '2.5.0-DEV') < 0) {
            $definition->addTag('doctrine.event_listener', array('event' => 'loadClassMetadata'));
        } else {
            $definition->addTag('doctrine.event_subscriber', array('connection' => 'default'));
        }
    }
}

在捆绑包中注册此编译器传递

namespace My\CustomBundle;

use Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
use My\CustomBundle\DependencyInjection\Compiler\DoctrineResolveTargetEntityPass;

class MyCustomBundle extends Bundle
{
    public function build(ContainerBuilder $container)
    {
        parent::build($container);
        $container->addCompilerPass(new DoctrineResolveTargetEntityPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 1000);
    }
}