Forked from artyuum/HashidsDoctrineParamConverter.php
Created
August 6, 2021 20:52
-
-
Save hriad/1f36492385ad7b8f341e80db3fd44d10 to your computer and use it in GitHub Desktop.
A ParamConverter to use HashIds with Doctrine + Symfony.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\ParamConverter; | |
use Doctrine\ORM\EntityManagerInterface; | |
use Hashids\HashidsInterface; | |
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; | |
use Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter\ParamConverterInterface; | |
use Symfony\Component\HttpFoundation\Request; | |
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; | |
use Symfony\Component\PropertyAccess\PropertyAccessorInterface; | |
use Throwable; | |
class HashidsDoctrineParamConverter implements ParamConverterInterface | |
{ | |
public function __construct( | |
private HashidsInterface $hashids, private EntityManagerInterface $entityManager, private PropertyAccessorInterface $propertyAccessor | |
) { | |
} | |
public function supports(ParamConverter $configuration) | |
{ | |
// supports by default | |
if (!isset($configuration->getOptions()['hashids_doctrine'])) { | |
return true; | |
} | |
return $configuration->getOptions()['hashids_doctrine']; | |
} | |
public function apply(Request $request, ParamConverter $configuration) | |
{ | |
$routeParams = $request->attributes->get('_route_params'); | |
$parameterName = $configuration->getName(); | |
$parameterValue = $request->attributes->get($parameterName); | |
$class = $configuration->getClass(); | |
if (!$configuration->getClass()) { | |
return; | |
} | |
// ensures that the parameter exists in the route params | |
if (!$routeParams || !in_array($parameterName, array_keys($routeParams), true)) { | |
return; | |
} | |
// ends here if the class is not an entity | |
try { | |
$repository = $this->entityManager->getRepository($class); | |
} catch (Throwable) { | |
return; | |
} | |
if (property_exists($class, $parameterName)) { | |
$entity = $repository->findOneBy([ | |
$parameterName => $parameterValue, | |
]); | |
// ends here if the entity couldn't be found | |
if (!$entity) { | |
throw new NotFoundHttpException(sprintf('%s object not found by the property "%s" with the value "%s".', $class, $parameterName, $parameterValue)); | |
} | |
// replaces the parameter value by the entity | |
$request->attributes->set($parameterName, $entity); | |
return; | |
} | |
// decodes the encoded ID | |
$decodedId = $this->hashids->decode($parameterValue); | |
// ends here if the ID couldn't be decoded | |
if (empty($decodedId)) { | |
throw new NotFoundHttpException(sprintf('The passed ID "%s" could not be decoded.', $parameterValue)); | |
} | |
$decodedId = current($decodedId); | |
$entity = $repository->find($decodedId); | |
// ends here if the entity couldn't be found | |
if (!$entity) { | |
throw new NotFoundHttpException(sprintf('%s object not found by ID: %s (%s)', $class, $decodedId, $parameterValue)); | |
} | |
// replaces the parameter value by the entity | |
$request->attributes->set($parameterName, $entity); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment