我正在使用ZF2 Apigility应用程序,该应用程序具有条令和QueryBuilderFilter模块。
基于此示例
我正在尝试为所有包含IdDealer
属性的实体获取添加一个筛选器。为此,我为所有获取事件附加了一个FetchListener
:
DoctrineResourceEvent::EVENT_FETCH_PRE
DoctrineResourceEvent::EVENT_FETCH_ALL_PRE
然后,如果实体与这个过滤器兼容,我会尝试向查询添加一个过滤器。
public function __invoke(DoctrineResourceEvent $event)
{
if ($event->getName() == DoctrineResourceEvent::EVENT_FETCH_ALL_PRE)
$entity_class = $event->getEntity();
else //DoctrineResourceEvent::EVENT_FETCH_PRE
$entity_class = $event->getEntityClassName();
/** Entity has idDealer so we filter for the user */
if (method_exists($entity_class, 'getIdDealer')) {
$em = $event->getObjectManager();
$filterManager = $this->getServiceManager()->get('Zf'Doctrine'QueryBuilder'Filter'ManagerOrm');
$filterManager->filter(
$em->createQueryBuilder()->select('row')->from($entity_class, 'row'),
$em->getMetadataFactory()->getMetadataFor($entity_class),
[
'filter' => [
'type' => 'eq',
'field' => 'idDealer',
'value' => (int)$this->getUser()->getIdDealer()->getId(),
]
]
);
}
}
但我无法让过滤器工作。我在网上发现了一些信息,说我应该能够从事件中检索到QueryBuilder
,但现在似乎已经不是这样了。
有人知道如何让它发挥作用吗?
我刚刚花了几个小时尝试做一些非常类似的事情。
zf条令querybuilder指南建议您可以使用Apigility条令事件来过滤查询:https://github.com/zfcampus/zf-doctrine-querybuilder#use-具有资本充足性原则的
并链接到一个示例:https://github.com/zfcampus/zf-doctrine-querybuilder/blob/master/docs/apigility.example.php
然而,我认为由于"从DoctrineResourceEvents中删除QueryBuilder;添加ObjectManager#182"的更改,此建议和示例代码现在已经过时:https://github.com/zfcampus/zf-apigility-doctrine/pull/182
我相信他们希望我们通过自定义查询提供程序来实现这一目标。请参阅以下文档,该文档提供了如何将自定义查询提供程序绑定到特定实体的示例:https://github.com/zfcampus/zf-apigility-doctrine#query-供应商
查询提供程序可用于所有查找操作。查找查询提供程序用于在对所有实体执行操作之前获取实体DoctrineResource方法(create除外)。
查询提供程序返回QueryBuilder对象。通过使用自定义查询提供程序,您可以注入特定于资源的条件,或者用户,而不修改资源。例如,您可以添加$queryBuilder->andWhere('user='.$event->getIdentity());在您的查询提供程序,然后返回在其中创建的QueryBuilder。
如果您想查看查询提供程序侦听器的示例,请参阅ZF''Doctrine''QueryBuilder''Query''Provider''DefaultOrm:https://github.com/zfcampus/zf-doctrine-querybuilder/blob/master/src/Query/Provider/DefaultOrm.php
到目前为止,我还没有找到任何其他解决方案来获取正在使用的QueryBuilder的句柄,就像以前可以从DoctrineResourceEvent对象获取它一样。
希望这能帮助
Alex