Skip to content

Instantly share code, notes, and snippets.

@zanbaldwin
Last active February 11, 2022 16:48
Show Gist options
  • Save zanbaldwin/94737c67f4fa56e4e0abf9d721f44fc2 to your computer and use it in GitHub Desktop.
Save zanbaldwin/94737c67f4fa56e4e0abf9d721f44fc2 to your computer and use it in GitHub Desktop.
This will be useful at some point.
<?php declare(strict_types=1);
namespace App\Request\ArgumentResolver;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface;
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class DoctrineArgumentResolver implements ArgumentValueResolverInterface
{
public function __construct(
private readonly ?ManagerRegistry $registry = null,
) {
}
public function supports(Request $request, ArgumentMetadata $argument): bool
{
// If there is no manager, only Doctrine DBAL is configured. And we're only working with Doctrine entities,
// which are objects, which we expect to be managed by an entity manager.
if ($argument->isVariadic()
|| null === $this->registry
|| !class_exists($argument->getType(), false)
|| null === $entityManager = $this->registry->getManagerForClass($argument->getType())
) {
return false;
}
if (!$argument->isNullable()
&& (!$argument->hasDefaultValue() || $argument->getDefaultValue() === null)
&& $request->attributes->get($argument->getName()) === null
) {
return false;
}
return !$entityManager->getMetadataFactory()->isTransient($argument->getType());
}
public function resolve(Request $request, ArgumentMetadata $argument): iterable
{
try {
$argumentValue = $request->attributes->get($argument->getName()) ?? $argument->getDefaultValue();
} catch (\LogicException) {
$argumentValue = null;
}
$entityRepository = $this->registry
->getManagerForClass($argument->getType())
->getRepository($argument->getType());
$entity = $entityRepository->find($argumentValue)
?? $entityRepository->findOneBy([$argument->getName() => $argumentValue]);
if ($entity === null && !$argument->isNullable()) {
throw new NotFoundHttpException(sprintf('Doctrine entity "%s" not found.', $argument->getType()));
}
yield $entity;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment