我正在为我的网站使用api-platform(https://api-platform.com/)框架,我试图用不同的标准多次序列化一个实体的集合。我创建了以下示例实体:
EntityWithFilteredCollection
namespace AppBundle\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ApiResource(attributes={"normalization_context"={"groups"={"get"}}})
* @ORM\Entity()
*/
class EntityWithFilteredCollection
{
/**
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
* @ORM\Column(type="integer")
* @Groups({"get"})
*/
private $id;
/**
* @ORM\OneToMany(targetEntity="AppBundle\Entity\FilteredCollectionRelatedEntity", mappedBy="relatedEntity")
*/
private $relatedEntities;
/**
* @Groups({"get"})
*/
private $filteredEntities;
public function __construct()
{
$this->relatedEntities = new ArrayCollection();
}
public function getId()
{
return $this->id;
}
public function getRelatedEntities()
{
return $this->relatedEntities;
}
public function setRelatedEntities($relatedEntities)
{
$this->relatedEntities = $relatedEntities;
}
public function getFilteredEntities()
{
return $this->filteredEntities;
}
public function setFilteredEntities($filteredEntities)
{
$this->filteredEntities = $filteredEntities;
}
}
FilteredCollectionRelatedEntity
namespace AppBundle\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Groups;
/**
* @ApiResource(attributes={"normalization_context"={"groups"={"get"}}})
* @ORM\Entity()
*/
class FilteredCollectionRelatedEntity
{
/**
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
* @ORM\Column(type="integer")
* @Groups({"get"})
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\RelatedEntity", inversedBy="relatedEntites")
*/
protected $relatedEntity;
/**
* @ORM\Column(type="integer")
* @Groups({"get"})
*/
protected $value;
/**
* @ORM\Column(type="boolean")
* @Groups({"get"})
*/
protected $condition;
public function getId()
{
return $this->id;
}
public function getRelatedEntity()
{
return $this->relatedEntity;
}
public function setRelatedEntity($relatedEntity)
{
$this->relatedEntity = $relatedEntity;
}
public function getValue()
{
return $this->value;
}
public function setValue($value)
{
$this->value = $value;
}
public function getCondition()
{
return $this->condition;
}
public function setCondition($condition)
{
$this->condition = $condition;
}
}
Doctrine Post Load Event的事件订阅者:
namespace AppBundle\EventSubscriber;
use AppBundle\Entity\EntityWithFilteredCollection;
use AppBundle\Entity\FilteredCollectionRelatedEntity;
use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
class FilterCollectionSubscriber implements EventSubscriber
{
/** @var RequestStack */
private $requestStack;
public function __construct(TokenStorage $tokenStorage, RequestStack $requestStack)
{
$this->tokenStorage = $tokenStorage;
$this->requestStack = $requestStack;
}
public function postLoad(LifecycleEventArgs $event)
{
$entity = $event->getEntity();
$method = $this->requestStack->getCurrentRequest()->getMethod();
if (!$entity instanceof EntityWithFilteredCollection || Request::METHOD_GET !== $method) {
return;
}
$entity->setFilteredEntities($entity->getRelatedEntities()->filter(function (FilteredCollectionRelatedEntity $entity) {
return $entity->getCondition();
}));
}
/**
* Returns an array of events this subscriber wants to listen to.
*
* @return array
*/
public function getSubscribedEvents()
{
return [
'postLoad'
];
}
}
当我尝试检索一个EntityWithFilteredCollection时,它有一些FilteredCollectionRelatedEntity实体,其条件值设置为true,我得到以下异常:
No resource class found for object of type "AppBundle\Entity\FilteredCollectionRelatedEntity"
我走错了路吗?我错过了什么吗? 当我没有尝试序列化已过滤的集合但原始的集合可行时,但我得到了所有实体。
答案 0 :(得分:0)
您应该使用自定义API平台的过滤器而不是Doctrine监听器:https://api-platform.com/docs/core/filters#creating-custom-filters
实现起来更容易,执行速度更快(数据将在DBMS端而不是PHP端进行过滤)。