Как использовать несколько маршрутов и несколько параметров с Symfony - PullRequest
0 голосов
/ 18 мая 2018

Можно ли использовать ParamConverter с разными классами в зависимости от вызываемого маршрута?Допустим, у меня есть родительский класс Food с двумя детьми Fruit класс и Vegetable класс.

Я хотел бы иметь возможность сделать что-то вроде этого:

    /**
     *
     * @Route("fruit/{id}", name="fruit_show")
     * @ParamConverter("food", class="AppBundle:Fruit")
     * @Route("vegetable/{id}", name="vegetable_show")
     * @ParamConverter("food", class="AppBundle:Vegetable")
     */
     public function showAction(Food $food)
     { ... }

Ответы [ 2 ]

0 голосов
/ 19 мая 2018

Кажется, что невозможно сделать именно то, что вы хотите.Но может быть возможно получить то, что вам нужно, с помощью двух простых действий оболочки.Вам даже не понадобится явная аннотация @ParamConverter.Например,

/**
 *
 * @Route("fruit/{id}", name="fruit_show")
 */
 public function showFruitAction(Fruit $fruit)
 { 
    return $this->showAction($fruit)
 }

/**
 *
 * @Route("vegetable/{id}", name="vegetable_show")
 */
 public function showVegetableAction(Food $food)
 { 
    return $this->showAction($vegetable)
 }


public function showAction (Food $food)
{ ... }
0 голосов
/ 18 мая 2018

Проблема, которую я обнаружил, заключается в том, что ParamConverter использует последний элемент в аннотациях.Если он соответствует маршруту fruit_show, переменная $ food является экземпляром класса AppBundle: Vegetable.То же самое, если он совпадает с маршрутом vegetable_show.

class FoodController
{
    /**
     * @Route("/items/fruits/{id}", methods={"GET"}, name="fruits_show")
     * @ParamConverter("food", class="AppBundle:Fruit")
     * @Route("/items/vegetables/{id}", methods={"GET"}, name="vegetables_show")
     * @ParamConverter("food", class="AppBundle:Vegetable")
     */
    public function foodAction(Request $request, $food)
    {
        //
    }
}

Один из способов, который вы можете использовать, - это написать собственный ParamConverter:

use Doctrine\ORM\EntityManagerInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter\ParamConverterInterface;
use Symfony\Component\HttpFoundation\Request;

class FoodConverter implements ParamConverterInterface
{
    protected $entityManager;

    public function __construct(EntityManagerInterface $entityManager)
    {
        $this->entityManager = $entityManager;
    }

    public function apply(Request $request, ParamConverter $configuration)
    {
        $id = $request->get('id');
        $route = $request->get('_route');
        $class = $configuration->getOptions()[$route];

        $request->attributes->set($configuration->getName(), $this->entityManager->getRepository($class)->findOneById($id));

        return true;
    }

    public function supports(ParamConverter $configuration)
    {
        return $configuration->getName() === 'food';
    }
}

Добавление его вваши услуги:

services:
    food_converter:
        class: App\SupportClasses\FoodConverter
        arguments: ['@doctrine.orm.entity_manager']
        tags:
            - {name: request.param_converter, priority: -2, converter: food_converter}

Используя это так:

class FoodController
{

    /**
     * @Route("/items/fruits/{id}", methods={"GET"}, name="fruits_show")
     * @Route("/items/vegetables/{id}", methods={"GET"}, name="vegetables_show")
     * @ParamConverter("food", converter = "food_converter" class="App:Food", options={"fruits_show" = "App:Fruit", "vegetables_show" = "App:Vegetable"})
     */
    public function foodAction(Request $request, $food)
    {
        var_dump($food);
        exit();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...