chill-bundles/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseApiController.php
Julien Fastré ae8e5bc2e3 Merge branch 'master' into 'fix-accompanying-period-opening'
# Conflicts:
#   src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseApiController.php
2021-05-26 13:11:23 +00:00

176 lines
6.4 KiB
PHP

<?php
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\CRUD\Controller\ApiController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use Chill\PersonBundle\Privacy\AccompanyingPeriodPrivacyEvent;
use Chill\PersonBundle\Entity\Person;
use Chill\ThirdPartyBundle\Entity\ThirdParty;
use Symfony\Component\Serializer\Exception\RuntimeException;
use Chill\PersonBundle\Entity\AccompanyingPeriod\Resource;
use Chill\PersonBundle\Entity\AccompanyingPeriod\Comment;
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
use Chill\MainBundle\Entity\Scope;
use Symfony\Component\Workflow\Registry;
class AccompanyingCourseApiController extends ApiController
{
protected EventDispatcherInterface $eventDispatcher;
protected ValidatorInterface $validator;
private Registry $registry;
public function __construct(
EventDispatcherInterface $eventDispatcher,
ValidatorInterface $validator,
Registry $registry
) {
$this->eventDispatcher = $eventDispatcher;
$this->validator = $validator;
$this->registry = $registry;
}
public function confirmApi($id, Request $request, $_format): Response
{
/** @var AccompanyingPeriod $accompanyingPeriod */
$accompanyingPeriod = $this->getEntity('participation', $id, $request);
$this->checkACL('confirm', $request, $_format, $accompanyingPeriod);
$workflow = $this->registry->get($accompanyingPeriod);
if (FALSE === $workflow->can($accompanyingPeriod, 'confirm')) {
throw new BadRequestException('It is not possible to confirm this period');
}
$workflow->apply($accompanyingPeriod, 'confirm');
$this->getDoctrine()->getManager()->flush();
return $this->json($accompanyingPeriod, Response::HTTP_OK, [], [
'groups' => [ 'read' ]
]);
}
public function participationApi($id, Request $request, $_format)
{
/** @var AccompanyingPeriod $accompanyingPeriod */
$accompanyingPeriod = $this->getEntity('participation', $id, $request);
$person = $this->getSerializer()
->deserialize($request->getContent(), Person::class, $_format, []);
if (NULL === $person) {
throw new BadRequestException('person id not found');
}
// TODO add acl
//
$this->onPostCheckACL('participation', $request, $_format, $accompanyingPeriod);
switch ($request->getMethod()) {
case Request::METHOD_POST:
$participation = $accompanyingPeriod->createParticipationFor($person);
break;
case Request::METHOD_DELETE:
$participation = $accompanyingPeriod->closeParticipationFor($person);
break;
default:
throw new BadRequestException("This method is not supported");
}
$errors = $this->validator->validate($accompanyingPeriod);
if ($errors->count() > 0) {
// only format accepted
return $this->json($errors, 422);
}
$this->getDoctrine()->getManager()->flush();
return $this->json($participation, 200, [], ['groups' => [ 'read' ]]);
}
public function resourceApi($id, Request $request, string $_format): Response
{
return $this->addRemoveSomething('resource', $id, $request, $_format, 'resource', Resource::class);
}
public function scopeApi($id, Request $request, string $_format): Response
{
return $this->addRemoveSomething('scope', $id, $request, $_format, 'scope', Scope::class, [ 'groups' => [ 'read' ] ]);
}
public function commentApi($id, Request $request, string $_format): Response
{
return $this->addRemoveSomething('comment', $id, $request, $_format, 'comment', Comment::class);
}
public function socialIssueApi($id, Request $request, string $_format): Response
{
return $this->addRemoveSomething('socialissue', $id, $request, $_format, 'socialIssue', SocialIssue::class, [ 'groups' => [ 'read' ] ]);
}
public function requestorApi($id, Request $request, string $_format): Response
{
/** @var AccompanyingPeriod $accompanyingPeriod */
$action = 'requestor';
$accompanyingPeriod = $this->getEntity($action, $id, $request);
// a requestor may be a person or a thirdParty
$this->checkACL($action, $request, $_format, $accompanyingPeriod);
$this->onPostCheckACL($action, $request, $_format, $accompanyingPeriod);
if (Request::METHOD_DELETE === $request->getMethod()) {
$accompanyingPeriod->setRequestor(NULL);
} elseif (Request::METHOD_POST === $request->getMethod()) {
$requestor = null;
$exceptions = [];
foreach ([Person::class, ThirdParty::class] as $class) {
try {
$requestor = $this->getSerializer()
->deserialize($request->getContent(), $class, $_format, []);
} catch (RuntimeException $e) {
$exceptions[] = $e;
}
}
if ($requestor === null) {
throw new BadRequestException('Could not find any person or requestor', 0, $exceptions[0]);
}
$accompanyingPeriod->setRequestor($requestor);
} else {
throw new BadRequestException('method not supported');
}
$errors = $this->validator->validate($accompanyingPeriod);
if ($errors->count() > 0) {
// only format accepted
return $this->json($errors, 422);
}
$this->getDoctrine()->getManager()->flush();
return $this->json($accompanyingPeriod->getRequestor(), 200, [], ['groups' => [ 'read']]);
}
protected function onPostCheckACL(string $action, Request $request, string $_format, $entity): ?Response
{
$this->eventDispatcher->dispatch(
AccompanyingPeriodPrivacyEvent::ACCOMPANYING_PERIOD_PRIVACY_EVENT,
new AccompanyingPeriodPrivacyEvent($entity, [
'action' => $action,
'request' => $request->getMethod()
])
);
return null;
}
}