Symfony @ParamConverter только для активной строки

#php #symfony

Вопрос:

 product_show:
    path: /product/{id}
    controller: AppControllerProductController::show
    methods: GET
    requirements:
      id: d 
 

 <?php
declare(strict_types=1);

namespace AppEntity;

use AppRepositoryProductRepository;
use DoctrineORMMapping as ORM;

/**
 * @ORMEntity(repositoryClass=ProductRepository::class)
 */
class Product
{
    /**
     * @ORMId
     * @ORMGeneratedValue(strategy="IDENTITY")
     * @ORMColumn(type="integer")
     */
    private int $id;


    /**
     * @ORMColumn(type="boolean", options={"default": true})
     */
    private bool $active = true;

    public function getId(): int
    {
        return $this->id;
    }

    public function active(): bool
    {
        return $this->active;
    }
}
 

 <?php

namespace AppController;

use AppEntityProduct;
use SymfonyBundleFrameworkBundleControllerAbstractController;
use SymfonyComponentHttpFoundationResponse;

class ProductController extends AbstractController
{
    public function show(Product $product): Response
    {
        return $this->render('product/show.html.twig', [
            'product' => $product,
        ]);
    }
}
 

Когда $product->active() возвращает false, я хочу отправить ответ 404.

Но это должно быть сделано без добавления if в действие контроллера.

Возможно, мне следует что-то изменить в ParamConverter. Как я могу это сделать? Как я могу перезаписать поведение ParamConverter?

Комментарии:

1. преобразователь параметров позволяет вам предоставить функцию репозитория, которую следует использовать. Если вы добавите функцию репозитория, которая возвращает только активные продукты для идентификатора продукта, это должно работать нормально. однако я не вижу, чтобы вы активно использовали преобразователь параметров…

Ответ №1:

Вы можете выполнить выборку с помощью выражения и использовать пользовательскую функцию в своем репозитории.

Например:

 class ProductController extends AbstractController
{
   /**
    * @Route("/product/{product_id}")
    * @Entity("product", expr="repository.findOneActive(product_id)")
    */
    public function show(Product $product): Response
    {
        return $this->render('product/show.html.twig', [
            'product' => $product,
        ]);
    }
}
 

И в вашем продуктовом каталоге:

 class ProductRepository
{
    public function findOneActive($productId)
    {
        // your query here...
    }
}