Passed
Push — master ( d1c4e0...b88e45 )
by Angel Fernando Quiroz
24:34 queued 16:01
created

Version20230904173400::updateAgendaReminders()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 8
nc 3
nop 2
dl 0
loc 12
rs 10
c 0
b 0
f 0
1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
declare(strict_types=1);
6
7
namespace Chamilo\CoreBundle\Migrations\Schema\V200;
8
9
use Chamilo\CoreBundle\Entity\User;
10
use Chamilo\CoreBundle\Migrations\AbstractMigrationChamilo;
11
use Chamilo\CourseBundle\Entity\CCalendarEvent;
12
use DateTime;
13
use DateTimeZone;
14
use Doctrine\DBAL\Schema\Schema;
15
use Doctrine\ORM\Exception\ORMException;
16
use Exception;
17
18
class Version20230904173400 extends AbstractMigrationChamilo
19
{
20
    public function getDescription(): string
21
    {
22
        return 'Migrate personal_agenda to c_calendar_event';
23
    }
24
25
    /**
26
     * @throws ORMException
27
     * @throws Exception
28
     */
29
    public function up(Schema $schema): void
30
    {
31
        $collectiveInvitationsEnabled = $this->getConfigurationValue('agenda_collective_invitations');
32
        $subscriptionsEnabled = $this->getConfigurationValue('agenda_event_subscriptions');
33
34
        $this->addSql("UPDATE personal_agenda SET parent_event_id = NULL WHERE parent_event_id = 0 OR parent_event_id = ''");
35
        $this->addSql('UPDATE personal_agenda SET parent_event_id = NULL WHERE parent_event_id NOT IN (SELECT id FROM personal_agenda)');
36
        $this->addSql('DELETE FROM personal_agenda WHERE user NOT IN (SELECT id FROM user)');
37
38
        /** @var array<int, CCalendarEvent> $map */
39
        $map = [];
40
41
        $em = $this->getEntityManager();
42
        $userRepo = $em->getRepository(User::class);
43
44
        $personalAgendas = $this->getPersonalEvents();
45
46
        $utc = new DateTimeZone('UTC');
47
48
        /** @var array $personalAgenda */
49
        foreach ($personalAgendas as $personalAgenda) {
50
            $oldParentId = (int) $personalAgenda['parent_event_id'];
51
            $user = $userRepo->find($personalAgenda['user']);
52
53
            $newParent = null;
54
55
            if ($oldParentId && isset($map[$oldParentId])) {
56
                $newParent = $map[$oldParentId];
57
            }
58
59
            $calendarEvent = $this->createCCalendarEvent(
60
                $personalAgenda['title'] ?: '-',
61
                $personalAgenda['text'],
62
                $personalAgenda['date'] ? new DateTime($personalAgenda['date'], $utc) : null,
63
                $personalAgenda['enddate'] ? new DateTime($personalAgenda['enddate'], $utc) : null,
64
                (bool) $personalAgenda['all_day'],
65
                $personalAgenda['color'],
66
                $user,
67
                $newParent
68
            );
69
70
            $map[$personalAgenda['id']] = $calendarEvent;
71
72
            $em->persist($calendarEvent);
73
74
            if ($collectiveInvitationsEnabled) {
75
                $invitationsOrSubscriptionsInfo = [];
76
77
                if ($subscriptionsEnabled) {
78
                    $subscriptionsInfo = $this->getSubscriptions((int) $personalAgenda['id']);
79
80
                    if (\count($subscriptionsInfo) > 0
81
                        && 0 !== $personalAgenda['subscription_visibility']
82
                    ) {
83
                        $invitationsOrSubscriptionsInfo = $subscriptionsInfo;
84
                    }
85
                }
86
87
                if ($invitationsOrSubscriptionsInfo) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $invitationsOrSubscriptionsInfo of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
88
                    $calendarEvent
89
                        ->setInvitationType(CCalendarEvent::TYPE_SUBSCRIPTION)
90
                        ->setSubscriptionVisibility($personalAgenda['subscription_visibility'])
91
                        ->setSubscriptionItemId($personalAgenda['subscription_item_id'])
92
                        ->setMaxAttendees($invitationsOrSubscriptionsInfo[0]['max_attendees'])
93
                    ;
94
                } else {
95
                    $invitationsInfo = $this->getInvitations($subscriptionsEnabled, (int) $personalAgenda['id']);
96
97
                    if (\count($invitationsInfo) > 0) {
98
                        $calendarEvent
99
                            ->setCollective((bool) $personalAgenda['collective'])
100
                            ->setInvitationType(CCalendarEvent::TYPE_INVITATION)
101
                        ;
102
103
                        $invitationsOrSubscriptionsInfo = $invitationsInfo;
104
                    }
105
                }
106
107
                foreach ($invitationsOrSubscriptionsInfo as $invitationOrSubscriptionInfo) {
108
                    $inviteesOrSubscribersInfo = $this->getInviteesOrSubscribers($invitationOrSubscriptionInfo['id']);
109
110
                    foreach ($inviteesOrSubscribersInfo as $oldInviteeOrSubscriberInfo) {
111
                        $user = $em->find(User::class, $oldInviteeOrSubscriberInfo['user_id']);
112
113
                        if ($user) {
114
                            $calendarEvent->addUserLink($user);
115
                        }
116
                    }
117
                }
118
            }
119
        }
120
121
        $em->flush();
122
    }
