From 061a7dd53789f036b42603722a89205523766a1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 11 May 2021 15:04:48 +0200 Subject: [PATCH] patch request for accompanying period --- .../Controller/AbstractCRUDController.php | 7 +- .../CRUD/Controller/ApiController.php | 89 ++++++++++++++++++- .../DependencyInjection/Configuration.php | 2 + .../ChillPersonExtension.php | 9 +- .../ChillPersonBundle/chill.api.specs.yaml | 34 +++++++ 5 files changed, 138 insertions(+), 3 deletions(-) diff --git a/src/Bundle/ChillMainBundle/CRUD/Controller/AbstractCRUDController.php b/src/Bundle/ChillMainBundle/CRUD/Controller/AbstractCRUDController.php index b5c935c76..df7d065cb 100644 --- a/src/Bundle/ChillMainBundle/CRUD/Controller/AbstractCRUDController.php +++ b/src/Bundle/ChillMainBundle/CRUD/Controller/AbstractCRUDController.php @@ -5,7 +5,7 @@ namespace Chill\MainBundle\CRUD\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Validator\Validator\ValidatorInterface; use Chill\MainBundle\Pagination\PaginatorFactory; use Chill\MainBundle\Pagination\PaginatorInterface; @@ -229,4 +229,9 @@ class AbstractCRUDController extends AbstractController { return $this->container->get('chill_main.paginator_factory'); } + + protected function getValidator(): ValidatorInterface + { + return $this->get('validator'); + } } diff --git a/src/Bundle/ChillMainBundle/CRUD/Controller/ApiController.php b/src/Bundle/ChillMainBundle/CRUD/Controller/ApiController.php index 7643db0e9..1d00a2a1a 100644 --- a/src/Bundle/ChillMainBundle/CRUD/Controller/ApiController.php +++ b/src/Bundle/ChillMainBundle/CRUD/Controller/ApiController.php @@ -8,6 +8,8 @@ use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Serializer\SerializerInterface; use Chill\MainBundle\Serializer\Model\Collection; use Chill\MainBundle\Pagination\PaginatorInterface; +use Symfony\Component\Serializer\Normalizer\AbstractNormalizer; +use Symfony\Component\Validator\ConstraintViolationListInterface; class ApiController extends AbstractCRUDController { @@ -81,13 +83,98 @@ class ApiController extends AbstractCRUDController { switch ($request->getMethod()) { case Request::METHOD_GET: - case REQUEST::METHOD_HEAD: + case Request::METHOD_HEAD: return $this->entityGet('_entity', $request, $id, $_format); + case Request::METHOD_PUT: + case Request::METHOD_PATCH: + return $this->entityPut('_entity', $request, $id, $_format); default: throw new \Symfony\Component\HttpFoundation\Exception\BadRequestException("This method is not implemented"); } } + public function entityPut($action, Request $request, $id, string $_format): Response + { + $entity = $this->getEntity($action, $id, $request, $_format); + + $postFetch = $this->onPostFetchEntity($action, $request, $entity, $_format); + + if ($postFetch instanceof Response) { + return $postFetch; + } + + if (NULL === $entity) { + throw $this->createNotFoundException(sprintf("The %s with id %s " + . "is not found", $this->getCrudName(), $id)); + } + + $response = $this->checkACL($action, $request, $_format, $entity); + if ($response instanceof Response) { + return $response; + } + + $response = $this->onPostCheckACL($action, $request, $_format, $entity); + if ($response instanceof Response) { + return $response; + } + + $response = $this->onBeforeSerialize($action, $request, $_format, $entity); + if ($response instanceof Response) { + return $response; + } + + $entity = $this->deserialize($action, $request, $_format, $entity); + $errors = $this->validate($action, $request, $_format, $entity); + + $response = $this->onAfterValidation($action, $request, $_format, $entity, $errors); + if ($response instanceof Response) { + return $response; + } + + if ($errors->count() > 0) { + $response = $this->json($errors); + $response->setStatusCode(Response::HTTP_UNPROCESSABLE_ENTITY); + + return $response; + } + + return $this->json($entity); + } + + protected function onAfterValidation(string $action, Request $request, string $_format, $entity, ConstraintViolationListInterface $errors): ?Response + { + return null; + } + + protected function getValidationGroups(string $action, Request $request, string $_format, $entity): ?array + { + return null; + } + + protected function validate(string $action, Request $request, string $_format, $entity): ConstraintViolationListInterface + { + $validationGroups = $this->getValidationGroups($action, $request, $_format, $entity); + + return $this->getValidator()->validate($entity, null, $validationGroups); + } + + protected function deserialize(string $action, Request $request, string $_format, $entity = null): object + { + $default = []; + + if (NULL !== $entity) { + $default[AbstractNormalizer::OBJECT_TO_POPULATE] = $entity; + } + + $context = \array_merge( + $default, + $this->getContextForSerialization($action, $request, $_format, $entity) + ); + + return $this->getSerializer()->deserialize($request->getContent(), $this->getEntityClass(), $_format, $context); + } + + /** * Base action for indexing entities */ diff --git a/src/Bundle/ChillMainBundle/DependencyInjection/Configuration.php b/src/Bundle/ChillMainBundle/DependencyInjection/Configuration.php index c7e4c00ef..4c90aaabb 100644 --- a/src/Bundle/ChillMainBundle/DependencyInjection/Configuration.php +++ b/src/Bundle/ChillMainBundle/DependencyInjection/Configuration.php @@ -221,6 +221,7 @@ class Configuration implements ConfigurationInterface ->booleanNode(Request::METHOD_POST)->defaultFalse()->end() ->booleanNode(Request::METHOD_DELETE)->defaultFalse()->end() ->booleanNode(Request::METHOD_PUT)->defaultFalse()->end() + ->booleanNode(Request::METHOD_PATCH)->defaultFalse()->end() ->end() ->end() ->arrayNode('roles') @@ -232,6 +233,7 @@ class Configuration implements ConfigurationInterface ->scalarNode(Request::METHOD_POST)->defaultNull()->end() ->scalarNode(Request::METHOD_DELETE)->defaultNull()->end() ->scalarNode(Request::METHOD_PUT)->defaultNull()->end() + ->scalarNode(Request::METHOD_PATCH)->defaultNull()->end() ->end() ->end() ->end() diff --git a/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php b/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php index 6fa58adac..230207f6b 100644 --- a/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php +++ b/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php @@ -320,7 +320,14 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac 'actions' => [ '_entity' => [ 'roles' => [ - Request::METHOD_GET => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE + Request::METHOD_GET => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE, + Request::METHOD_PATCH => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE, + Request::METHOD_PUT => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE, + ], + 'methods' => [ + Request::METHOD_GET => true, + Request::METHOD_PUT => true, + Request::METHOD_PATCH => true, ] ], 'participation' => [ diff --git a/src/Bundle/ChillPersonBundle/chill.api.specs.yaml b/src/Bundle/ChillPersonBundle/chill.api.specs.yaml index 0713afd8d..dfb7752f5 100644 --- a/src/Bundle/ChillPersonBundle/chill.api.specs.yaml +++ b/src/Bundle/ChillPersonBundle/chill.api.specs.yaml @@ -14,6 +14,13 @@ components: type: integer required: - thirdparty_id + AccompanyingPeriod: + type: object + properties: + id: + type: integer + requestorAnonymous: + type: boolean paths: @@ -38,6 +45,33 @@ paths: description: "Not found" 200: description: "OK" + patch: + tags: + - person + summary: "Return the description for an accompanying course (accompanying period)" + parameters: + - name: id + in: path + required: true + description: The accompanying period's id + schema: + type: integer + format: integer + minimum: 1 + requestBody: + description: "An accompanying period" + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AccompanyingPeriod' + responses: + 401: + description: "Unauthorized" + 404: + description: "Not found" + 200: + description: "OK" /1.0/person/accompanying-course/{id}/requestor.json: post: tags: