Internal: Calendar: Replace controller for the api post operation with a api state processor

pull/5206/head
Angel Fernando Quiroz Campos 9 months ago
parent da9f6d1a8f
commit 69cbf94960
  1. 6
      config/services.yaml
  2. 60
      src/CoreBundle/Controller/Api/CreateCCalendarEventAction.php
  3. 5
      src/CoreBundle/Entity/AbstractResource.php
  4. 64
      src/CoreBundle/State/CCalendarEventProcessor.php
  5. 15
      src/CourseBundle/Entity/CCalendarEvent.php
  6. 10
      tests/CourseBundle/Repository/CCalendarEventRepositoryTest.php

@ -67,6 +67,12 @@ services:
bind:
$persistProcessor: '@api_platform.doctrine.orm.state.persist_processor'
Chamilo\CoreBundle\State\CCalendarEventProcessor:
arguments:
$persistProcessor: '@api_platform.doctrine.orm.state.persist_processor'
tags:
- { name: 'api_platform.state_processor' }
Chamilo\CoreBundle\State\UsergroupPostProcessor:
arguments:
$processor: '@api_platform.doctrine.orm.state.persist_processor'

@ -1,60 +0,0 @@
<?php
declare(strict_types=1);
/* For licensing terms, see /license.txt */
namespace Chamilo\CoreBundle\Controller\Api;
use Chamilo\CoreBundle\Entity\User;
use Chamilo\CourseBundle\Entity\CCalendarEvent;
use Chamilo\CourseBundle\Repository\CCalendarEventRepository;
use DateTime;
use Exception;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Security;
class CreateCCalendarEventAction extends BaseResourceFileAction
{
public function __invoke(Request $request, CCalendarEventRepository $repo, Security $security): CCalendarEvent
{
$event = new CCalendarEvent();
$result = $this->handleCreateRequest($event, $repo, $request);
/** @var User $currentUser */
$currentUser = $security->getUser();
$event
->setContent($result['content'] ?? '')
->setComment($result['comment'] ?? '')
->setColor($result['color'] ?? '')
->setStartDate(new DateTime($result['startDate'] ?? ''))
->setEndDate(new DateTime($result['endDate'] ?? ''))
// ->setAllDay($result['allDay'] ?? false)
->setCollective($result['collective'] ?? false)
->setCreator($currentUser)
;
// Detect event type based in the resource link array.
$type = 'personal';
if (!empty($event->getResourceLinkArray())) {
foreach ($event->getResourceLinkArray() as $link) {
if (isset($link['cid'])) {
$type = 'course';
break;
}
}
}
if ('personal' === $type) {
if ($currentUser->getResourceNode()->getId() !== $event->getParentResourceNode()) {
throw new Exception('Not allowed');
}
}
// @todo check course access? Should be handle by CourseVoter?
return $event;
}
}

@ -83,6 +83,7 @@ abstract class AbstractResource
'document:read',
'document:write',
'c_student_publication:write',
'calendar_event:write',
])]
public ?int $parentResourceNode = 0;
@ -100,8 +101,10 @@ abstract class AbstractResource
/**
* Use when sending a request to Api platform.
* Temporal array that saves the resource link list that will be filled by CreateDocumentFileAction.php.
*
* @var array<int, array<string, int>>
*/
#[Groups(['c_tool_intro:write', 'resource_node:write', 'c_student_publication:write'])]
#[Groups(['c_tool_intro:write', 'resource_node:write', 'c_student_publication:write', 'calendar_event:write'])]
public array $resourceLinkList = [];
/**

@ -0,0 +1,64 @@
<?php
namespace Chamilo\CoreBundle\State;
use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProcessorInterface;
use Chamilo\CoreBundle\Entity\User;
use Chamilo\CourseBundle\Entity\CCalendarEvent;
use Exception;
use Symfony\Component\Security\Core\Security;
/**
* @implements ProcessorInterface<CCalendarEvent>
*/
class CCalendarEventProcessor implements ProcessorInterface
{
public function __construct(
private readonly ProcessorInterface $persistProcessor,
private readonly Security $security,
) {
}
/**
* @throws Exception
*/
public function process($data, Operation $operation, array $uriVariables = [], array $context = []): CCalendarEvent
{
assert($data instanceof CCalendarEvent);
/** @var User $currentUser */
$currentUser = $this->security->getUser();
$data->setCreator($currentUser);
if ($this->isPersonalEvent($data)) {
if ($currentUser->getResourceNode()->getId() !== $data->getParentResourceNode()) {
throw new Exception('Not allowed');
}
}
/** @var CCalendarEvent $result */
$result = $this->persistProcessor->process($data, $operation, $uriVariables, $context);
return $result;
}
private function isPersonalEvent(CCalendarEvent $event): bool
{
$type = 'personal';
if (!empty($event->getResourceLinkArray())) {
foreach ($event->getResourceLinkArray() as $link) {
if (isset($link['cid'])) {
$type = 'course';
break;
}
}
}
return 'personal' === $type;
}
}