123
124
    private function getPersonalEvents(): array
125
    {
126
        $sql = 'SELECT * FROM personal_agenda ORDER BY id';
127
        $result = $this->connection->executeQuery($sql);
128
129
        return $result->fetchAllAssociative();
130
    }
131
132
    private function createCCalendarEvent(
133
        string $title,
134
        string $content,
135
        ?DateTime $startDate,
136
        ?DateTime $endDate,
137
        bool $allDay,
138
        string $color,
139
        User $creator,
140
        ?CCalendarEvent $parentEvent = null
141
    ): CCalendarEvent {
142
        $calendarEvent = new CCalendarEvent();
143
144
        $calendarEvent
145
            ->setTitle($title)
146
            ->setContent($content)
147
            ->setStartDate($startDate)
148
            ->setEndDate($endDate)
149
            ->setAllDay($allDay)
150
            ->setColor($color)
151
            ->setCreator($creator)
152
            ->setResourceName($title)
153
        ;
154
155
        if ($parentEvent) {
156
            $calendarEvent
157
                ->setParentEvent($parentEvent)
158
                ->setParentResourceNode($parentEvent->getResourceNode()->getId())
159
            ;
160
        } else {
161
            $calendarEvent->setParentResourceNode($creator->getResourceNode()->getId());
162
        }
163
164
        return $calendarEvent;
165
    }
166
167
    private function getInvitations(bool $subscriptionsEnabled, int $personalAgendaId): array
168
    {
169
        $sql = "SELECT i.id, i.creator_id, i.created_at, i.updated_at
170
            FROM agenda_event_invitation i
171
            INNER JOIN personal_agenda pa ON i.id = pa.agenda_event_invitation_id
172
            WHERE pa.id = $personalAgendaId";
173
174
        if ($subscriptionsEnabled) {
175
            $sql .= " AND i.type = 'invitation'";
176
        }
177
178
        try {
179
            $result = $this->connection->executeQuery($sql);
180
181
            return $result->fetchAllAssociative();
182
        } catch (\Doctrine\DBAL\Exception) {
183
            return [];
184
        }
185
    }
186
187
    private function getInviteesOrSubscribers(int $invitationId): array
188
    {
189
        $sql = "SELECT id, user_id, created_at, updated_at
190
            FROM agenda_event_invitee
191
            WHERE invitation_id = $invitationId
192
            ORDER BY created_at ASC";
193
194
        try {
195
            $result = $this->connection->executeQuery($sql);
196
197
            return $result->fetchAllAssociative();
198
        } catch (\Doctrine\DBAL\Exception) {
199
            return [];
200
        }
201
    }
202
203
    private function getSubscriptions(int $personalAgendaId): array
204
    {
205
        $sql = "SELECT i.id, i.creator_id, i.created_at, i.updated_at, i.max_attendees
206
            FROM agenda_event_invitation i
207
            INNER JOIN personal_agenda pa ON i.id = pa.agenda_event_invitation_id
208
            WHERE pa.id = $personalAgendaId
209
                AND i.type = 'subscription'";
210
211
        try {
212
            $result = $this->connection->executeQuery($sql);
213
214
            return $result->fetchAllAssociative();
215
        } catch (\Doctrine\DBAL\Exception) {
216
            return [];
217
        }
218
    }
219
}
220