Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[HttpKernel] Replace ArgumentValueResolverInterface by ValueResolverInterface #47363

Merged
merged 1 commit into from Aug 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions UPGRADE-6.2.md
Expand Up @@ -14,6 +14,11 @@ HttpFoundation

* Deprecate `Request::getContentType()`, use `Request::getContentTypeFormat()` instead

HttpKernel
----------

* Deprecate `ArgumentValueResolverInterface`, use `ValueResolverInterface` instead

Ldap
----

Expand Down
101 changes: 28 additions & 73 deletions src/Symfony/Bridge/Doctrine/ArgumentResolver/EntityValueResolver.php
Expand Up @@ -19,7 +19,7 @@
use Symfony\Bridge\Doctrine\Attribute\MapEntity;
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface;
use Symfony\Component\HttpKernel\Controller\ValueResolverInterface;
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

Expand All @@ -29,7 +29,7 @@
* @author Fabien Potencier <fabien@symfony.com>
* @author Jérémy Derussé <jeremy@derusse.com>
*/
final class EntityValueResolver implements ArgumentValueResolverInterface
final class EntityValueResolver implements ValueResolverInterface
{
public function __construct(
private ManagerRegistry $registry,
Expand All @@ -41,66 +41,36 @@ public function __construct(
/**
* {@inheritdoc}
*/
public function supports(Request $request, ArgumentMetadata $argument): bool
public function resolve(Request $request, ArgumentMetadata $argument): array
{
if (!$this->registry->getManagerNames()) {
return false;
}

$options = $this->getMapEntityAttribute($argument);
if (!$options->class || $options->disabled) {
return false;
}

if (null === $options->expr && !($options->mapping || $options->exclude) && null === $this->getIdentifier($request, $options, $argument->getName())) {
return false;
}

// Doctrine Entity?
if (!$objectManager = $this->getManager($options->objectManager, $options->class)) {
return false;
return [];
}

if ($objectManager->getMetadataFactory()->isTransient($options->class)) {
return false;
if (!$manager = $this->getManager($options->objectManager, $options->class)) {
return [];
}

return null !== $options->expr || $this->getCriteria($request, $options, $objectManager);
}

/**
* {@inheritdoc}
*/
public function resolve(Request $request, ArgumentMetadata $argument): iterable
{
$options = $this->getMapEntityAttribute($argument);
$name = $argument->getName();
$objectManager = $this->getManager($options->objectManager, $options->class);

$errorMessage = null;
$message = '';
if (null !== $options->expr) {
if (null === $object = $this->findViaExpression($objectManager, $request, $options)) {
$errorMessage = sprintf('The expression "%s" returned null', $options->expr);
if (null === $object = $this->findViaExpression($manager, $request, $options)) {
$message = sprintf(' The expression "%s" returned null.', $options->expr);
}
// find by identifier?
} elseif (false === $object = $this->find($objectManager, $request, $options, $name)) {
} elseif (false === $object = $this->find($manager, $request, $options, $argument->getName())) {
// find by criteria
if (false === $object = $this->findOneBy($objectManager, $request, $options)) {
if (!$argument->isNullable()) {
throw new \LogicException(sprintf('Unable to guess how to get a Doctrine instance from the request information for parameter "%s".', $name));
}

if (!$criteria = $this->getCriteria($request, $options, $manager)) {
return [];
}
try {
$object = $manager->getRepository($options->class)->findOneBy($criteria);
} catch (NoResultException|ConversionException) {
$object = null;
}
}

if (null === $object && !$argument->isNullable()) {
$message = sprintf('"%s" object not found by the "%s" Argument Resolver.', $options->class, self::class);
if ($errorMessage) {
$message .= ' '.$errorMessage;
}

throw new NotFoundHttpException($message);
throw new NotFoundHttpException(sprintf('"%s" object not found by "%s".', $options->class, self::class).$message);
}

return [$object];
Expand All @@ -112,18 +82,16 @@ private function getManager(?string $name, string $class): ?ObjectManager
return $this->registry->getManagerForClass($class);
}

if (!isset($this->registry->getManagerNames()[$name])) {
return null;
}

try {
return $this->registry->getManager($name);
$manager = $this->registry->getManager($name);
} catch (\InvalidArgumentException) {
return null;
}

return $manager->getMetadataFactory()->isTransient($class) ? null : $manager;
}

private function find(ObjectManager $objectManager, Request $request, MapEntity $options, string $name): false|object|null
private function find(ObjectManager $manager, Request $request, MapEntity $options, string $name): false|object|null
{
if ($options->mapping || $options->exclude) {
return false;
Expand All @@ -134,15 +102,15 @@ private function find(ObjectManager $objectManager, Request $request, MapEntity
return $id;
}

if ($options->evictCache && $objectManager instanceof EntityManagerInterface) {
$cacheProvider = $objectManager->getCache();
if ($options->evictCache && $manager instanceof EntityManagerInterface) {
$cacheProvider = $manager->getCache();
if ($cacheProvider && $cacheProvider->containsEntity($options->class, $id)) {
$cacheProvider->evictEntity($options->class, $id);
}
}

try {
return $objectManager->getRepository($options->class)->find($id);
return $manager->getRepository($options->class)->find($id);
} catch (NoResultException|ConversionException) {
return null;
}
Expand Down Expand Up @@ -179,20 +147,7 @@ private function getIdentifier(Request $request, MapEntity $options, string $nam
return false;
}

private function findOneBy(ObjectManager $objectManager, Request $request, MapEntity $options): false|object|null
{
if (!$criteria = $this->getCriteria($request, $options, $objectManager)) {
return false;
}

try {
return $objectManager->getRepository($options->class)->findOneBy($criteria);
} catch (NoResultException|ConversionException) {
return null;
}
}

private function getCriteria(Request $request, MapEntity $options, ObjectManager $objectManager): array
private function getCriteria(Request $request, MapEntity $options, ObjectManager $manager): array
{
if (null === $mapping = $options->mapping) {
$mapping = $request->attributes->keys();
Expand All @@ -217,7 +172,7 @@ private function getCriteria(Request $request, MapEntity $options, ObjectManager
}

$criteria = [];
$metadata = $objectManager->getClassMetadata($options->class);
$metadata = $manager->getClassMetadata($options->class);

foreach ($mapping as $attribute => $field) {
if (!$metadata->hasField($field) && (!$metadata->hasAssociation($field) || !$metadata->isSingleValuedAssociation($field))) {
Expand All @@ -234,13 +189,13 @@ private function getCriteria(Request $request, MapEntity $options, ObjectManager
return $criteria;
}

private function findViaExpression(ObjectManager $objectManager, Request $request, MapEntity $options): ?object
private function findViaExpression(ObjectManager $manager, Request $request, MapEntity $options): ?object
{
if (!$this->expressionLanguage) {
throw new \LogicException(sprintf('You cannot use the "%s" if the ExpressionLanguage component is not available. Try running "composer require symfony/expression-language".', __CLASS__));
}

$repository = $objectManager->getRepository($options->class);
$repository = $manager->getRepository($options->class);
$variables = array_merge($request->attributes->all(), ['repository' => $repository]);

try {
Expand Down