From 1c3ed356bd1ff67cd71806efbb71511644035c85 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 24 Mar 2015 16:10:10 +0100 Subject: [PATCH] fixed logic from previous PR --- .../ParamConverter/DoctrineParamConverter.php | 38 ++++++++----------- Resources/doc/annotations/converters.rst | 7 ++-- .../DoctrineParamConverterTest.php | 2 +- 3 files changed, 20 insertions(+), 27 deletions(-) diff --git a/Request/ParamConverter/DoctrineParamConverter.php b/Request/ParamConverter/DoctrineParamConverter.php index d1ca9858..c3fb984c 100644 --- a/Request/ParamConverter/DoctrineParamConverter.php +++ b/Request/ParamConverter/DoctrineParamConverter.php @@ -90,12 +90,10 @@ protected function find($class, Request $request, $options, $name) } try { - $result = $this->getManager($options['entity_manager'], $class)->getRepository($class)->$method($id); + return $this->getManager($options['entity_manager'], $class)->getRepository($class)->$method($id); } catch (NoResultException $e) { - $result = null; + return; } - - return $result; } protected function getIdentifier(Request $request, $options, $name) @@ -177,35 +175,31 @@ protected function findOneBy($class, Request $request, $options) try { if ($mapMethodSignature) { - $result = $this->findDataByMapMethodSignature($em, $class, $repositoryMethod, $criteria); - } else { - $result = $em->getRepository($class)->$repositoryMethod($criteria); + return $this->findDataByMapMethodSignature($em, $class, $repositoryMethod, $criteria); } + + return $em->getRepository($class)->$repositoryMethod($criteria); } catch (NoResultException $e) { - $result = null; + return; } - - return $result; } private function findDataByMapMethodSignature($em, $class, $repositoryMethod, $criteria) { + $arguments = array(); $repository = $em->getRepository($class); - $repositoryClass = get_class($repository); - - $reflectionMethod = new \ReflectionMethod($repositoryClass, $repositoryMethod); - $parameters = array(); - for ($i = 0; $i < count($criteria); $i++) { - $parameterName = new \ReflectionParameter(array($repositoryClass, $repositoryMethod), $i); - $parameterName = $parameterName->name; - if (!in_array($parameterName, array_keys($criteria))) { - throw new \InvalidArgumentException(sprintf('Parameter %s in %s::%s should be "%s"!', $i + 1, $repositoryClass, $repositoryMethod, $parameterName)); + $ref = new \ReflectionMethod($repository, $repositoryMethod); + foreach ($ref->getParameters() as $parameter) { + if (array_key_exists($parameter->name, $criteria)) { + $arguments[] = $criteria[$parameter->name]; + } elseif ($parameter->isDefaultValueAvailable()) { + $arguments[] = $parameter->getDefaultValue(); + } else { + throw new \InvalidArgumentException(sprintf('Repository method "%s::%s" requires that you provide a value for the "$%s" argument.', get_class($repository), $repositoryMethod, $parameter->name)); } - - $parameters[$parameterName] = $criteria[$parameterName]; } - return $reflectionMethod->invokeArgs($repository, $parameters); + return $ref->invokeArgs($repository, $arguments); } /** diff --git a/Resources/doc/annotations/converters.rst b/Resources/doc/annotations/converters.rst index b3250c73..549ca913 100644 --- a/Resources/doc/annotations/converters.rst +++ b/Resources/doc/annotations/converters.rst @@ -183,7 +183,7 @@ methods. There are cases where you want to you use your own repository method and you want to map the criteria to the method signature. This is possible when you set -the ``map_method_signature`` option to true. The default is false. +the ``map_method_signature`` option to true. The default is false:: /** * @Route("/user/{first_name}/{last_name}") @@ -207,9 +207,8 @@ the ``map_method_signature`` option to true. The default is false. .. tip:: - With de default implementation, the ``firstName`` and ``lastName`` - parameters have to be Doctrine fields. When using ``map_method_signature``, - they don't have to be known by Doctrine. + When ``map_method_signature`` is ``true``, the ``firstName`` and + ``lastName`` parameters do not have to be Doctrine fields. DateTime Converter ~~~~~~~~~~~~~~~~~~ diff --git a/Tests/Request/ParamConverter/DoctrineParamConverterTest.php b/Tests/Request/ParamConverter/DoctrineParamConverterTest.php index 2625217d..7f1f177a 100644 --- a/Tests/Request/ParamConverter/DoctrineParamConverterTest.php +++ b/Tests/Request/ParamConverter/DoctrineParamConverterTest.php @@ -376,7 +376,7 @@ public function testApplyWithRepositoryMethodAndMapMethodSignature() /** * @expectedException InvalidArgumentException - * @expectedExceptionMessage Parameter 2 in Sensio\Bundle\FrameworkExtraBundle\Tests\Request\ParamConverter\TestUserRepository::findByFullName should be "lastName"! + * @expectedExceptionMessage Repository method "Sensio\Bundle\FrameworkExtraBundle\Tests\Request\ParamConverter\TestUserRepository::findByFullName" requires that you provide a value for the "$lastName" argument. */ public function testApplyWithRepositoryMethodAndMapMethodSignatureException() {