DiscriminatorMap批注中的环境变量或函数

西蒙

如何获得基于当前环境设置的鉴别器图?

我有一个使用单表继承和鉴别符列的实体:

@ORM\DiscriminatorMap({1="Product", 2="User"})

鉴别符值(1, 2)在我的生产和开发环境中有所不同,因此需要动态设置这些值。不幸的是,在Doctrine注释文档中,这似乎不是一个选项

在注释中直接使用环境似乎无效。例如,我尝试过:

@ORM\DiscriminatorMap('%discrimination_array%')

然后discrimination_array在中定义doctrine.yaml

discrimination_array: '{%env(PRODUCT)%="Product", %env(USER)%="User"}'

以及以下方面的相应环境变量.env

PRODUCT=1
USER=2

但是,Doctrine会抛出诸如

将varchar值'%env(PRODUCT)%'转换为数据类型smallint时,转换失败。

是否可以根据当前环境设置类别区分图?

亚力山大

这可以通过扩展特定实体的数据映射来完成。当注释被解析时,Doctrine会触发一个事件

读取实体的映射信息后,会将其填充到ClassMetadataInfo实例中。您可以参与此过程并操作实例。

通过订阅此事件,可以DiscriminatorMap在加载实体设置实体的

这是一个一般的例子。首先,实现一个订户。在加载相关实体(Item::class)时,添加相关DiscriminatorMap

<?php

namespace App\Doctrine\Listener;

use App\Entity\Item;
use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Event\LoadClassMetadataEventArgs;

class LoadClassMetadataSubscriber implements EventSubscriber
{
    private $discriminatorMap;

    public function __construct( $discriminatorMap)
    {
        $this->discriminatorMap = $discriminatorMap;
    }

    public function getSubscribedEvents()
    {
        return [
            Events::loadClassMetadata
        ];
    }

    /**
     * @param LoadClassMetadataEventArgs $eventArgs
     */
    public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs)
    {
        /**
         * @var \Doctrine\ORM\Mapping\ClassMetadata $classMetadata
         */
        $classMetadata = $eventArgs->getClassMetadata();

        if ($classMetadata->name !== Item::class) {
            return;
        }

        $map = [];
        foreach ($this->discriminatorMap as $value) {
            $partial = explode('=', $value);
            $map[$partial[0]] = $partial[1];
        }

        $classMetadata->setDiscriminatorMap($map);
    }
}

因为鉴别符映射是类解析之后添加的,Entity\Item所以不需要DiscriminatorMap注释:

<?php

namespace App\Entity;

use App\Map;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(...)
 * @ORM\Table(...)
 * @ORM\InheritanceType("SINGLE_TABLE")
 * @ORM\DiscriminatorColumn(name="discr", type="string")
 */
abstract class Item {

映射应添加到环境(.env或类似环境)中:

DISCRIMINATOR_MAP=one=App\Entity\Item\One,two=App\Entity\Item\Two

为订户注册正确的事件(config/services.yaml):

services:
    ...

    # Set up the custom subscriber. It'll take the environmental variable as
    # an argument, and subscribe to the `loadClassMetadata` event. 
    App\Doctrine\Listener\LoadClassMetadataSubscriber:
        public: true
        arguments:
            - '%env(csv:MAP)%'
        tags:
            - { name: doctrine.event_listener, event: loadClassMetadata, lazy: true }

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章