Passed
Pull Request — master (#6053)
by
unknown
07:47
created

CAttendanceStateProcessor::handleAddCalendar()   B

Complexity

Conditions 7
Paths 7

Size

Total Lines 25
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 17
c 1
b 0
f 0
nc 7
nop 1
dl 0
loc 25
rs 8.8333
1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
declare(strict_types=1);
6
7
namespace Chamilo\CoreBundle\State;
8
9
use ApiPlatform\Metadata\Operation;
10
use ApiPlatform\State\ProcessorInterface;
11
use Chamilo\CourseBundle\Entity\CAttendance;
12
use Chamilo\CourseBundle\Entity\CAttendanceCalendar;
13
use Chamilo\CourseBundle\Entity\CAttendanceCalendarRelGroup;
14
use Chamilo\CourseBundle\Repository\CAttendanceCalendarRepository;
15
use Doctrine\ORM\EntityManagerInterface;
16
use Symfony\Component\HttpFoundation\RequestStack;
17
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
18
19
final class CAttendanceStateProcessor implements ProcessorInterface
20
{
21
    public function __construct(
22
        private readonly ProcessorInterface $persistProcessor,
23
        private readonly EntityManagerInterface $entityManager,
24
        private readonly CAttendanceCalendarRepository $calendarRepo,
25
        private readonly RequestStack $requestStack
26
    ) {}
27
28
    /**
29
     * Main process function for handling attendance and calendar operations.
30
     */
31
    public function process($data, Operation $operation, array $uriVariables = [], array $context = []): void
32
    {
33
        \assert($data instanceof CAttendance);
34
35
        $operationName = $operation->getName();
36
37
        error_log("Processing $operationName");
38
39
        match ($operationName) {
40
            'toggle_visibility' => $this->handleToggleVisibility($data),
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->handleToggleVisibility($data) targeting Chamilo\CoreBundle\State...andleToggleVisibility() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
41
            'soft_delete' => $this->handleSoftDelete($data),
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->handleSoftDelete($data) targeting Chamilo\CoreBundle\State...sor::handleSoftDelete() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
42
            'calendar_add' => $this->handleAddCalendar($data),
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->handleAddCalendar($data) targeting Chamilo\CoreBundle\State...or::handleAddCalendar() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
43
            default => throw new BadRequestHttpException('Operation not supported.'),
44
        };
45
46
        $this->persistProcessor->process($data, $operation, $uriVariables, $context);
47
    }
48
49
    private function handleToggleVisibility(CAttendance $attendance): void
50
    {
51
        $attendanceRepo = $this->entityManager->getRepository(CAttendance::class);
52
53
        $course = $attendance->getFirstResourceLink()->getCourse();
54
        $attendanceRepo->toggleVisibilityPublishedDraft($attendance, $course);
55
56
        $this->entityManager->persist($attendance);
57
        $this->entityManager->flush();
58
    }
59
60
    private function handleSoftDelete(CAttendance $attendance): void
61
    {
62
        $attendance->setActive(2);
63
        $this->entityManager->persist($attendance);
64
    }
65
66
    private function handleAddCalendar(CAttendance $attendance): void
67
    {
68
        $request = $this->requestStack->getCurrentRequest();
69
        $data = json_decode($request->getContent(), true);
70
71
        if (!$data) {
72
            throw new BadRequestHttpException('Request data is required to create a calendar.');
73
        }
74
75
        $startDate = new \DateTime($data['startDate']);
76
        $repeatDate = $data['repeatDate'] ?? false;
77
        $repeatType = $data['repeatType'] ?? null;
78
        $repeatDays = $data['repeatDays'] ?? null;
79
        $endDate = $repeatDate ? new \DateTime($data['repeatEndDate']) : null;
80
        $groupId = $data['group'] ?? 0;
81
82
        $this->saveCalendar($attendance, $startDate, $groupId);
83
84
        if ($repeatDate && $repeatType && $endDate) {
85
            $interval = $this->getRepeatInterval($repeatType, $repeatDays);
86
            $currentDate = clone $startDate;
87
88
            while ($currentDate < $endDate) {
89
                $currentDate->add($interval);
90
                $this->saveCalendar($attendance, $currentDate, $groupId);
91
            }
92
        }
93
    }
94
95
    private function saveCalendar(CAttendance $attendance, \DateTime $date, ?int $groupId): void
96
    {
97
        $existingCalendar = $this->calendarRepo->findOneBy([
98
            'attendance' => $attendance->getIid(),
99
            'dateTime' => $date,
100
        ]);
101
102
        if ($existingCalendar) {
103
104
            return;
105
        }
106
107
        $calendar = new CAttendanceCalendar();
108
        $calendar->setAttendance($attendance);
109
        $calendar->setDateTime($date);
110
        $calendar->setDoneAttendance(false);
111
        $calendar->setBlocked(false);
112
113
        $this->entityManager->persist($calendar);
114
        $this->entityManager->flush();
115
116
        if (!empty($groupId)) {
117
            $this->addAttendanceCalendarToGroup($calendar, $groupId);
118
        }
119
    }
120
121
    private function addAttendanceCalendarToGroup(CAttendanceCalendar $calendar, int $groupId): void
122
    {
123
        $repository = $this->entityManager->getRepository(CAttendanceCalendarRelGroup::class);
124
        $repository->addGroupToCalendar($calendar->getIid(), $groupId);
125
    }
126
127
    private function getRepeatInterval(string $repeatType, ?int $repeatDays = null): \DateInterval
128
    {
129
        return match ($repeatType) {
130
            'daily' => new \DateInterval('P1D'),
131
            'weekly' => new \DateInterval('P7D'),
132
            'bi-weekly' => new \DateInterval('P14D'),
133
            'every-x-days' => new \DateInterval("P{$repeatDays}D"),
134
            'monthly-by-date' => new \DateInterval('P1M'),
135
            default => throw new BadRequestHttpException('Invalid repeat type.'),
136
        };
137
    }
138
}
139