Как использовать DoctrineParamConverter из класса Object Transformer Object для запроса? - PullRequest
0 голосов
/ 20 сентября 2019

Я начну говорить, что я использую Symfony 4.3.4 и Api Platform (теперь называется AP).Сказав, что так выглядит мой пользовательский контроллер (используемый для AP):

declare(strict_types=1);

namespace App\Controller\CaseWork\Pend;

use App\Request\PendCaseRequest;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Component\Routing\Annotation\Route;

class PendCaseController
{
    /**
     * @Route("/myroute/{id}/pend", name="routeName")
     * @ParamConverter("case", class="App\Entity\Cases")
     */
    public function __invoke(PendCaseRequest $request, int $id)
    {
        // do something with the $request
    }
}

Как вы можете заметить, у меня также есть объект Data Data Transformer, и вот фрагмент кода для него:

declare(strict_types=1);

namespace App\Request;

use App\Interfaces\RequestDTOInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Validator\Constraints as Assert;

class PendCaseRequest implements RequestDTOInterface
{
    /**
     * @var int
     *
     * @Assert\NotBlank()
     * @Assert\NotNull()
     * @Assert\Type("integer")
     */
    private $param;

    public function __construct(Request $request)
    {
        $data = json_decode($request->getContent(), true);
        $this->param = (int) $data['param'];
        // ...
    }
}

Предполагается (согласно документам здесь ), что, когда поступит запрос и найден id, соответствующий App\Entity\Cases, новый атрибут с именем case должен быть добавлен к моему $request объект, но в моем сценарии не происходит, и я не уверен, почему или чего мне не хватает.

При отладке и установке точки останова на этой строке $this->param = (int) $data['param']; в моем DTO, если я распечатаю $this->attributes, я получаю следующий вывод:

‌Symfony\Component\HttpFoundation\ParameterBag::__set_state(array(
   'parameters' => 
  array (
  ),
))

Чего мне здесь не хватает?Что не так с моим подходом?

1 Ответ

0 голосов
/ 23 сентября 2019

Я нашел "решение" здесь .В итоге я использую Decorator, как подсказывает ответ на этот пост.

Мой основной контроллер изменился на:

declare(strict_types=1);

namespace App\Controller\CaseWork\Pend;

use App\Request\PendCaseRequest;
use App\Entity\Cases;

class PendCaseController
{
    public function __invoke(PendCaseRequest $request, Cases $case)
    {
        // do something with the $request
    }
}

Создан декоратор:

declare(strict_types=1);

namespace App\Decorator;

use App\Controller\CaseWork\Pend\PendCaseController;
use Doctrine\ORM\EntityManagerInterface;
use App\Entity\Cases;
use App\Request\PendCaseRequest;

class PendCaseDecorator
{
    /** @var PendCaseController */
    protected $decoratedController;

    /** @var EntityManagerInterface */
    protected $entityManager;

    public function __construct(PendCaseController $controller, EntityManagerInterface $entityManager)
    {
        $this->decoratedController = $controller;
        $this->entityManager = $entityManager;
    }

    public function __invoke(PendCaseRequest $request, int $id)
    {
        $object = $this->entityManager->getRepository(Cases::class)->find($id);
        if (!$object instanceof Cases) {
            throw new NotFoundHttpException('Entity with '.$id.' not found');
        }

        return $this->decoratedController($request, $object);
    }
}

И я зарегистрировал его в services.yml:

services:
    App\Controller\CaseWork\Pend\PendCaseController: ~
    App\Decorator\PendCaseDecorator:
        decorates: App\Controller\CaseWork\Pend\PendCaseController

Таким образом я продолжаю использовать свой DTO и возвращаю Cases объект сущности.

...