From 3e85529468afefed677572aa4e7daf41f15d3e26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 13 May 2021 17:25:24 +0200 Subject: [PATCH] add route for comment + track update/creation of entities --- .../Event/TrackCreateUpdateSubscriber.php | 62 ++++++++++++ .../Doctrine/Model/TrackCreationInterface.php | 12 +++ .../Doctrine/Model/TrackUpdateInterface.php | 12 +++ .../ChillMainBundle/config/services.yaml | 6 ++ .../AccompanyingCourseApiController.php | 5 + .../ChillPersonExtension.php | 14 ++- .../Entity/AccompanyingPeriod.php | 6 +- .../Entity/AccompanyingPeriod/Comment.php | 22 ++++- .../ChillPersonBundle/chill.api.specs.yaml | 94 +++++++++++++++++++ 9 files changed, 229 insertions(+), 4 deletions(-) create mode 100644 src/Bundle/ChillMainBundle/Doctrine/Event/TrackCreateUpdateSubscriber.php create mode 100644 src/Bundle/ChillMainBundle/Doctrine/Model/TrackCreationInterface.php create mode 100644 src/Bundle/ChillMainBundle/Doctrine/Model/TrackUpdateInterface.php diff --git a/src/Bundle/ChillMainBundle/Doctrine/Event/TrackCreateUpdateSubscriber.php b/src/Bundle/ChillMainBundle/Doctrine/Event/TrackCreateUpdateSubscriber.php new file mode 100644 index 000000000..222ed2213 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Doctrine/Event/TrackCreateUpdateSubscriber.php @@ -0,0 +1,62 @@ +security = $security; + } + + /** + * {@inheritDoc} + */ + public function getSubscribedEvents() + { + return [ + Events::prePersist, + Events::preUpdate + ]; + } + + public function prePersist(LifecycleEventArgs $args): void + { + $object = $args->getObject(); + + if ($object instanceof TrackCreationInterface) { + $object->setCreatedBy($this->security->getUser()); + $object->setCreatedAt(new \DateTimeImmutable('now')); + } + + $this->onUpdate($object); + } + + public function preUpdate(LifecycleEventArgs $args): void + { + $object = $args->getObject(); + + $this->onUpdate($object); + } + + protected function onUpdate(object $object): void + { + if ($object instanceof TrackUpdateInterface) { + $object->setUpdatedBy($this->security->getUser()); + $object->setUpdatedAt(new \DateTimeImmutable('now')); + } + } +} diff --git a/src/Bundle/ChillMainBundle/Doctrine/Model/TrackCreationInterface.php b/src/Bundle/ChillMainBundle/Doctrine/Model/TrackCreationInterface.php new file mode 100644 index 000000000..192d4e7a9 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Doctrine/Model/TrackCreationInterface.php @@ -0,0 +1,12 @@ +addRemoveSomething('resource', $id, $request, $_format, 'resource', Resource::class); } + public function commentApi($id, Request $request, string $_format): Response + { + return $this->addRemoveSomething('comment', $id, $request, $_format, 'comment', Comment::class); + } public function requestorApi($id, Request $request, string $_format): Response { diff --git a/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php b/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php index 7c54ad90f..cda8f0a81 100644 --- a/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php +++ b/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php @@ -354,6 +354,18 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac Request::METHOD_DELETE=> \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE ] ], + 'comment' => [ + 'methods' => [ + Request::METHOD_POST => true, + Request::METHOD_DELETE => true, + Request::METHOD_GET => false, + Request::METHOD_HEAD => false, + ], + 'roles' => [ + Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE, + Request::METHOD_DELETE=> \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE + ] + ], 'requestor' => [ 'methods' => [ Request::METHOD_POST => true, @@ -389,7 +401,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac ] ], ] - ] + ], ] ]); } diff --git a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php index dab4b1b71..65699f7c4 100644 --- a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php +++ b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php @@ -117,7 +117,9 @@ class AccompanyingPeriod * @var Collection * * @ORM\OneToMany(targetEntity="Chill\PersonBundle\Entity\AccompanyingPeriod\Comment", - * mappedBy="accompanyingPeriod" + * mappedBy="accompanyingPeriod", + * cascade={"persist", "remove"}, + * orphanRemoval=true * ) * @Groups({"read"}) */ @@ -350,12 +352,14 @@ class AccompanyingPeriod public function addComment(Comment $comment): self { $this->comments[] = $comment; + $comment->setAccompanyingPeriod($this); return $this; } public function removeComment(Comment $comment): void { + $comment->setAccompanyingPeriod(null); $this->comments->removeElement($comment); } diff --git a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/Comment.php b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/Comment.php index e8ecf3248..0a6ee1400 100644 --- a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/Comment.php +++ b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/Comment.php @@ -26,17 +26,25 @@ use Chill\PersonBundle\Repository\AccompanyingPeriod\CommentRepository; use Chill\MainBundle\Entity\User; use Chill\PersonBundle\Entity\AccompanyingPeriod; use Doctrine\ORM\Mapping as ORM; +use Symfony\Component\Serializer\Annotation\Groups; +use Symfony\Component\Serializer\Annotation\DiscriminatorMap; +use Chill\MainBundle\Doctrine\Model\TrackCreationInterface; +use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface; /** * @ORM\Entity(repositoryClass=CommentRepository::class) * @ORM\Table(name="chill_person_accompanying_period_comment") + * @DiscriminatorMap(typeProperty="type", mapping={ + * "accompanying_period_comment"=Comment::class + * }) */ -class Comment +class Comment implements TrackCreationInterface, TrackUpdateInterface { /** * @ORM\Id * @ORM\GeneratedValue * @ORM\Column(type="integer") + * @Groups({"read"}) */ private $id; @@ -51,27 +59,32 @@ class Comment /** * @ORM\ManyToOne(targetEntity=User::class) * @ORM\JoinColumn(nullable=false) + * @Groups({"read"}) */ private $creator; /** * @ORM\Column(type="datetime") + * @Groups({"read"}) */ private $createdAt; /** * @ORM\Column(type="datetime") + * @Groups({"read"}) */ private $updatedAt; /** * @ORM\ManyToOne(targetEntity=User::class) * @ORM\JoinColumn(nullable=false) + * @Groups({"read"}) */ private $updatedBy; /** * @ORM\Column(type="text") + * @Groups({"read", "write"}) */ private $content; @@ -104,6 +117,11 @@ class Comment return $this; } + public function setCreatedBy(User $user): self + { + return $this->setCreator($user); + } + public function getCreatedAt(): ?\DateTimeInterface { return $this->createdAt; @@ -133,7 +151,7 @@ class Comment return $this->updatedBy; } - public function setUpdatedBy(?User $updatedBy): self + public function setUpdatedBy(User $updatedBy): self { $this->updatedBy = $updatedBy; diff --git a/src/Bundle/ChillPersonBundle/chill.api.specs.yaml b/src/Bundle/ChillPersonBundle/chill.api.specs.yaml index e6029c366..fed3ddf6f 100644 --- a/src/Bundle/ChillPersonBundle/chill.api.specs.yaml +++ b/src/Bundle/ChillPersonBundle/chill.api.specs.yaml @@ -92,6 +92,31 @@ components: required: - id - type + Comment: + type: object + properties: + type: + type: string + enum: + - 'accompanying_period_comment' + readOnly: true + id: + type: integer + readOnly: true + content: + type: string + CommentById: + type: object + properties: + id: + type: integer + type: + type: string + enum: + - 'accompanying_period_comment' + required: + - id + - type paths: /1.0/person/accompanying-course/{id}.json: @@ -345,3 +370,72 @@ paths: description: "OK" 422: description: "object with validation errors" + + /1.0/person/accompanying-course/{id}/comment.json: + post: + tags: + - person + summary: "Add a comment to the accompanying course" + parameters: + - name: id + in: path + required: true + description: The accompanying period's id + schema: + type: integer + format: integer + minimum: 1 + requestBody: + description: "A comment" + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Comment' + examples: + a single comment: + summary: "a simple comment" + value: + type: accompanying_period_comment + content: | + This is a funny comment I would like to share with you. + + Thank you for reading this ! + responses: + 401: + description: "Unauthorized" + 404: + description: "Not found" + 200: + description: "OK" + 422: + description: "object with validation errors" + delete: + tags: + - person + summary: "Remove the resource" + parameters: + - name: id + in: path + required: true + description: The accompanying period's id + schema: + type: integer + format: integer + minimum: 1 + requestBody: + description: "A resource" + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CommentById' + responses: + 401: + description: "Unauthorized" + 404: + description: "Not found" + 200: + description: "OK" + 422: + description: "object with validation errors"