@ -16,7 +16,6 @@ use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Post;
use ApiPlatform\Metadata\Put;
use Chamilo\CoreBundle\ApiResource\CalendarEvent;
use Chamilo\CoreBundle\Controller\Api\CreateCCalendarEventAction;
use Chamilo\CoreBundle\Controller\Api\UpdateCCalendarEventAction;
use Chamilo\CoreBundle\Entity\AbstractResource;
use Chamilo\CoreBundle\Entity\ResourceInterface;
@ -24,6 +23,7 @@ use Chamilo\CoreBundle\Entity\Room;
use Chamilo\CoreBundle\Filter\CidFilter;
use Chamilo\CoreBundle\Filter\SidFilter;
use Chamilo\CoreBundle\State\CalendarEventProvider;
use Chamilo\CoreBundle\State\CCalendarEventProcessor;
use Chamilo\CourseBundle\Repository\CCalendarEventRepository;
use DateTime;
use Doctrine\Common\Collections\ArrayCollection;
@ -53,8 +53,8 @@ use Symfony\Component\Validator\Constraints as Assert;
provider: CalendarEventProvider::class,
),
new Post(
controller: CreateCCalendarEventAction::class,
securityPostDenormalize: "is_granted('CREATE', object)"
securityPostDenormalize: "is_granted('CREATE', object)",
processor: CCalendarEventProcessor::class
),
],
normalizationContext: ['groups' => ['calendar_event:read', 'resource_node:read']],
@ -84,21 +84,21 @@ class CCalendarEvent extends AbstractResource implements ResourceInterface, Stri
#[ORM\GeneratedValue]
protected ?int $iid = null;
#[Groups(['calendar_event:read'])]
#[Groups(['calendar_event:read', 'calendar_event:write'])]
#[Assert\NotBlank]
#[ORM\Column(name: 'title', type: 'string', length: 255, nullable: false)]
protected string $title;
#[Groups(['calendar_event:read'])]
#[Groups(['calendar_event:read', 'calendar_event:write'])]
#[Assert\NotBlank]
#[ORM\Column(name: 'content', type: 'text', nullable: true)]
protected ?string $content = null;
#[Groups(['calendar_event:read'])]
#[Groups(['calendar_event:read', 'calendar_event:write'])]
#[ORM\Column(name: 'start_date', type: 'datetime', nullable: true)]
protected ?DateTime $startDate = null;
#[Groups(['calendar_event:read'])]
#[Groups(['calendar_event:read', 'calendar_event:write'])]
#[ORM\Column(name: 'end_date', type: 'datetime', nullable: true)]
protected ?DateTime $endDate = null;
@ -143,6 +143,7 @@ class CCalendarEvent extends AbstractResource implements ResourceInterface, Stri
#[ORM\OneToMany(mappedBy: 'event', targetEntity: CCalendarEventAttachment::class, cascade: ['persist', 'remove'])]
protected Collection $attachments;
#[Groups(['calendar_event:read', 'calendar_event:write'])]
#[Assert\NotNull]
#[ORM\Column(name: 'collective', type: 'boolean', nullable: false, options: ['default' => false])]
protected bool $collective = false;

@ -109,7 +109,7 @@ class CCalendarEventRepositoryTest extends AbstractApiTest
'content' => '<p>test event</p>',
'startDate' => $start->format('Y-m-d H:i:s'),
'endDate' => $end->format('Y-m-d H:i:s'),
'parentResourceNodeId' => $resourceNodeId,
'parentResourceNode' => $resourceNodeId,
],
]
);
@ -191,7 +191,7 @@ class CCalendarEventRepositoryTest extends AbstractApiTest
'content' => '<p>test event</p>',
'startDate' => $start->format('Y-m-d H:i:s'),
'endDate' => $end->format('Y-m-d H:i:s'),
'parentResourceNodeId' => $resourceNodeId,
'parentResourceNode' => $resourceNodeId,
],
]
);
@ -238,7 +238,7 @@ class CCalendarEventRepositoryTest extends AbstractApiTest
'content' => '<p>test event</p>',
'startDate' => $start->format('Y-m-d H:i:s'),
'endDate' => $end->format('Y-m-d H:i:s'),
'parentResourceNodeId' => $resourceNodeId,
'parentResourceNode' => $resourceNodeId,
],
]
);
@ -360,8 +360,8 @@ class CCalendarEventRepositoryTest extends AbstractApiTest
'content' => '<p>test event</p>',
'startDate' => $start->format('Y-m-d H:i:s'),
'endDate' => $end->format('Y-m-d H:i:s'),
'parentResourceNodeId' => $resourceNodeId,
'resourceLinkListFromEntity' => $resourceLinkList,
'parentResourceNode' => $resourceNodeId,
'resourceLinkList' => $resourceLinkList,
],
]
);

Loading…
Cancel
Save