나는 그것을 알아 냈습니다. 답변은입니다. 질문과 모든 처리 내용을 여기에 남겨두면 누군가가 같은 것을 나중에 도출하는 데 도움이 될 수 있습니다.하지만 대부분은 대답에 의해 중복됩니다.ZF2 + Doctrine 2 - 공장을 사용하여 Doctrine SQLFilter를 작성하십시오 - 어떻게?
입니다 난 할 노력하고있어, 사용자가 (User#company
)과 연결되어 있는지 회사를 기반으로 데이터를 필터링.
나는이 시나리오에 대한 몇 가지 엔티티가 :
- 사용자
- 회사
- 주소 시나리오는 데이터,이 경우
Address
엔티티 객체에 의해 생성되는 것을
User
엔티티. 각 User
에는 속한 Company
엔터티가 있습니다. 따라서 각 Address
에는 Address#createdByCompany
속성이 있습니다.
Doctrine docs - "Working with Filters"에 설명 된대로 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의 일반 경로를 사용하거나 Doctrine 자체의 등록을 통해이 클래스를 만들 수 있습니까? 이미 해결책을 찾기 위해 노력하고, 지난 몇 시간 동안 많은 Google'ing하는
다음을 시도했다
, 나는 또한 다음
을 시도했습니다 1 - ZF2 공장
공장에서 구성을 등록하는 기본 ZF2 방법을 사용하면 작동하지 않습니다.
'service_manager' => [
'factories' => [
CreatedByCompanyFilter::class => CreatedByCompanyFilterFactory::class,
],
],
공장은 결코 간단히 호출되지 않습니다. 이것은 실행의 순서와 관련이있을 수 있습니다. ServiceManager가 완전히 실행되기 전에 Doctrine SQLFilters가 설정되었다고 생각하고 있습니다. 시나리오를 수행하려고 할 때를 대비해 일부 역할 기반 항목 (또는 "company-stuff")을 기반으로 사용자 데이터를 필터링합니다. 이 경우).
2 -이 작업을하는 동안 Ocramius's ZF2 Delegator Factories
나는 Ocramius의 위임자의 공장을 발견했다. 매우 흥미로운 것들, 확실히 읽을 가치가 있고 멋지게 작동합니다. 그러나, 내 시나리오 아닙니다. 나는 그의 가이드를 따라 CreatedByCompanyFilterDelegatorFactory
을 만들었습니다. 이것은 내가 config에 등록했지만 결과가 없으므로 실제 Factory는 결코 호출되지 않습니다.
는 (죄송합니다, 제거 코드 이미)
공장은 내가
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;
}
}
이하 '현재 시도'를 참조 가
*ListenerFactory
으로 업데이트를 실행하기 위해 노력하고있어 현재 tr ying
나는 Gedmo Extensions와 Doctrine Events 지침서에서 한 페이지를 가져와 loadClassMetadata
이벤트에 Listener를 연결하는 형식을 사용할 수 있다고 생각했습니다. 다음
'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,
],
],
예를 들어 , Gedmo의 SoftDeleteable
은 다음과 그것이 작동되도록하는 교리의 설정에서 설정을 가지고 인증 목적의 User
엔티티를 *Listener
에 가져 오기 위해 *ListenerFactory
을 사용하는 것이 목적입니다. *Listener
은 User
과 연결된 Company
을 CreatedByCompanyFilter
에 전달 된 EventArgs
으로 전달합니다. 이론적으로는 그 객체를 사용할 수 있어야합니다.
CreatedByCompanyLister
다음, 지금이다 : 그러나,이 *ListenerFactory
에 사용되는 Zend\Authentication\AuthenticationService
에 갇히지있어
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
}
, 그것은 User
의 정체성을 얻으려고 노력 예외가 발생합니다 $user = $authService->getIdentity();
.
Zend\ServiceManager\ServiceManager::get was unable to fetch or create an instance for doctrine.entitymanager.orm_default
어떻게 든 전화 (PhpStorm에서 Xdebug는)를 통해 스테핑 :
는 내부적으로이 기능은getMapper()
에 던지고, 그것은 충돌 ZfcUser\Authentication\Storage\Db
클래스, 라인 (70), ($identity = $this->getMapper()->findById($identity);
)로 계속 그것은 조금 더 (wtf의 비트에 대한 계속 ...)하지만 다음 예외 :
An exception was raised while creating "zfcuser_user_mapper"; no instance returned
라는 "* 예외 * 이전"으로 :
Circular dependency for LazyServiceLoader was found for instance Doctrine\ORM\EntityManager
자주적으로 내가 알고있는 모든 이러한 오류의 의미는 없지만 같은 함수 호출 (->getMapper()
)에 의해 throw 된 모든 것을 본 적이 없습니다. b efore. 어떤 아이디어?