From 199445c061aac9aa77294d3861c11ca10a77a94b Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Wed, 4 Jul 2018 10:23:19 +0200 Subject: [PATCH] Refine the search REST ressource. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Benoit --- composer.json | 1 + composer.lock | 88 ++++++++++++++++++++++++++++- config/packages/fos_rest.yaml | 1 + src/Controller/PersonController.php | 35 ++++++++---- symfony.lock | 6 ++ tests/curl.txt | 4 +- 6 files changed, 122 insertions(+), 13 deletions(-) diff --git a/composer.json b/composer.json index dc517c3..323da99 100644 --- a/composer.json +++ b/composer.json @@ -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": { diff --git a/composer.lock b/composer.lock index 5443fa3..65d3cce 100644 --- a/composer.lock +++ b/composer.lock @@ -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", @@ -3477,6 +3477,92 @@ "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", diff --git a/config/packages/fos_rest.yaml b/config/packages/fos_rest.yaml index 18a74b1..a1f7913 100644 --- a/config/packages/fos_rest.yaml +++ b/config/packages/fos_rest.yaml @@ -34,3 +34,4 @@ fos_rest: regex: '/(v|version)=(?P[0-9\.]+)/' serializer: serialize_null: true + param_fetcher_listener : true diff --git a/src/Controller/PersonController.php b/src/Controller/PersonController.php index 6b41205..0b7a7d5 100644 --- a/src/Controller/PersonController.php +++ b/src/Controller/PersonController.php @@ -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; diff --git a/symfony.lock b/symfony.lock index 296c0d1..e4b43b2 100644 --- a/symfony.lock +++ b/symfony.lock @@ -191,6 +191,9 @@ "ref": "cda8b550123383d25827705d05a42acf6819fe4e" } }, + "symfony/security": { + "version": "v4.1.1" + }, "symfony/security-bundle": { "version": "3.3", "recipe": { @@ -239,6 +242,9 @@ "ref": "f75ac166398e107796ca94cc57fa1edaa06ec47f" } }, + "symfony/validator": { + "version": "v4.1.1" + }, "symfony/web-server-bundle": { "version": "3.3", "recipe": { diff --git a/tests/curl.txt b/tests/curl.txt index 7e14731..821b938 100644 --- a/tests/curl.txt +++ b/tests/curl.txt @@ -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 -- 2.34.1