Passed
Push — master ( 131c23...309a4e )
by Angel Fernando Quiroz
07:28
created

Version20230904173400::createCCalendarEvent()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 33
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 17
nc 2
nop 8
dl 0
loc 33
rs 9.7
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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\CoreBundle\Repository\Node\UserRepository;
12
use Chamilo\CourseBundle\Entity\CCalendarEvent;
13
use DateTime;
14
use DateTimeZone;
15
use Doctrine\DBAL\Schema\Schema;
16
use Doctrine\ORM\Exception\ORMException;
17
use Exception;
18
19
class Version20230904173400 extends AbstractMigrationChamilo
20
{
21
    public function getDescription(): string
22
    {
23
        return 'Migrate personal_agenda to c_calendar_event and update agenda_reminder';
24
    }
25
26
    /**
27
     * @throws ORMException
28
     * @throws Exception
29
     */
30
    public function up(Schema $schema): void
31
    {
32
        $collectiveInvitationsEnabled = $this->getConfigurationValue('agenda_collective_invitations');
33
        $subscriptionsEnabled = $this->getConfigurationValue('agenda_event_subscriptions');
34
35
        $this->addSql("UPDATE personal_agenda SET parent_event_id = NULL WHERE parent_event_id = 0 OR parent_event_id = ''");
36
        $this->addSql('UPDATE personal_agenda SET parent_event_id = NULL WHERE parent_event_id NOT IN (SELECT id FROM personal_agenda)');
37
        $this->addSql('DELETE FROM personal_agenda WHERE user NOT IN (SELECT id FROM user)');
38
39
        /** @var array<int, CCalendarEvent> $map */
40
        $map = [];
41
42
        $userRepo = $this->container->get(UserRepository::class);
0 ignored issues
show
Bug introduced by
The method get() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

42
        /** @scrutinizer ignore-call */ 
43
        $userRepo = $this->container->get(UserRepository::class);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
43
44
        $personalAgendas = $this->getPersonalEvents();
45
46
        $utc = new DateTimeZone('UTC');
47
        $oldNewEventIdMap = [];
48
49
        /** @var array $personalAgenda */
50
        foreach ($personalAgendas as $personalAgenda) {
51
            $oldParentId = (int) $personalAgenda['parent_event_id'];
52
            $user = $userRepo->find($personalAgenda['user']);
53
54
            $newParent = null;
55
56
            if ($oldParentId && isset($map[$oldParentId])) {
57
                $newParent = $map[$oldParentId];
58
            }
59
60
            $calendarEvent = $this->createCCalendarEvent(
61
                $personalAgenda['title'] ?: '-',
62
                $personalAgenda['text'],
63
                $personalAgenda['date'] ? new DateTime($personalAgenda['date'], $utc) : null,
64
                $personalAgenda['enddate'] ? new DateTime($personalAgenda['enddate'], $utc) : null,
65
                (bool) $personalAgenda['all_day'],
66
                $personalAgenda['color'],
67
                $user,
68
                $newParent
69
            );
70
71
            $map[$personalAgenda['id']] = $calendarEvent;
72
73
            $this->entityManager->persist($calendarEvent);
0 ignored issues
show
Bug introduced by
The method persist() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

73
            $this->entityManager->/** @scrutinizer ignore-call */ 
74
                                  persist($calendarEvent);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
74
            $this->entityManager->flush();
75
76
            if ($collectiveInvitationsEnabled) {
77
                $invitationsOrSubscriptionsInfo = [];
78
79
                if ($subscriptionsEnabled) {
80
                    $subscriptionsInfo = $this->getSubscriptions((int) $personalAgenda['id']);
81
82
                    if (\count($subscriptionsInfo) > 0
83
                        && 0 !== $personalAgenda['subscription_visibility']
84
                    ) {
85
                        $invitationsOrSubscriptionsInfo = $subscriptionsInfo;
86
                    }
87
                }
88
89
                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...
90
                    $calendarEvent
91
                        ->setInvitationType(CCalendarEvent::TYPE_SUBSCRIPTION)
92
                        ->setSubscriptionVisibility($personalAgenda['subscription_visibility'])
93
                        ->setSubscriptionItemId($personalAgenda['subscription_item_id'])
94
                        ->setMaxAttendees($invitationsOrSubscriptionsInfo[0]['max_attendees'])
95
                    ;
96
                } else {
97
                    $invitationsInfo = $this->getInvitations($subscriptionsEnabled, (int) $personalAgenda['id']);
98
99
                    if (\count($invitationsInfo) > 0) {
100
                        $calendarEvent
101
                            ->setCollective((bool) $personalAgenda['collective'])
102
                            ->setInvitationType(CCalendarEvent::TYPE_INVITATION)
103
                        ;
104
105
                        $invitationsOrSubscriptionsInfo = $invitationsInfo;
106
                    }
107
                }
108
109
                foreach ($invitationsOrSubscriptionsInfo as $invitationOrSubscriptionInfo) {
110
                    $inviteesOrSubscribersInfo = $this->getInviteesOrSubscribers($invitationOrSubscriptionInfo['id']);
111
112
                    foreach ($inviteesOrSubscribersInfo as $oldInviteeOrSubscriberInfo) {
113
                        $user = $this->entityManager->find(User::class, $oldInviteeOrSubscriberInfo['user_id']);
114
115
                        if ($user) {
116
                            $calendarEvent->addUserLink($user);
117
                        }
118
                    }
119
                }
120
            }
121
            $oldNewEventIdMap[$personalAgenda['id']] = $calendarEvent;
122
        }
123
124
        $this->entityManager->flush();
125
126
        if ($schema->hasTable('agenda_reminder')) {
127
            if ($tblAgendaReminder->hasColumn('type')) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $tblAgendaReminder seems to be never defined.
Loading history...
128
                $this->updateAgendaReminders($oldNewEventIdMap);
129
            }
130
        }
