Doctrine orm ZF2和x2B;条令2-使用工厂创建条令SQLFilter-如何?

Doctrine orm ZF2和x2B;条令2-使用工厂创建条令SQLFilter-如何?,doctrine-orm,zend-framework2,doctrine-orm-filters,Doctrine Orm,Zend Framework2,Doctrine Orm Filters,我找到了答案,答案如下-将问题和所有流程内容留在这里,以防将来可能会有人找到相同的答案,尽管大部分答案都是多余的 我想做的是,根据用户关联的公司过滤数据(User#Company) 对于这种情况,我有几个实体: 使用者 公司 地址 这种情况下,数据(在本例中为地址实体对象)由用户实体创建。每个用户都有其所属的公司实体。因此,每个地址都有一个地址#createdByCompany属性 现在,我正试图创建一个SQLFilter扩展,如 我创建了以下类: class CreatedByCompa

我找到了答案,答案如下-将问题和所有流程内容留在这里,以防将来可能会有人找到相同的答案,尽管大部分答案都是多余的


我想做的是,根据用户关联的公司过滤数据(
User#Company

对于这种情况,我有几个实体:

  • 使用者
  • 公司
  • 地址
这种情况下,数据(在本例中为
地址
实体对象)由
用户
实体创建。每个
用户
都有其所属的
公司
实体。因此,每个
地址
都有一个
地址#createdByCompany
属性

现在,我正试图创建一个
SQLFilter
扩展,如

我创建了以下类:

class CreatedByCompanyFilter extends SQLFilter
{
    /**
     * @var Company
     */
    protected $company;

    /**
     * @param ClassMetadata $targetEntity
     * @param string $targetTableAlias
     * @return string
     * @throws TraitNotImplementException
     */
    public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias)
    {
        // Check if Entity implements CreatedByCompanyAwareInterface, if not, return empty string
        if (!$targetEntity->getReflectionClass()->implementsInterface(CreatedByCompanyInterface::class)) {

            return '';
        }

        if (!array_key_exists(CreatedByCompanyTrait::class, $targetEntity->getReflectionClass()->getTraits())) {

            throw new TraitNotImplementException(
                ($targetEntity->getReflectionClass()->getName()) . ' requires "' . CreatedByCompanyTrait::class . '" to be implemented.'
            );
        }

        return $targetTableAlias . '.created_by_company = ' . $this->getCompany()->getId();
    }

    /**
     * @return Company
     */
    public function getCompany(): Company // Using PHP 7.1 -> explicit return types
    {
        return $this->company;
    }

    /**
     * @param Company $company
     * @return CreatedByCompanyFilter
     */
    public function setCompany(Company $company): CreatedByCompanyFilter
    {
        $this->company = $company;
        return $this;
    }
}
要使用此筛选器,它将在配置和设置中注册,以加载到模块引导(
onBootstrap
)中。到目前为止,上述方法得到了应用

但是,上述内容不是通过工厂模式使用的。另外,您可能会注意到,
addFilterConstraint(…)
使用
$this->getCompany()->>getId()
,但是
$this->setCompany()
不会在任何地方调用,而是对
null
值创建函数调用

我如何使用工厂创建此类,或者使用ZF2 ServiceManager的常规路径,或者通过原则本身的注册


我已经尝试过的

除了在过去的几个小时里谷歌搜索了很多东西,试图找到一个解决方案,我还尝试了以下几点

1-ZF2工厂

使用默认的ZF2方法在配置中注册工厂不起作用:

'service_manager' => [
    'factories' => [
        CreatedByCompanyFilter::class => CreatedByCompanyFilterFactory::class,
    ],
],
这家工厂根本没有接到电话。这可能与执行顺序有关。我想在ServiceManager完全启动和运行之前就设置好过滤器,以防出现我正在尝试的场景:根据一些基于角色的内容(或本例中的“公司内容”)为用户过滤数据

2-

在这项工作中,我找到了奥克拉米乌斯的授权者工厂。非常有趣的东西,绝对值得一读,效果很好。但是,对于我的场景,情况并非如此。我按照他的指导创建了一个
CreatedByCompanyFilterDelegatorFactory
。这是我在配置中注册的,但没有结果,实际的工厂从未被调用

(抱歉,已删除代码)


我尝试运行的工厂更新为
*ListenerFactory
,请参阅下面的“当前正在尝试”


当前正在尝试

我想我可以尝试从Gedmo扩展和条令事件剧本中抽出一页,使用将侦听器挂接到
loadClassMetadata
事件的格式

例如,Gedmo在条令配置中具有以下配置,以使其工作:

'eventmanager' => [
    'orm_default' => [
        'subscribers' => [
            SoftDeleteableListener::class,
        ],
    ],
],
'configuration' => [
    'orm_default' => [
        'filters' => [
            'soft-deleteable' => SoftDeleteableFilter::class,
        ],
    ],
],
所以我想,见鬼,让我们试试,然后设置以下内容:

'eventmanager' => [
    'orm_default' => [
        'subscribers' => [
            CreatedByCompanyListener::class,
        ],
    ],
],
'configuration' => [
    'orm_default' => [
        'filters' => [
            'created-by-company' => CreatedByCompanyFilter::class,
        ],
    ],
],
'service_manager' => [
    'factories' => [
        CreatedByCompanyListener::class => CreatedByCompanyListenerFactory::class,
    ],
],
class CreatedByCompanyListener implements EventSubscriber
{
    //NOTE: REMOVED DOCBLOCKS/HINTS FOR LESS CODE
    protected $company;

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

    public function loadClassMetadata(EventArgs $eventArgs)
    {
        $test = $eventArgs; // Debug line, not sure on what to do if this works yet ;) 
    }

    // $company getter/setter
}
'listeners' => [
    CreatedByCompanyListener::class,
],
'service_manager' => [
    'factories' => [
        CreatedByCompanyListener::class => CreatedByCompanyListenerFactory::class,
    ],
],
目的是使用
*监听器工厂
将经过身份验证的
用户
实体放入
*监听器
*侦听器
依次将与
用户
关联的
公司
传递到传递给
CreatedByCompanyFilter的
事件参数
。从理论上讲,这样做应该是可行的

目前,CreatedByCompanyLister的
功能如下:

'eventmanager' => [
    'orm_default' => [
        'subscribers' => [
            CreatedByCompanyListener::class,
        ],
    ],
],
'configuration' => [
    'orm_default' => [
        'filters' => [
            'created-by-company' => CreatedByCompanyFilter::class,
        ],
    ],
],
'service_manager' => [
    'factories' => [
        CreatedByCompanyListener::class => CreatedByCompanyListenerFactory::class,
    ],
],
class CreatedByCompanyListener implements EventSubscriber
{
    //NOTE: REMOVED DOCBLOCKS/HINTS FOR LESS CODE
    protected $company;

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

    public function loadClassMetadata(EventArgs $eventArgs)
    {
        $test = $eventArgs; // Debug line, not sure on what to do if this works yet ;) 
    }

    // $company getter/setter
}
'listeners' => [
    CreatedByCompanyListener::class,
],
'service_manager' => [
    'factories' => [
        CreatedByCompanyListener::class => CreatedByCompanyListenerFactory::class,
    ],
],
但是,我一直在使用
*ListenerFactory
中使用的
Zend\Authentication\AuthenticationService
,它在尝试使用
$User=$authService->getIdentity()获取
用户的身份时抛出异常

在内部,该函数继续进入
ZfcUser\Authentication\Storage\Db
类的第70行(
$identity=$this->getMapper()->findById($identity);
),在那里它崩溃,抛出
getMapper()

Zend\ServiceManager\ServiceManager::get无法获取或创建doctrine.entitymanager.orm_default的实例

跨过(PhpStorm中的xdebug)该调用会让它继续一段时间(wtf的一段…),但随后会抛出:

创建“zfcuser\u user\u映射器”时引发异常;没有返回实例

带有一个“*例外*上一个”,表示:

在实例条令\ORM\EntityManager中找到LazyServiceLoader的循环依赖项


独立而言,我知道所有这些错误的含义,但我以前从未见过所有这些错误都被同一个函数调用(
->getMapper()
)抛出。有什么想法吗

当然,我当时的想法太复杂了。我现在使用以下类运行它:

  • CreatedByCompanyFilter
  • CreatedByCompanyListener
  • CreatedByCompanyListenerFactory
我需要的唯一配置是:

'eventmanager' => [
    'orm_default' => [
        'subscribers' => [
            CreatedByCompanyListener::class,
        ],
    ],
],
'configuration' => [
    'orm_default' => [
        'filters' => [
            'created-by-company' => CreatedByCompanyFilter::class,
        ],
    ],
],
'service_manager' => [
    'factories' => [
        CreatedByCompanyListener::class => CreatedByCompanyListenerFactory::class,
    ],
],
class CreatedByCompanyListener implements EventSubscriber
{
    //NOTE: REMOVED DOCBLOCKS/HINTS FOR LESS CODE
    protected $company;

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

    public function loadClassMetadata(EventArgs $eventArgs)
    {
        $test = $eventArgs; // Debug line, not sure on what to do if this works yet ;) 
    }

    // $company getter/setter
}
'listeners' => [
    CreatedByCompanyListener::class,
],
'service_manager' => [
    'factories' => [
        CreatedByCompanyListener::class => CreatedByCompanyListenerFactory::class,
    ],
],
注意:未在条令配置中注册筛选器。因此如果您希望这样做,请不要执行下面的操作

'doctrine' => [
    'eventmanager' => [
        'orm_default' => [
            'subscribers' => [
                CreatedByCompanyListener::class,
            ],
        ],
    ],
    'configuration' => [
        'orm_default' => [
            'filters' => [
                'created-by-company' => CreatedByCompanyFilter::class,
            ],
        ],
    ],
],
重复:在这个场景中不需要上述内容-尽管看到我一直在做什么,但我可以看到我(和其他人)可能会怎么想


因此,只有3个类,其中一个是注册的
Listener
,在
ServiceManager
配置中有一个注册的
ListenerFactory

逻辑是,
侦听器
需要使用
原则实体管理器
启用
过滤器
,然后可以在返回值(过滤器)中设置所需参数。不确定“Daredevel”是否有Stackoverflow帐户,但在其中