Refine the search REST ressource.
authorJérôme Benoit <jerome.benoit@piment-noir.org>
Wed, 4 Jul 2018 08:23:19 +0000 (10:23 +0200)
committerJérôme Benoit <jerome.benoit@piment-noir.org>
Wed, 4 Jul 2018 08:23:19 +0000 (10:23 +0200)
Signed-off-by: Jérôme Benoit <jerome.benoit@piment-noir.org>
composer.json
composer.lock
config/packages/fos_rest.yaml
src/Controller/PersonController.php
symfony.lock
tests/curl.txt

index dc517c346fa5dc5b16fabddf546a3a83bf71cd91..323da99856cc3712f3468cd6ae6e72b1e4cbafbf 100644 (file)
@@ -19,6 +19,7 @@
         "symfony/swiftmailer-bundle": "^3.2",
         "symfony/translation": "^4.1",
         "symfony/twig-bundle": "^4.1",
+        "symfony/validator": "^4.1",
         "symfony/yaml": "^4.1"
     },
     "require-dev": {
index 5443fa30845a99e592335c70935512c23a3853bd..65d3cce1f605904a6a40edc9b34fea7d29e44445 100644 (file)
@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
         "This file is @generated automatically"
     ],
-    "content-hash": "cb8518852a624cb243ef9a1ff48e8ba5",
+    "content-hash": "2aa00432d94d158e18e4cf3b588212b0",
     "packages": [
         {
             "name": "doctrine/annotations",
             "homepage": "https://symfony.com",
             "time": "2018-06-25T11:12:43+00:00"
         },
+        {
+            "name": "symfony/validator",
+            "version": "v4.1.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/validator.git",
+                "reference": "f2523bfd8dc5ff648aca55c0f2748674ca4661bb"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/validator/zipball/f2523bfd8dc5ff648aca55c0f2748674ca4661bb",
+                "reference": "f2523bfd8dc5ff648aca55c0f2748674ca4661bb",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.1.3",
+                "symfony/polyfill-ctype": "~1.8",
+                "symfony/polyfill-mbstring": "~1.0",
+                "symfony/translation": "~3.4|~4.0"
+            },
+            "conflict": {
+                "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0",
+                "symfony/dependency-injection": "<3.4",
+                "symfony/http-kernel": "<3.4",
+                "symfony/intl": "<4.1",
+                "symfony/yaml": "<3.4"
+            },
+            "require-dev": {
+                "doctrine/annotations": "~1.0",
+                "doctrine/cache": "~1.0",
+                "egulias/email-validator": "^1.2.8|~2.0",
+                "symfony/cache": "~3.4|~4.0",
+                "symfony/config": "~3.4|~4.0",
+                "symfony/dependency-injection": "~3.4|~4.0",
+                "symfony/expression-language": "~3.4|~4.0",
+                "symfony/http-foundation": "~4.1",
+                "symfony/http-kernel": "~3.4|~4.0",
+                "symfony/intl": "~4.1",
+                "symfony/property-access": "~3.4|~4.0",
+                "symfony/var-dumper": "~3.4|~4.0",
+                "symfony/yaml": "~3.4|~4.0"
+            },
+            "suggest": {
+                "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.",
+                "doctrine/cache": "For using the default cached annotation reader and metadata cache.",
+                "egulias/email-validator": "Strict (RFC compliant) email validation",
+                "psr/cache-implementation": "For using the metadata cache.",
+                "symfony/config": "",
+                "symfony/expression-language": "For using the Expression validator",
+                "symfony/http-foundation": "",
+                "symfony/intl": "",
+                "symfony/property-access": "For accessing properties within comparison constraints",
+                "symfony/yaml": ""
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "4.1-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Component\\Validator\\": ""
+                },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony Validator Component",
+            "homepage": "https://symfony.com",
+            "time": "2018-06-19T21:38:16+00:00"
+        },
         {
             "name": "symfony/yaml",
             "version": "v4.1.1",
index 18a74b1fe61d7361d285a24607bd94ce13bf968d..a1f7913e3978d7d6f6de4e93b3e7b025fc45b332 100644 (file)
@@ -34,3 +34,4 @@ fos_rest:
                 regex: '/(v|version)=(?P<version>[0-9\.]+)/'
     serializer:
         serialize_null: true
+    param_fetcher_listener : true
index 6b4120545ec9196498d354910457e2de92407f97..0b7a7d5c5d127e3f88c83dbaac3141c0c8da129b 100644 (file)
@@ -4,11 +4,13 @@ namespace App\Controller;
 use App\Entity\Person;
 use App\Entity\Localisation;
 use \Datetime;
+use \NotNull;
 use Symfony\Bundle\FrameworkBundle\Controller\Controller;
 use FOS\RestBundle\Controller\FOSRestController;
 use FOS\RestBundle\Controller\Annotations as Rest;
 use FOS\RestBundle\View\ViewHandler;
 use FOS\RestBundle\View\View;
+use FOS\RestBundle\Request\ParamFetcherInterface;
 use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpFoundation\Response;
@@ -38,7 +40,10 @@ class PersonController extends FOSRestController
         $em->persist($person);
         $em->flush();
 
-        return $this->view($person, Response::HTTP_CREATED, ['Location' => $this->generateUrl('show_person', ['id' => $person->getId(), UrlGeneratorInterface::ABSOLUTE_URL])]);
+        return $this->view($person, Response::HTTP_CREATED,
+                           ['Location' => $this->generateUrl('show_person',
+                           ['id' => $person->getId(),
+                           UrlGeneratorInterface::ABSOLUTE_URL])]);
     }
 
     /**
@@ -106,7 +111,10 @@ class PersonController extends FOSRestController
         $em->merge($person);
         $em->flush();
 
-        return $this->view($person, Response::HTTP_CREATED, ['Location' => $this->generateUrl('show_person', ['id' => $person->getId(), UrlGeneratorInterface::ABSOLUTE_URL])]);
+        return $this->view($person, Response::HTTP_CREATED,
+                           ['Location' => $this->generateUrl('show_person',
+                           ['id' => $person->getId(),
+                           UrlGeneratorInterface::ABSOLUTE_URL])]);
     }
 
     /**
@@ -128,7 +136,10 @@ class PersonController extends FOSRestController
         if ($request->get('password') != $person->getPassword()) {
             return $this->PersonWrongPassword();
         } else {
-            return $this->view($person, Response::HTTP_ACCEPTED, ['Location' => $this->generateUrl('show_person', ['id' => $person->getId(), UrlGeneratorInterface::ABSOLUTE_URL])]);
+            return $this->view($person, Response::HTTP_ACCEPTED,
+                               ['Location' => $this->generateUrl('show_person',
+                               ['id' => $person->getId(),
+                               UrlGeneratorInterface::ABSOLUTE_URL])]);
         }
     }
 
@@ -177,7 +188,10 @@ class PersonController extends FOSRestController
     }
 
     private function getLastLocalisation($em, $id) {
-        $query = $em->createQuery("SELECT l1 FROM App\Entity\Localisation l1 WHERE l1.person = :person and l1.timestamp = (SELECT MAX(l2.timestamp) FROM App\Entity\Localisation l2 WHERE l2.person = l1.person)");
+        $query = $em->createQuery("SELECT l1 FROM App\Entity\Localisation l1
+                                   WHERE l1.person = :person and l1.timestamp =
+                                   (SELECT MAX(l2.timestamp) FROM App\Entity\Localisation l2
+                                   WHERE l2.person = l1.person)");
         $query->setParameter('person', $id);
         $result = $query->getResult();
         if (!empty($result)) {
@@ -413,24 +427,25 @@ class PersonController extends FOSRestController
     }
 
     /**
-     * @Rest\Post(
+     * @Rest\Get(
      *     path = "/api/person/search",
      *     name = "search_person"
      * )
+     * @Rest\QueryParam(name="keyword")
      * @Rest\View()
      */
