我想通了,回答低于 - 留下问题和所有过程的东西在这里,以便它可以帮助别人找出未来相同的东西,虽然大部分是由答案。ZF2 + Doctrine 2 - 使用工厂创建一个Doctrine SQLFilter - 如何?
我想要做的是,根据本公司,用户与(User#company
)相关的过滤器的数据。
我对这个方案的几个实体:
- 用户
- 公司
- 地址
场景为数据,在这种情况下Address
实体对象,通过创建User
实体。每个User
都有一个Company
它所属的实体。因此,每个Address
都有Address#createdByCompany
属性。
现在我试图创建一个SQLFilter
扩展,如Doctrine docs - "Working with Filters"所述。
我创建了以下类:
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
值的函数调用。
如何使用Factory来创建此类,或者使用ZF2 ServiceManager的正常路由或通过注册Doctrine本身?
我已经尝试过
下一步Google'ing很多过去几个小时,试图找到一个解决方案,我也试过以下
1 - ZF2工厂
使用在config中注册Factory的默认ZF2方法不起作用:
'service_manager' => [
'factories' => [
CreatedByCompanyFilter::class => CreatedByCompanyFilterFactory::class,
],
],
工厂根本不会被调用。这可能与执行顺序有关。我正在考虑Doctrine SQLFilters在ServiceManager完全启动并运行之前得到设置,以防万一我想要做的场景:基于某些基于角色的内容(或“公司内容”)为用户过滤数据这个案例)。
2 - Ocramius's ZF2 Delegator Factories
虽然这方面的工作,我发现Ocramius的委托者工厂。非常有趣的东西,绝对值得一读,并很好地工作。但是,不适合我的场景。我遵循他的指导并创建了一个CreatedByCompanyFilterDelegatorFactory
。这是我在配置中注册的,但没有结果,实际的Factory永远不会被调用。
(对不起,已经删除代码)
工厂我试图运行更新为*ListenerFactory
,见 '目前试图' 下面
class CreatedByCompanyListenerFactory implements FactoryInterface
{
// NOTE: REMOVED DOCBLOCKS/COMMENTS FOR LESS CODE
public function createService(ServiceLocatorInterface $serviceLocator)
{
$authService = $serviceLocator->get('zfcuser_auth_service');
$user = $authService->getIdentity();
$listener = new CreatedByCompanyListener();
$listener->setCompany($user->getCompany());
return $listener;
}
}
当前tr ying
我想我可以尝试从Gedmo Extensions和Doctrine Events剧本中跳出一页,并使用将监听器连接到loadClassMetadata
事件的格式。
举个例子,Gedmo的SoftDeleteable
有学说的配置中的以下配置,使其工作:
'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,
],
],
目的是使用*ListenerFactory
获得认证的User
实体到*Listener
。 *Listener
又将与User
关联的Company
传递到传递到CreatedByCompanyFilter
的EventArgs
。理论上讲,这个对象应该是可用的。
的CreatedByCompanyLister
是,就目前而言,以下几点:
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
}
不过,我被陷在了*ListenerFactory
使用的Zend\Authentication\AuthenticationService
,它抛出试图让User
与身份时,一个异常$user = $authService->getIdentity();
。
内部此功能延续到ZfcUser\Authentication\Storage\Db
类,线70,($identity = $this->getMapper()->findById($identity);
),它崩溃,投掷getMapper()
:
Zend\ServiceManager\ServiceManager::get was unable to fetch or create an instance for doctrine.entitymanager.orm_default
步进了(在PhpStorm的XDebug)调用不知何故让它继续一点点(跆拳道的位...),但随后抛出:
An exception was raised while creating "zfcuser_user_mapper"; no instance returned
以 “*异常*以前”,上面写着:
Circular dependency for LazyServiceLoader was found for instance Doctrine\ORM\EntityManager
独立我知道所有的这些错误的意思,但我从来没有见过所有的他们被相同的函数调用抛出(->getMapper()
)b安伏。有任何想法吗?