add route for comment + track update/creation of entities

This commit is contained in:
Julien Fastré 2021-05-13 17:25:24 +02:00
parent 05798688d0
commit 3e85529468
9 changed files with 229 additions and 4 deletions

View File

@ -0,0 +1,62 @@
<?php
namespace Chill\MainBundle\Doctrine\Event;
use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Events;
use Doctrine\Persistence\Event\LifecycleEventArgs;
use Chill\MainBundle\Doctrine\Model\TrackCreationInterface;
use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface;
use Symfony\Component\Security\Core\Security;
class TrackCreateUpdateSubscriber implements EventSubscriber
{
private Security $security;
/**
* @param Security $security
*/
public function __construct(Security $security)
{
$this->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'));
}
}
}

View File

@ -0,0 +1,12 @@
<?php
namespace Chill\MainBundle\Doctrine\Model;
use Chill\MainBundle\Entity\User;
interface TrackCreationInterface
{
public function setCreatedBy(User $user): self;
public function setCreatedAt(\DateTimeInterface $datetime): self;
}

View File

@ -0,0 +1,12 @@
<?php
namespace Chill\MainBundle\Doctrine\Model;
use Chill\MainBundle\Entity\User;
interface TrackUpdateInterface
{
public function setUpdatedBy(User $user): self;
public function setUpdatedAt(\DateTimeInterface $datetime): self;
}

View File

@ -9,6 +9,12 @@ services:
tags: tags:
- { name: 'serializer.normalizer', priority: 64 } - { name: 'serializer.normalizer', priority: 64 }
Chill\MainBundle\Doctrine\Event\:
resource: '../Doctrine/Event/'
autowire: true
tags:
- { name: 'doctrine.event_subscriber' }
chill.main.helper.translatable_string: chill.main.helper.translatable_string:
class: Chill\MainBundle\Templating\TranslatableStringHelper class: Chill\MainBundle\Templating\TranslatableStringHelper
arguments: arguments:

View File

@ -15,6 +15,7 @@ use Chill\PersonBundle\Entity\Person;
use Chill\ThirdPartyBundle\Entity\ThirdParty; use Chill\ThirdPartyBundle\Entity\ThirdParty;
use Symfony\Component\Serializer\Exception\RuntimeException; use Symfony\Component\Serializer\Exception\RuntimeException;
use Chill\PersonBundle\Entity\AccompanyingPeriod\Resource; use Chill\PersonBundle\Entity\AccompanyingPeriod\Resource;
use Chill\PersonBundle\Entity\AccompanyingPeriod\Comment;
class AccompanyingCourseApiController extends ApiController class AccompanyingCourseApiController extends ApiController
{ {
@ -71,6 +72,10 @@ class AccompanyingCourseApiController extends ApiController
return $this->addRemoveSomething('resource', $id, $request, $_format, 'resource', Resource::class); return $this->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 public function requestorApi($id, Request $request, string $_format): Response
{ {

View File

@ -354,6 +354,18 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
Request::METHOD_DELETE=> \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE 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' => [ 'requestor' => [
'methods' => [ 'methods' => [
Request::METHOD_POST => true, Request::METHOD_POST => true,
@ -389,7 +401,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
] ]
], ],
] ]
] ],
] ]
]); ]);
} }

View File

@ -117,7 +117,9 @@ class AccompanyingPeriod
* @var Collection * @var Collection
* *
* @ORM\OneToMany(targetEntity="Chill\PersonBundle\Entity\AccompanyingPeriod\Comment", * @ORM\OneToMany(targetEntity="Chill\PersonBundle\Entity\AccompanyingPeriod\Comment",
* mappedBy="accompanyingPeriod" * mappedBy="accompanyingPeriod",
* cascade={"persist", "remove"},
* orphanRemoval=true
* ) * )
* @Groups({"read"}) * @Groups({"read"})
*/ */
@ -350,12 +352,14 @@ class AccompanyingPeriod
public function addComment(Comment $comment): self public function addComment(Comment $comment): self
{ {
$this->comments[] = $comment; $this->comments[] = $comment;
$comment->setAccompanyingPeriod($this);
return $this; return $this;
} }
public function removeComment(Comment $comment): void public function removeComment(Comment $comment): void
{ {
$comment->setAccompanyingPeriod(null);
$this->comments->removeElement($comment); $this->comments->removeElement($comment);
} }

View File

@ -26,17 +26,25 @@ use Chill\PersonBundle\Repository\AccompanyingPeriod\CommentRepository;
use Chill\MainBundle\Entity\User; use Chill\MainBundle\Entity\User;
use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Doctrine\ORM\Mapping as ORM; 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\Entity(repositoryClass=CommentRepository::class)
* @ORM\Table(name="chill_person_accompanying_period_comment") * @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\Id
* @ORM\GeneratedValue * @ORM\GeneratedValue
* @ORM\Column(type="integer") * @ORM\Column(type="integer")
* @Groups({"read"})
*/ */
private $id; private $id;
@ -51,27 +59,32 @@ class Comment
/** /**
* @ORM\ManyToOne(targetEntity=User::class) * @ORM\ManyToOne(targetEntity=User::class)
* @ORM\JoinColumn(nullable=false) * @ORM\JoinColumn(nullable=false)
* @Groups({"read"})
*/ */
private $creator; private $creator;
/** /**
* @ORM\Column(type="datetime") * @ORM\Column(type="datetime")
* @Groups({"read"})
*/ */
private $createdAt; private $createdAt;
/** /**
* @ORM\Column(type="datetime") * @ORM\Column(type="datetime")
* @Groups({"read"})
*/ */
private $updatedAt; private $updatedAt;
/** /**
* @ORM\ManyToOne(targetEntity=User::class) * @ORM\ManyToOne(targetEntity=User::class)
* @ORM\JoinColumn(nullable=false) * @ORM\JoinColumn(nullable=false)
* @Groups({"read"})
*/ */
private $updatedBy; private $updatedBy;
/** /**
* @ORM\Column(type="text") * @ORM\Column(type="text")
* @Groups({"read", "write"})
*/ */
private $content; private $content;
@ -104,6 +117,11 @@ class Comment
return $this; return $this;
} }
public function setCreatedBy(User $user): self
{
return $this->setCreator($user);
}
public function getCreatedAt(): ?\DateTimeInterface public function getCreatedAt(): ?\DateTimeInterface
{ {
return $this->createdAt; return $this->createdAt;
@ -133,7 +151,7 @@ class Comment
return $this->updatedBy; return $this->updatedBy;
} }
public function setUpdatedBy(?User $updatedBy): self public function setUpdatedBy(User $updatedBy): self
{ {
$this->updatedBy = $updatedBy; $this->updatedBy = $updatedBy;

View File

@ -92,6 +92,31 @@ components:
required: required:
- id - id
- type - 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: paths:
/1.0/person/accompanying-course/{id}.json: /1.0/person/accompanying-course/{id}.json:
@ -345,3 +370,72 @@ paths:
description: "OK" description: "OK"
422: 422:
description: "object with validation errors" 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"