-    public function searchPerson(Request $request)
+    public function searchPerson(ParamFetcherInterface $paramFetcher)
     {
         $em = $this->getDoctrine()->getManager();
         $query = $em->createQuery("SELECT DISTINCT p FROM App\Entity\Person p WHERE
-            p.firstname LIKE :keyword or
-            p.lastname LIKE :keyword or
+            p.firstname LIKE :keyword OR
+            p.lastname LIKE :keyword OR
             p.email LIKE :keyword");
-        $query->setParameter('keyword', '%'.$request->get('keyword').'%');
+        $query->setParameter('keyword', '%'.$paramFetcher->get('keyword').'%');
         $persons = $query->getResult();
 
         if (empty($persons)) {
-            return $this->PersonNotFound();
+            return $this->PersonsNotFound();
         }
 
         return $persons;
index 296c0d1ff45bab3fd42d25f5140607ab620d427c..e4b43b222f8c20958ef38c4b61bacaba2dd9ee67 100644 (file)
             "ref": "cda8b550123383d25827705d05a42acf6819fe4e"
         }
     },
+    "symfony/security": {
+        "version": "v4.1.1"
+    },
     "symfony/security-bundle": {
         "version": "3.3",
         "recipe": {
             "ref": "f75ac166398e107796ca94cc57fa1edaa06ec47f"
         }
     },
+    "symfony/validator": {
+        "version": "v4.1.1"
+    },
     "symfony/web-server-bundle": {
         "version": "3.3",
         "recipe": {
index 7e147312b7fe458a7968f2ae43dd22790dbae3f5..821b938e69aea725f6a476ebf28c1c300fa86d92 100644 (file)
@@ -17,8 +17,8 @@ curl --request POST http://localhost:8000/api/person/1/localisation --data "{ \"
 curl --request PUT http://localhost:8000/api/person/1/online
 curl --request PUT http://localhost:8000/api/person/1/offline
 
-* Search a user with a keyword:
-curl --request POST http://localhost:8000/api/person/search --data "{ \"keyword\": \"isabelle\"}" --header "Content-Type: application/json"
+* Search a user with a keyword set to isabelle:
+curl --request GET http://localhost:8000/api/person/search?keyword=isabelle
 
 * Show a user with id 1:
 curl --request GET http://localhost:8000/api/person/1