1

我正在为我的网站使用 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 事件的事件订阅者:

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"

我走错路了吗?我错过了什么吗?当我不尝试序列化过滤后的集合但原始集合时它可以工作,但我得到了所有实体。

4

1 回答 1

1

您应该使用自定义 API 平台的过滤器而不是 Doctrine 侦听器:https ://api-platform.com/docs/core/filters#creating-custom-filters

它将更容易实现和更快地执行(数据将在 DBMS 端而不是 PHP 端进行过滤)。

于 2017-05-15T11:54:55.440 回答