Symfony create custom ParamConverter
Introduction
This article is who using symfony and faced wasn’t enough ParamConverter basic possibility
When I want to get from database only active data. I always check data after fetch from DB in my controller, it was seem very bad practice for me, and I decided check active condition while getting data and did following way
namespace App\Convertor;
use App\Repository\TechnicalCardRepository;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter\ParamConverterInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class TechnicalCardParamConvertor implements ParamConverterInterface
{
private TechnicalCardRepository $technicalCardRepository;
public function __construct(
TechnicalCardRepository $technicalCardRepository
)
{
$this->technicalCardRepository = $technicalCardRepository;
}
public function apply(Request $request, ParamConverter $configuration)
{
$technicalCard = $this->technicalCardRepository->findOneBy([
'id' => $request->attributes->getInt($configuration->getName()),
'active' => true
]);
if ($technicalCard == null) {
throw new NotFoundHttpException("Technical card not found or inactive");
}
$request->attributes->set($configuration->getName(), $technicalCard);
}
public function supports(ParamConverter $configuration)
{
return basename(str_replace('\\', '/', $configuration->getClass())) == 'TechnicalCard';
}
}
/**
* @Rest\Get("technical-cards/{technicalCard}", requirements={"technicalCard" = "\d+"})
*/
public function show(TechnicalCard $technicalCard): Response
{
return $this->response($technicalCard); // there is object will be only active
}
There is above example I have created my own ParamConverter and implemented from ParamConverterInterface which have two abstract methods, and override those methods
- supports is return true it means apply method will be call. In my case I want to use this convertor for whole Entity that why I checked the class name
- apply this method will call if supports result is true, in my case I want to get only active data, you can put there any condition, if those condition not find any data I can throw exception