131
    }
132
133
    private function getPersonalEvents(): array
134
    {
135
        $sql = 'SELECT * FROM personal_agenda ORDER BY id';
136
        $result = $this->connection->executeQuery($sql);
137
138
        return $result->fetchAllAssociative();
139
    }
140
141
    private function createCCalendarEvent(
142
        string $title,
143
        string $content,
144
        ?DateTime $startDate,
145
        ?DateTime $endDate,
146
        bool $allDay,
147
        string $color,
148
        User $creator,
149
        ?CCalendarEvent $parentEvent = null
150
    ): CCalendarEvent {
151
        $calendarEvent = new CCalendarEvent();
152
153
        $calendarEvent
154
            ->setTitle($title)
155
            ->setContent($content)
156
            ->setStartDate($startDate)
157
            ->setEndDate($endDate)
158
            ->setAllDay($allDay)
159
            ->setColor($color)
160
            ->setCreator($creator)
161
            ->setResourceName($title)
162
        ;
163
164
        if ($parentEvent) {
165
            $calendarEvent
166
                ->setParentEvent($parentEvent)
167
                ->setParentResourceNode($parentEvent->getResourceNode()->getId())
168
            ;
169
        } else {
170
            $calendarEvent->setParentResourceNode($creator->getResourceNode()->getId());
171
        }
172
173
        return $calendarEvent;
174
    }
175
176
    private function getInvitations(bool $subscriptionsEnabled, int $personalAgendaId): array
177
    {
178
        $sql = "SELECT i.id, i.creator_id, i.created_at, i.updated_at
179
            FROM agenda_event_invitation i
180
            INNER JOIN personal_agenda pa ON i.id = pa.agenda_event_invitation_id
181
            WHERE pa.id = $personalAgendaId";
182
183
        if ($subscriptionsEnabled) {
184
            $sql .= " AND i.type = 'invitation'";
185
        }
186
187
        try {
188
            $result = $this->connection->executeQuery($sql);
189
190
            return $result->fetchAllAssociative();
191
        } catch (\Doctrine\DBAL\Exception) {
192
            return [];
193
        }
194
    }
195
196
    private function getInviteesOrSubscribers(int $invitationId): array
197
    {
198
        $sql = "SELECT id, user_id, created_at, updated_at
199
            FROM agenda_event_invitee
200
            WHERE invitation_id = $invitationId
201
            ORDER BY created_at ASC";
202
203
        try {
204
            $result = $this->connection->executeQuery($sql);
205
206
            return $result->fetchAllAssociative();
207
        } catch (\Doctrine\DBAL\Exception) {
208
            return [];
209
        }
210
    }
211
212
    private function getSubscriptions(int $personalAgendaId): array
213
    {
214
        $sql = "SELECT i.id, i.creator_id, i.created_at, i.updated_at, i.max_attendees
215
            FROM agenda_event_invitation i
216
            INNER JOIN personal_agenda pa ON i.id = pa.agenda_event_invitation_id
217
            WHERE pa.id = $personalAgendaId
218
                AND i.type = 'subscription'";
219
220
        try {
221
            $result = $this->connection->executeQuery($sql);
222
223
            return $result->fetchAllAssociative();
224
        } catch (\Doctrine\DBAL\Exception) {
225
            return [];
226
        }
227
    }
228
229
    /**
230
     * @param array<int, CCalendarEvent> $oldNewEventIdMap
231
     */
232
    private function updateAgendaReminders(array $oldNewEventIdMap): void
233
    {
234
        $result = $this->connection->executeQuery("SELECT * FROM agenda_reminder WHERE type = 'personal'");
235
236
        while (($reminder = $result->fetchAssociative()) !== false) {
237
            $oldEventId = $reminder['event_id'];
238
            if (\array_key_exists($oldEventId, $oldNewEventIdMap)) {
239
                $newEvent = $oldNewEventIdMap[$oldEventId];
240
                $this->addSql(
241
                    sprintf(
242
                        'UPDATE agenda_reminder SET event_id = %d WHERE id = %d',
243
                        $newEvent->getIid(),
244
                        $reminder['id']
245
                    )
246
                );
247
            }
248
        }
249
    }
250
}
251