Agenda   F
last analyzed

Complexity

Total Complexity 692

Size/Duplication

Total Lines 5336
Duplicated Lines 0 %

Importance

Changes 10
Bugs 2 Features 0
Metric Value
wmc 692
eloc 2959
dl 0
loc 5336
rs 0.8
c 10
b 2
f 0

77 Methods

Rating   Name   Duplication   Size   Complexity  
A setSenderId() 0 3 1
A getType() 0 4 2
A setType() 0 6 2
A getSenderId() 0 3 1
A set_course() 0 3 1
A setSessionInfo() 0 3 1
A getTypes() 0 3 1
A getSessionId() 0 3 1
A setSessionId() 0 3 1
C __construct() 0 99 17
A parseAgendaFilter() 0 23 5
A getRepeatTypes() 0 9 1
F display_mymonthcalendar() 0 249 30
A deleteAttachmentFile() 0 27 4
C importEventFile() 0 135 15
A setIsAllowedToEdit() 0 3 1
B addAttachment() 0 65 6
C get_personal_agenda_items() 0 118 10
A changeVisibility() 0 28 3
A calculate_start_end_of_week() 0 33 1
A addFieldsForRemindersToForm() 0 41 2
A getAttachmentList() 0 18 2
A getIsAllowedToEdit() 0 3 1
A getAllRepeatEvents() 0 25 6
A hasChildren() 0 18 2
A showToForm() 0 39 3
A formatEventDate() 0 14 2
C get_global_agenda_items() 0 138 14
C get_personal_agenda_items_between_dates() 0 122 11
C get_myagendaitems() 0 117 11
A updateAttachment() 0 16 2
A getAttachment() 0 25 5
A getReminder() 0 24 4
A getRepeatedInfoByEvent() 0 14 2
A storeAgendaEventAsAnnouncement() 0 43 5
A removeReminders() 0 29 4
B generateDatesByType() 0 87 11
B addRepeatedItem() 0 84 7
A deleteEventIfAlreadyExists() 0 27 2
A addReminder() 0 26 4
F getCourseEvents() 0 364 68
F getForm() 0 280 45
B move_event() 0 44 6
B parseSendToArray() 0 28 7
A isUserInvitedInEvent() 0 10 1
A parseEventReminders() 0 24 4
A getJsForReminders() 0 21 1
A returnOnHoverInfo() 0 11 2
A returnFullCalendarExtraSettings() 0 11 3
A getEventReminders() 0 9 2
D displayActions() 0 146 30
A resizeEvent() 0 31 5
D getPlatformEvents() 0 112 22
A getInviteesForPersonalEvent() 0 28 4
A returnGoogleCalendarUrl() 0 9 3
F editEvent() 0 387 59
B addSubscriptionFields() 0 86 5
A cleanEvents() 0 12 3
B saveCollectiveProperties() 0 51 7
D setSendToSelect() 0 112 22
A getImportCalendarForm() 0 18 1
D deleteEvent() 0 100 21
A editReminders() 0 20 6
F getEvents() 0 202 32
B addCollectiveInvitationsFields() 0 41 6
A getSessionEvents() 0 19 3
B subscribeCurrentUserToEvent() 0 45 9
B exportEventMembersToCsv() 0 31 7
F getPersonalEvents() 0 143 19
B getUsersAndGroupSubscribedToEvent() 0 57 8
A unsubscribeCurrentUserToEvent() 0 25 5
B convertSessionWithDates() 0 34 6
A convertSessionWithDuration() 0 43 5
B loadSessionsAsEvents() 0 30 8
B loadEventsAsInvitee() 0 49 7
C get_event() 0 98 14
F addEvent() 0 263 32

How to fix   Complexity   

Complex Class

Complex classes like Agenda often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Agenda, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
use Chamilo\CoreBundle\Entity\AgendaEventInvitation;
6
use Chamilo\CoreBundle\Entity\AgendaEventInvitee;
7
use Chamilo\CoreBundle\Entity\AgendaEventSubscriber;
8
use Chamilo\CoreBundle\Entity\AgendaEventSubscription;
9
use Chamilo\CoreBundle\Entity\AgendaReminder;
10
use Chamilo\CoreBundle\Entity\PersonalAgenda;
11
use Chamilo\UserBundle\Entity\User;
12
13
/**
14
 * Class Agenda.
15
 *
16
 * @author: Julio Montoya <[email protected]>
17
 */
18
class Agenda
19
{
20
    public $events = [];
21
    /** @var string Current type */
22
    public $type = 'personal';
23
    public $types = ['personal', 'admin', 'course'];
24
    public $sessionId = 0;
25
    public $senderId;
26
    /** @var array */
27
    public $course;
28
    /** @var string */
29
    public $comment;
30
    public $eventStudentPublicationColor;
31
    /** @var array */
32
    private $sessionInfo;
33
    /** @var bool */
34
    private $isAllowedToEdit;
35
36
    /**
37
     * Constructor.
38
     *
39
     * @param string $type
40
     * @param int    $senderId  Optional The user sender ID
41
     * @param int    $courseId  Optional. The course ID
42
     * @param int    $sessionId Optional The session ID
43
     */
44
    public function __construct(
45
        $type,
46
        $senderId = 0,
47
        $courseId = 0,
48
        $sessionId = 0
49
    ) {
50
        // Table definitions
51
        $this->tbl_global_agenda = Database::get_main_table(TABLE_MAIN_SYSTEM_CALENDAR);
52
        $this->tbl_personal_agenda = Database::get_main_table(TABLE_PERSONAL_AGENDA);
53
        $this->tbl_course_agenda = Database::get_course_table(TABLE_AGENDA);
54
        $this->table_repeat = Database::get_course_table(TABLE_AGENDA_REPEAT);
55
56
        $this->setType($type);
57
        $this->setSenderId($senderId ?: api_get_user_id());
58
        $isAllowToEdit = false;
59
60
        switch ($type) {
61
            case 'course':
62
                $sessionId = $sessionId ?: api_get_session_id();
63
                $sessionInfo = api_get_session_info($sessionId);
64
                $this->setSessionId($sessionId);
65
                $this->setSessionInfo($sessionInfo);
66
67
                // Setting the course object if we are in a course
68
                $courseInfo = api_get_course_info_by_id($courseId);
69
                if (!empty($courseInfo)) {
70
                    $this->set_course($courseInfo);
71
                }
72
73
                // Check if teacher/admin rights.
74
                $isAllowToEdit = api_is_allowed_to_edit(false, true);
75
                // Check course setting.
76
                if (api_get_course_setting('allow_user_edit_agenda') == '1'
77
                    && api_is_allowed_in_course()
78
                ) {
79
                    $isAllowToEdit = true;
80
                }
81
82
                $groupId = api_get_group_id();
83
                if (!empty($groupId)) {
84
                    $groupInfo = GroupManager::get_group_properties($groupId);
85
                    $userHasAccess = GroupManager::user_has_access(
86
                        api_get_user_id(),
87
                        $groupInfo['iid'],
88
                        GroupManager::GROUP_TOOL_CALENDAR
89
                    );
90
                    $isTutor = GroupManager::is_tutor_of_group(
91
                        api_get_user_id(),
92
                        $groupInfo
93
                    );
94
95
                    $isGroupAccess = $userHasAccess || $isTutor;
96
                    $isAllowToEdit = false;
97
                    if ($isGroupAccess) {
98
                        $isAllowToEdit = true;
99
                    }
100
                }
101
102
                if (false === $isAllowToEdit && !empty($sessionId)) {
103
                    $allowDhrToEdit = api_get_configuration_value('allow_agenda_edit_for_hrm');
104
                    if ($allowDhrToEdit) {
105
                        $isHrm = SessionManager::isUserSubscribedAsHRM($sessionId, api_get_user_id());
106
                        if ($isHrm) {
107
                            $isAllowToEdit = true;
108
                        }
109
                    }
110
                }
111
                break;
112
            case 'admin':
113
                $isAllowToEdit = api_is_platform_admin();
114
                break;
115
            case 'personal':
116
                $isAllowToEdit = !api_is_anonymous();
117
                break;
118
        }
119
120
        $this->setIsAllowedToEdit($isAllowToEdit);
121
        $this->events = [];
122
        $agendaColors = array_merge(
123
            [
124
                'platform' => 'red', //red
125
                'course' => '#458B00', //green
126
                'group' => '#A0522D', //siena
127
                'session' => '#00496D', // kind of green
128
                'other_session' => '#999', // kind of green
129
                'personal' => 'steel blue', //steel blue
130
                'student_publication' => '#FF8C00', //DarkOrange
131
            ],
132
            api_get_configuration_value('agenda_colors') ?: []
133
        );
134
135
        // Event colors
136
        $this->event_platform_color = $agendaColors['platform'];
137
        $this->event_course_color = $agendaColors['course'];
138
        $this->event_group_color = $agendaColors['group'];
139
        $this->event_session_color = $agendaColors['session'];
140
        $this->eventOtherSessionColor = $agendaColors['other_session'];
141
        $this->event_personal_color = $agendaColors['personal'];
142
        $this->eventStudentPublicationColor = $agendaColors['student_publication'];
143
    }
144
145
    /**
146
     * @param int $senderId
147
     */
148
    public function setSenderId($senderId)
149
    {
150
        $this->senderId = (int) $senderId;
151
    }
152
153
    /**
154
     * @return int
155
     */
156
    public function getSenderId()
157
    {
158
        return $this->senderId;
159
    }
160
161
    /**
162
     * @param string $type can be 'personal', 'admin'  or  'course'
163
     */
164
    public function setType($type)
165
    {
166
        $type = (string) trim($type);
167
        $typeList = $this->getTypes();
168
        if (in_array($type, $typeList, true)) {
169
            $this->type = $type;
170
        }
171
    }
172
173
    /**
174
     * Returns the type previously set (and filtered) through setType
175
     * If setType() was not called, then type defaults to "personal" as
176
     * set in the class definition.
177
     */
178
    public function getType()
179
    {
180
        if (isset($this->type)) {
181
            return $this->type;
182
        }
183
    }
184
185
    /**
186
     * @param int $id
187
     */
188
    public function setSessionId($id)
189
    {
190
        $this->sessionId = (int) $id;
191
    }
192
193
    /**
194
     * @param array $sessionInfo
195
     */
196
    public function setSessionInfo($sessionInfo)
197
    {
198
        $this->sessionInfo = $sessionInfo;
199
    }
200
201
    /**
202
     * @return int $id
203
     */
204
    public function getSessionId()
205
    {
206
        return $this->sessionId;
207
    }
208
209
    /**
210
     * @param array $courseInfo
211
     */
212
    public function set_course($courseInfo)
213
    {
214
        $this->course = $courseInfo;
215
    }
216
217
    /**
218
     * @return array
219
     */
220
    public function getTypes()
221
    {
222
        return $this->types;
223
    }
224
225
    /**
226
     * Adds an event to the calendar.
227
     *
228
     * @param string $start                 datetime format: 2012-06-14 09:00:00 in local time
229
     * @param string $end                   datetime format: 2012-06-14 09:00:00 in local time
230
     * @param string $allDay                (true, false)
231
     * @param string $title
232
     * @param string $content
233
     * @param array  $usersToSend           array('everyone') or a list of user/group ids
234
     * @param bool   $addAsAnnouncement     event as a *course* announcement
235
     * @param int    $parentEventId
236
     * @param array  $attachmentArray       array of $_FILES['']
237
     * @param array  $attachmentCommentList
238
     * @param string $eventComment
239
     * @param string $color
240
     *
241
     * @return int
242
     */
243
    public function addEvent(
244
        $start,
245
        $end,
246
        $allDay,
247
        $title,
248
        $content,
249
        $usersToSend = [],
250
        $addAsAnnouncement = false,
251
        $parentEventId = null,
252
        $attachmentArray = [],
253
        $attachmentCommentList = [],
254
        $eventComment = null,
255
        $color = '',
256
        array $inviteesList = [],
257
        bool $isCollective = false,
258
        array $reminders = [],
259
        int $careerId = 0,
260
        int $promotionId = 0,
261
        int $subscriptionVisibility = 0,
262
        ?int $subscriptionItemId = null,
263
        int $maxSubscriptions = 0
264
    ) {
265
        $start = api_get_utc_datetime($start);
266
        $end = api_get_utc_datetime($end);
267
        $allDay = isset($allDay) && ($allDay === 'true' || $allDay == 1) ? 1 : 0;
268
        $id = null;
269
270
        $em = Database::getManager();
271
272
        switch ($this->type) {
273
            case 'personal':
274
                $attributes = [
275
                    'user' => api_get_user_id(),
276
                    'title' => $title,
277
                    'text' => Security::remove_XSS($content),
278
                    'date' => $start,
279
                    'enddate' => $end,
280
                    'all_day' => $allDay,
281
                    'color' => $color,
282
                ];
283
284
                $id = Database::insert(
285
                    $this->tbl_personal_agenda,
286
                    $attributes
287
                );
288
289
                if (api_get_configuration_value('agenda_collective_invitations')) {
290
                    Agenda::saveCollectiveProperties($inviteesList, $isCollective, $id);
291
                }
292
293
                if (api_get_configuration_value('agenda_event_subscriptions') && api_is_platform_admin()) {
294
                    $personalEvent = $em->find(PersonalAgenda::class, $id);
295
296
                    if ($personalEvent->hasInvitation()
297
                        && !($personalEvent->getInvitation() instanceof AgendaEventSubscription)
298
                    ) {
299
                        break;
300
                    }
301
302
                    $personalEvent
303
                        ->setSubscriptionVisibility($subscriptionVisibility)
304
                        ->setSubscriptionItemId($subscriptionItemId ?: null)
305
                    ;
306
307
                    $subscription = (new AgendaEventSubscription())
308
                        ->setCreator(api_get_user_entity(api_get_user_id()))
309
                        ->setMaxAttendees($subscriptionVisibility > 0 ? $maxSubscriptions : 0)
310
                    ;
311
312
                    $personalEvent
313
                        ->setCollective(false)
314
                        ->setInvitation($subscription)
315
                    ;
316
317
                    $em->flush();
318
                }
319
                break;
320
            case 'course':
321
                $attributes = [
322
                    'title' => $title,
323
                    'content' => Security::remove_XSS($content),
324
                    'start_date' => $start,
325
                    'end_date' => $end,
326
                    'all_day' => $allDay,
327
                    'session_id' => $this->getSessionId(),
328
                    'c_id' => $this->course['real_id'],
329
                    'comment' => $eventComment,
330
                    'color' => $color,
331
                ];
332
333
                if (!empty($parentEventId)) {
334
                    $attributes['parent_event_id'] = $parentEventId;
335
                }
336
                $this->deleteEventIfAlreadyExists($start, $end, $allDay, $title);
337
                $senderId = $this->getSenderId();
338
                $sessionId = $this->getSessionId();
339
340
                // Simple course event.
341
                $id = Database::insert($this->tbl_course_agenda, $attributes);
342
343
                if ($id) {
344
                    $sql = "UPDATE ".$this->tbl_course_agenda." SET id = iid WHERE iid = $id";
345
                    Database::query($sql);
346
347
                    $groupId = api_get_group_id();
348
                    $groupInfo = [];
349
                    if ($groupId) {
350
                        $groupInfo = GroupManager::get_group_properties(
351
                            $groupId
352
                        );
353
                    }
354
355
                    if (!empty($usersToSend)) {
356
                        $sendTo = $this->parseSendToArray($usersToSend);
357
                        if ($sendTo['everyone']) {
358
                            api_item_property_update(
359
                                $this->course,
360
                                TOOL_CALENDAR_EVENT,
361
                                $id,
362
                                'AgendaAdded',
363
                                $senderId,
364
                                $groupInfo,
365
                                '',
366
                                $start,
367
                                $end,
368
                                $sessionId
369
                            );
370
                            api_item_property_update(
371
                                $this->course,
372
                                TOOL_CALENDAR_EVENT,
373
                                $id,
374
                                'visible',
375
                                $senderId,
376
                                $groupInfo,
377
                                '',
378
                                $start,
379
                                $end,
380
                                $sessionId
381
                            );
382
                        } else {
383
                            // Storing the selected groups
384
                            if (!empty($sendTo['groups'])) {
385
                                foreach ($sendTo['groups'] as $group) {
386
                                    $groupInfoItem = [];
387
                                    if ($group) {
388
                                        $groupInfoItem = GroupManager::get_group_properties($group);
389
                                    }
390
391
                                    api_item_property_update(
392
                                        $this->course,
393
                                        TOOL_CALENDAR_EVENT,
394
                                        $id,
395
                                        'AgendaAdded',
396
                                        $senderId,
397
                                        $groupInfoItem,
398
                                        0,
399
                                        $start,
400
                                        $end,
401
                                        $sessionId
402
                                    );
403
404
                                    api_item_property_update(
405
                                        $this->course,
406
                                        TOOL_CALENDAR_EVENT,
407
                                        $id,
408
                                        'visible',
409
                                        $senderId,
410
                                        $groupInfoItem,
411
                                        0,
412
                                        $start,
413
                                        $end,
414
                                        $sessionId
415
                                    );
416
                                }
417
                            }
418
419
                            // storing the selected users
420
                            if (!empty($sendTo['users'])) {
421
                                foreach ($sendTo['users'] as $userId) {
422
                                    api_item_property_update(
423
                                        $this->course,
424
                                        TOOL_CALENDAR_EVENT,
425
                                        $id,
426
                                        'AgendaAdded',
427
                                        $senderId,
428
                                        $groupInfo,
429
                                        $userId,
430
                                        $start,
431
                                        $end,
432
                                        $sessionId
433
                                    );
434
435
                                    api_item_property_update(
436
                                        $this->course,
437
                                        TOOL_CALENDAR_EVENT,
438
                                        $id,
439
                                        'visible',
440
                                        $senderId,
441
                                        $groupInfo,
442
                                        $userId,
443
                                        $start,
444
                                        $end,
445
                                        $sessionId
446
                                    );
447
                                }
448
                            }
449
                        }
450
                    }
451
452
                    // Add announcement.
453
                    if ($addAsAnnouncement) {
454
                        $this->storeAgendaEventAsAnnouncement(
455
                            $id,
456
                            $usersToSend
457
                        );
458
                    }
459
460
                    // Add attachment.
461
                    if (isset($attachmentArray) && !empty($attachmentArray)) {
462
                        $counter = 0;
463
                        foreach ($attachmentArray as $attachmentItem) {
464
                            $this->addAttachment(
465
                                $id,
466
                                $attachmentItem,
467
                                $attachmentCommentList[$counter],
468
                                $this->course
469
                            );
470
                            $counter++;
471
                        }
472
                    }
473
                }
474
                break;
475
            case 'admin':
476
                if (api_is_platform_admin()) {
477
                    $attributes = [
478
                        'title' => $title,
479
                        'content' => Security::remove_XSS($content),
480
                        'start_date' => $start,
481
                        'end_date' => $end,
482
                        'all_day' => $allDay,
483
                        'access_url_id' => api_get_current_access_url_id(),
484
                    ];
485
486
                    if (api_get_configuration_value('allow_careers_in_global_agenda')) {
487
                        $attributes['career_id'] = $careerId;
488
                        $attributes['promotion_id'] = $promotionId;
489
                    }
490
491
                    $id = Database::insert(
492
                        $this->tbl_global_agenda,
493
                        $attributes
494
                    );
495
                }
496
                break;
497
        }
498
499
        if (api_get_configuration_value('agenda_reminders')) {
500
            foreach ($reminders as $reminder) {
501
                $this->addReminder($id, $reminder[0], $reminder[1]);
502
            }
503
        }
504
505
        return $id;
506
    }
507
508
    /**
509
     * Checks if an event exists and delete it (right before inserting a modified version in addEvent()).
510
     *
511
     * @param string $start  datetime format: 2012-06-14 09:00:00 in local time
512
     * @param string $end    datetime format: 2012-06-14 09:00:00 in local time
513
     * @param int    $allDay (true = 1, false = 0)
514
     *
515
     * @throws Exception
516
     */
517
    public function deleteEventIfAlreadyExists(
518
        string $start,
519
        string $end,
520
        int $allDay,
521
        string $title
522
    ): bool {
523
        $courseId = $this->course['real_id'];
524
        $start = Database::escape_string($start);
525
        $end = Database::escape_string($end);
526
        $title = Database::escape_string($title);
527
        $sql = "SELECT id FROM ".$this->tbl_course_agenda."
528
                WHERE c_id = $courseId
529
                AND session_id = ".$this->sessionId."
530
                AND start_date = '$start'
531
                AND end_date = '$end'
532
                AND all_day = $allDay
533
                AND title = '$title'";
534
        $res = Database::query($sql);
535
        if (Database::num_rows($res) > 0) {
536
            $row = Database::fetch_array($res, 'ASSOC');
537
            $id = $row['id'];
538
            $this->deleteEvent($id);
539
540
            return true;
541
        }
542
543
        return false;
544
    }
545
546
    /**
547
     * @throws Exception
548
     */
549
    public function addReminder($eventId, $count, $period)
550
    {
551
        switch ($period) {
552
            case 'i':
553
                $dateInterval = DateInterval::createFromDateString("$count minutes");
554
                break;
555
            case 'h':
556
                $dateInterval = DateInterval::createFromDateString("$count hours");
557
                break;
558
            case 'd':
559
                $dateInterval = DateInterval::createFromDateString("$count days");
560
                break;
561
            default:
562
                return null;
563
        }
564
565
        $agendaReminder = new AgendaReminder();
566
        $agendaReminder
567
            ->setType($this->type)
568
            ->setEventId($eventId)
569
            ->setDateInterval($dateInterval)
570
        ;
571
572
        $em = Database::getManager();
573
        $em->persist($agendaReminder);
574
        $em->flush();
575
    }
576
577
    public function removeReminders(int $eventId, int $count, string $period)
578
    {
579
        switch ($period) {
580
            case 'i':
581
                $dateInterval = DateInterval::createFromDateString("$count minutes");
582
                break;
583
            case 'h':
584
                $dateInterval = DateInterval::createFromDateString("$count hours");
585
                break;
586
            case 'd':
587
                $dateInterval = DateInterval::createFromDateString("$count days");
588
                break;
589
            default:
590
                return null;
591
        }
592
593
        Database::getManager()
594
            ->createQuery(
595
                'DELETE FROM ChamiloCoreBundle:AgendaReminder ar
596
                WHERE ar.eventId = :eventId AND ar.type = :type AND ar.dateInterval = :dateInterval'
597
            )
598
            ->setParameters(
599
                [
600
                    'eventId' => $eventId,
601
                    'type' => $this->type,
602
                    'dateInterval' => $dateInterval,
603
                ]
604
            )
605
            ->execute();
606
    }
607
608
    public function getReminder(int $eventId, int $count, string $period)
609
    {
610
        switch ($period) {
611
            case 'i':
612
                $dateInterval = DateInterval::createFromDateString("$count minutes");
613
                break;
614
            case 'h':
615
                $dateInterval = DateInterval::createFromDateString("$count hours");
616
                break;
617
            case 'd':
618
                $dateInterval = DateInterval::createFromDateString("$count days");
619
                break;
620
            default:
621
                return null;
622
        }
623
624
        $em = Database::getManager();
625
        $remindersRepo = $em->getRepository('ChamiloCoreBundle:AgendaReminder');
626
627
        return $remindersRepo->findOneBy(
628
            [
629
                'type' => $this->type,
630
                'dateInterval' => $dateInterval,
631
                'eventId' => $eventId,
632
            ]
633
        );
634
    }
635
636
    /**
637
     * @param int $eventId
638
     * @param int $courseId
639
     *
640
     * @return array
641
     */
642
    public function getRepeatedInfoByEvent($eventId, $courseId)
643
    {
644
        $repeatTable = Database::get_course_table(TABLE_AGENDA_REPEAT);
645
        $eventId = (int) $eventId;
646
        $courseId = (int) $courseId;
647
        $sql = "SELECT * FROM $repeatTable
648
                WHERE c_id = $courseId AND cal_id = $eventId";
649
        $res = Database::query($sql);
650
        $repeatInfo = [];
651
        if (Database::num_rows($res) > 0) {
652
            $repeatInfo = Database::fetch_array($res, 'ASSOC');
653
        }
654
655
        return $repeatInfo;
656
    }
657
658
    /**
659
     * @param string $type
660
     * @param string $startEvent      in UTC
661
     * @param string $endEvent        in UTC
662
     * @param string $repeatUntilDate in UTC
663
     *
664
     * @throws Exception
665
     *
666
     * @return array with local times
667
     */
668
    public function generateDatesByType($type, $startEvent, $endEvent, $repeatUntilDate)
669
    {
670
        $continue = true;
671
        $repeatUntilDate = new DateTime($repeatUntilDate, new DateTimeZone('UTC'));
672
        $loopMax = 365;
673
        $counter = 0;
674
        $list = [];
675
676
        switch ($type) {
677
            case 'daily':
678
                $interval = 'P1D';
679
                break;
680
            case 'weekly':
681
                $interval = 'P1W';
682
                break;
683
            case 'monthlyByDate':
684
                $interval = 'P1M';
685
                break;
686
            case 'monthlyByDay':
687
                // not yet implemented
688
                break;
689
            case 'monthlyByDayR':
690
                // not yet implemented
691
                break;
692
            case 'yearly':
693
                $interval = 'P1Y';
694
                break;
695
        }
696
697
        if (empty($interval)) {
698
            return [];
699
        }
700
        $timeZone = api_get_timezone();
701
702
        while ($continue) {
703
            $startDate = new DateTime($startEvent, new DateTimeZone('UTC'));
704
            $endDate = new DateTime($endEvent, new DateTimeZone('UTC'));
705
706
            $startDate->add(new DateInterval($interval));
707
            $endDate->add(new DateInterval($interval));
708
709
            $newStartDate = $startDate->format('Y-m-d H:i:s');
710
            $newEndDate = $endDate->format('Y-m-d H:i:s');
711
712
            $startEvent = $newStartDate;
713
            $endEvent = $newEndDate;
714
715
            if ($endDate > $repeatUntilDate) {
716
                break;
717
            }
718
719
            // @todo remove comment code
720
            // The code below was not adpating to saving light time but was doubling the difference with UTC time.
721
            // Might be necessary to adapt to update saving light time difference.
722
            /*            $startDateInLocal = new DateTime($newStartDate, new DateTimeZone($timeZone));
723
                        if ($startDateInLocal->format('I') == 0) {
724
                            // Is saving time? Then fix UTC time to add time
725
                            $seconds = $startDateInLocal->getOffset();
726
                            $startDate->add(new DateInterval("PT".$seconds."S"));
727
                            //$startDateFixed = $startDate->format('Y-m-d H:i:s');
728
                            //$startDateInLocalFixed = new DateTime($startDateFixed, new DateTimeZone($timeZone));
729
                            //$newStartDate = $startDateInLocalFixed->format('Y-m-d H:i:s');
730
                            //$newStartDate = $startDate->setTimezone(new DateTimeZone($timeZone))->format('Y-m-d H:i:s');
731
                        }
732
733
                        $endDateInLocal = new DateTime($newEndDate, new DateTimeZone($timeZone));
734
                        if ($endDateInLocal->format('I') == 0) {
735
                            // Is saving time? Then fix UTC time to add time
736
                            $seconds = $endDateInLocal->getOffset();
737
                            $endDate->add(new DateInterval("PT".$seconds."S"));
738
                            //$endDateFixed = $endDate->format('Y-m-d H:i:s');
739
                            //$endDateInLocalFixed = new DateTime($endDateFixed, new DateTimeZone($timeZone));
740
                            //$newEndDate = $endDateInLocalFixed->format('Y-m-d H:i:s');
741
                    }
742
            */
743
            $newStartDate = $startDate->setTimezone(new DateTimeZone($timeZone))->format('Y-m-d H:i:s');
744
            $newEndDate = $endDate->setTimezone(new DateTimeZone($timeZone))->format('Y-m-d H:i:s');
745
            $list[] = ['start' => $newStartDate, 'end' => $newEndDate];
746
            $counter++;
747
748
            // just in case stop if more than $loopMax
749
            if ($counter > $loopMax) {
750
                break;
751
            }
752
        }
753
754
        return $list;
755
    }
756
757
    /**
758
     * @param int    $eventId
759
     * @param string $type
760
     * @param string $end     in UTC
761
     * @param array  $sentTo
762
     *
763
     * @return bool
764
     */
765
    public function addRepeatedItem($eventId, $type, $end, $sentTo = [])
766
    {
767
        $t_agenda = Database::get_course_table(TABLE_AGENDA);
768
        $t_agenda_r = Database::get_course_table(TABLE_AGENDA_REPEAT);
769
770
        if (empty($this->course)) {
771
            return false;
772
        }
773
774
        $courseId = $this->course['real_id'];
775
        $eventId = (int) $eventId;
776
777
        $sql = "SELECT title, content, start_date, end_date, all_day
778
                FROM $t_agenda
779
                WHERE c_id = $courseId AND id = $eventId";
780
        $res = Database::query($sql);
781
782
        if (Database::num_rows($res) !== 1) {
783
            return false;
784
        }
785
786
        $typeList = [
787
            'daily',
788
            'weekly',
789
            'monthlyByDate',
790
            'monthlyByDay',
791
            'monthlyByDayR',
792
            'yearly',
793
        ];
794
795
        if (!in_array($type, $typeList)) {
796
            return false;
797
        }
798
799
        $now = time();
800
801
        // The event has to repeat *in the future*. We don't allow repeated
802
        // events in the past.
803
        $endTimeStamp = api_strtotime($end, 'UTC');
804
805
        if ($endTimeStamp < $now) {
806
            return false;
807
        }
808
809
        $row = Database::fetch_array($res);
810
811
        $title = $row['title'];
812
        $content = $row['content'];
813
        $allDay = $row['all_day'];
814
815
        $type = Database::escape_string($type);
816
        $end = Database::escape_string($end);
817
818
        $sql = "INSERT INTO $t_agenda_r (c_id, cal_id, cal_type, cal_end)
819
                VALUES ($courseId, '$eventId', '$type', '$endTimeStamp')";
820
        Database::query($sql);
821
822
        $generatedDates = $this->generateDatesByType($type, $row['start_date'], $row['end_date'], $end);
823
824
        if (empty($generatedDates)) {
825
            return false;
826
        }
827
828
        foreach ($generatedDates as $dateInfo) {
829
//            $start = api_get_local_time($dateInfo['start']);
830
//            $end = api_get_local_time($dateInfo['end']);
831
            // On line 529 in function generateDatesByType there is a @todo remove comment code
832
            // just before the part updating the date in local time so keep both synchronised
833
            $start = $dateInfo['start'];
834
            $end = $dateInfo['end'];
835
836
            $this->addEvent(
837
                $start,
838
                $end,
839
                $allDay,
840
                $title,
841
                $content,
842
                $sentTo,
843
                false,
844
                $eventId
845
            );
846
        }
847
848
        return true;
849
    }
850
851
    /**
852
     * @param int   $item_id
853
     * @param array $sentTo
854
     *
855
     * @return int
856
     */
857
    public function storeAgendaEventAsAnnouncement($item_id, $sentTo = [])
858
    {
859
        $table_agenda = Database::get_course_table(TABLE_AGENDA);
860
        $courseId = api_get_course_int_id();
861
862
        // Check params
863
        if (empty($item_id) || $item_id != strval(intval($item_id))) {
864
            return -1;
865
        }
866
867
        // Get the agenda item.
868
        $item_id = intval($item_id);
869
        $sql = "SELECT * FROM $table_agenda
870
                WHERE c_id = $courseId AND id = ".$item_id;
871
        $res = Database::query($sql);
872
873
        if (Database::num_rows($res) > 0) {
874
            $row = Database::fetch_array($res, 'ASSOC');
875
876
            // Sending announcement
877
            if (!empty($sentTo)) {
878
                $id = AnnouncementManager::add_announcement(
879
                    api_get_course_info(),
880
                    api_get_session_id(),
881
                    $row['title'],
882
                    $row['content'],
883
                    $sentTo,
884
                    null,
885
                    null,
886
                    $row['end_date']
887
                );
888
889
                AnnouncementManager::sendEmail(
890
                    api_get_course_info(),
891
                    api_get_session_id(),
892
                    $id
893
                );
894
895
                return $id;
896
            }
897
        }
898
899
        return -1;
900
    }
901
902
    /**
903
     * Edits an event.
904
     *
905
     * @param int    $id
906
     * @param string $start                 datetime format: 2012-06-14 09:00:00
907
     * @param string $end                   datetime format: 2012-06-14 09:00:00
908
     * @param int    $allDay                is all day 'true' or 'false'
909
     * @param string $title
910
     * @param string $content
911
     * @param array  $usersToSend
912
     * @param array  $attachmentArray
913
     * @param array  $attachmentCommentList
914
     * @param string $comment
915
     * @param string $color
916
     * @param bool   $addAnnouncement
917
     * @param bool   $updateContent
918
     * @param int    $authorId
919
     *
920
     * @return bool
921
     */
922
    public function editEvent(
923
        $id,
924
        $start,
925
        $end,
926
        $allDay,
927
        $title,
928
        $content,
929
        $usersToSend = [],
930
        $attachmentArray = [],
931
        $attachmentCommentList = [],
932
        $comment = null,
933
        $color = '',
934
        $addAnnouncement = false,
935
        $updateContent = true,
936
        $authorId = 0,
937
        array $inviteesList = [],
938
        bool $isCollective = false,
939
        array $remindersList = [],
940
        int $careerId = 0,
941
        int $promotionId = 0,
942
        int $subscriptionVisibility = 0,
943
        ?int $subscriptionItemId = null,
944
        int $maxSubscriptions = 0,
945
        array $subscribers = []
946
    ) {
947
        $id = (int) $id;
948
        $start = api_get_utc_datetime($start);
949
        $end = api_get_utc_datetime($end);
950
        $allDay = isset($allDay) && $allDay == 'true' ? 1 : 0;
951
        $currentUserId = api_get_user_id();
952
        $authorId = empty($authorId) ? $currentUserId : (int) $authorId;
953
954
        $em = Database::getManager();
955
956
        switch ($this->type) {
957
            case 'personal':
958
                $eventInfo = $this->get_event($id);
959
                if ($eventInfo['user'] != $currentUserId
960
                    && (
961
                        api_get_configuration_value('agenda_collective_invitations')
962
                            && !self::isUserInvitedInEvent($id, $currentUserId)
963
                    )
964
                ) {
965
                    break;
966
                }
967
                $attributes = [
968
                    'title' => $title,
969
                    'date' => $start,
970
                    'enddate' => $end,
971
                    'all_day' => $allDay,
972
                ];
973
974
                if ($updateContent) {
975
                    $attributes['text'] = $content;
976
                }
977
978
                if (!empty($color)) {
979
                    $attributes['color'] = $color;
980
                }
981
982
                Database::update(
983
                    $this->tbl_personal_agenda,
984
                    $attributes,
985
                    ['id = ?' => $id]
986
                );
987
988
                if (api_get_configuration_value('agenda_collective_invitations')) {
989
                    Agenda::saveCollectiveProperties($inviteesList, $isCollective, $id);
990
                }
991
992
                if (api_get_configuration_value('agenda_event_subscriptions') && api_is_platform_admin()) {
993
                    $personalEvent = $em->find(PersonalAgenda::class, $id);
994
995
                    if ($personalEvent->hasInvitation()
996
                        && !($personalEvent->getInvitation() instanceof AgendaEventSubscription)
997
                    ) {
998
                        break;
999
                    }
1000
1001
                    $personalEvent->setSubscriptionVisibility($subscriptionVisibility);
1002
1003
                    /** @var AgendaEventSubscription $subscription */
1004
                    $subscription = $personalEvent->getInvitation();
1005
1006
                    if ($subscription) {
1007
                        $subscription->setMaxAttendees($subscriptionVisibility > 0 ? $maxSubscriptions : 0);
1008
1009
                        if ($personalEvent->getSubscriptionItemId() != $subscriptionItemId) {
1010
                            $personalEvent->setSubscriptionItemId($subscriptionItemId ?: null);
1011
                            $subscription->removeInvitees();
1012
                        } else {
1013
                            $subscription->removeInviteesNotInIdList($subscribers);
1014
                        }
1015
1016
                        $em->flush();
1017
                    }
1018
                }
1019
                break;
1020
            case 'course':
1021
                $eventInfo = $this->get_event($id);
1022
1023
                if (empty($eventInfo)) {
1024
                    return false;
1025
                }
1026
1027
                $groupId = api_get_group_id();
1028
                $groupIid = 0;
1029
                $groupInfo = [];
1030
                if ($groupId) {
1031
                    $groupInfo = GroupManager::get_group_properties($groupId);
1032
                    if ($groupInfo) {
1033
                        $groupIid = $groupInfo['iid'];
1034
                    }
1035
                }
1036
1037
                $courseId = $this->course['real_id'];
1038
1039
                if (empty($courseId)) {
1040
                    return false;
1041
                }
1042
1043
                if (!$this->getIsAllowedToEdit()) {
1044
                    return false;
1045
                }
1046
1047
                $attributes = [
1048
                    'title' => $title,
1049
                    'start_date' => $start,
1050
                    'end_date' => $end,
1051
                    'all_day' => $allDay,
1052
                    'comment' => $comment,
1053
                ];
1054
1055
                if ($updateContent) {
1056
                    $attributes['content'] = $content;
1057
                }
1058
1059
                if (!empty($color)) {
1060
                    $attributes['color'] = $color;
1061
                }
1062
1063
                Database::update(
1064
                    $this->tbl_course_agenda,
1065
                    $attributes,
1066
                    [
1067
                        'id = ? AND c_id = ? AND session_id = ? ' => [
1068
                            $id,
1069
                            $courseId,
1070
                            $this->sessionId,
1071
                        ],
1072
                    ]
1073
                );
1074
1075
                if (!empty($usersToSend)) {
1076
                    $sendTo = $this->parseSendToArray($usersToSend);
1077
1078
                    $usersToDelete = array_diff(
1079
                        $eventInfo['send_to']['users'],
1080
                        $sendTo['users']
1081
                    );
1082
                    $usersToAdd = array_diff(
1083
                        $sendTo['users'],
1084
                        $eventInfo['send_to']['users']
1085
                    );
1086
1087
                    $groupsToDelete = array_diff(
1088
                        $eventInfo['send_to']['groups'],
1089
                        $sendTo['groups']
1090
                    );
1091
                    $groupToAdd = array_diff(
1092
                        $sendTo['groups'],
1093
                        $eventInfo['send_to']['groups']
1094
                    );
1095
1096
                    if ($sendTo['everyone']) {
1097
                        // Delete all from group
1098
                        if (isset($eventInfo['send_to']['groups']) &&
1099
                            !empty($eventInfo['send_to']['groups'])
1100
                        ) {
1101
                            foreach ($eventInfo['send_to']['groups'] as $group) {
1102
                                $groupIidItem = 0;
1103
                                if ($group) {
1104
                                    $groupInfoItem = GroupManager::get_group_properties(
1105
                                        $group
1106
                                    );
1107
                                    if ($groupInfoItem) {
1108
                                        $groupIidItem = $groupInfoItem['iid'];
1109
                                    }
1110
                                }
1111
1112
                                api_item_property_delete(
1113
                                    $this->course,
1114
                                    TOOL_CALENDAR_EVENT,
1115
                                    $id,
1116
                                    0,
1117
                                    $groupIidItem,
1118
                                    $this->sessionId
1119
                                );
1120
                            }
1121
                        }
1122
1123
                        // Storing the selected users.
1124
                        if (isset($eventInfo['send_to']['users']) &&
1125
                            !empty($eventInfo['send_to']['users'])
1126
                        ) {
1127
                            foreach ($eventInfo['send_to']['users'] as $userId) {
1128
                                api_item_property_delete(
1129
                                    $this->course,
1130
                                    TOOL_CALENDAR_EVENT,
1131
                                    $id,
1132
                                    $userId,
1133
                                    $groupIid,
1134
                                    $this->sessionId
1135
                                );
1136
                            }
1137
                        }
1138
1139
                        // Add to everyone only.
1140
                        api_item_property_update(
1141
                            $this->course,
1142
                            TOOL_CALENDAR_EVENT,
1143
                            $id,
1144
                            'visible',
1145
                            $authorId,
1146
                            $groupInfo,
1147
                            null,
1148
                            $start,
1149
                            $end,
1150
                            $this->sessionId
1151
                        );
1152
                    } else {
1153
                        // Delete "everyone".
1154
                        api_item_property_delete(
1155
                            $this->course,
1156
                            TOOL_CALENDAR_EVENT,
1157
                            $id,
1158
                            0,
1159
                            0,
1160
                            $this->sessionId
1161
                        );
1162
1163
                        // Add groups
1164
                        if (!empty($groupToAdd)) {
1165
                            foreach ($groupToAdd as $group) {
1166
                                $groupInfoItem = [];
1167
                                if ($group) {
1168
                                    $groupInfoItem = GroupManager::get_group_properties(
1169
                                        $group
1170
                                    );
1171
                                }
1172
1173
                                api_item_property_update(
1174
                                    $this->course,
1175
                                    TOOL_CALENDAR_EVENT,
1176
                                    $id,
1177
                                    'visible',
1178
                                    $authorId,
1179
                                    $groupInfoItem,
1180
                                    0,
1181
                                    $start,
1182
                                    $end,
1183
                                    $this->sessionId
1184
                                );
1185
                            }
1186
                        }
1187
1188
                        // Delete groups.
1189
                        if (!empty($groupsToDelete)) {
1190
                            foreach ($groupsToDelete as $group) {
1191
                                $groupIidItem = 0;
1192
                                $groupInfoItem = [];
1193
                                if ($group) {
1194
                                    $groupInfoItem = GroupManager::get_group_properties(
1195
                                        $group
1196
                                    );
1197
                                    if ($groupInfoItem) {
1198
                                        $groupIidItem = $groupInfoItem['iid'];
1199
                                    }
1200
                                }
1201
1202
                                api_item_property_delete(
1203
                                    $this->course,
1204
                                    TOOL_CALENDAR_EVENT,
1205
                                    $id,
1206
                                    0,
1207
                                    $groupIidItem,
1208
                                    $this->sessionId
1209
                                );
1210
                            }
1211
                        }
1212
1213
                        // Add users.
1214
                        if (!empty($usersToAdd)) {
1215
                            foreach ($usersToAdd as $userId) {
1216
                                api_item_property_update(
1217
                                    $this->course,
1218
                                    TOOL_CALENDAR_EVENT,
1219
                                    $id,
1220
                                    'visible',
1221
                                    $authorId,
1222
                                    $groupInfo,
1223
                                    $userId,
1224
                                    $start,
1225
                                    $end,
1226
                                    $this->sessionId
1227
                                );
1228
                            }
1229
                        }
1230
1231
                        // Delete users.
1232
                        if (!empty($usersToDelete)) {
1233
                            foreach ($usersToDelete as $userId) {
1234
                                api_item_property_delete(
1235
                                    $this->course,
1236
                                    TOOL_CALENDAR_EVENT,
1237
                                    $id,
1238
                                    $userId,
1239
                                    $groupInfo,
1240
                                    $this->sessionId
1241
                                );
1242
                            }
1243
                        }
1244
                    }
1245
                }
1246
1247
                // Add announcement.
1248
                if (isset($addAnnouncement) && !empty($addAnnouncement)) {
1249
                    $this->storeAgendaEventAsAnnouncement(
1250
                        $id,
1251
                        $usersToSend
1252
                    );
1253
                }
1254
1255
                // Add attachment.
1256
                if (isset($attachmentArray) && !empty($attachmentArray)) {
1257
                    $counter = 0;
1258
                    foreach ($attachmentArray as $attachmentItem) {
1259
                        if (empty($attachmentItem['id'])) {
1260
                            $this->addAttachment(
1261
                                $id,
1262
                                $attachmentItem,
1263
                                $attachmentCommentList[$counter],
1264
                                $this->course
1265
                            );
1266
                        } else {
1267
                            $this->updateAttachment(
1268
                                $attachmentItem['id'],
1269
                                $id,
1270
                                $attachmentItem,
1271
                                $attachmentCommentList[$counter],
1272
                                $this->course
1273
                            );
1274
                        }
1275
                        $counter++;
1276
                    }
1277
                }
1278
                break;
1279
            case 'admin':
1280
            case 'platform':
1281
                if (api_is_platform_admin()) {
1282
                    $attributes = [
1283
                        'title' => $title,
1284
                        'start_date' => $start,
1285
                        'end_date' => $end,
1286
                        'all_day' => $allDay,
1287
                    ];
1288
1289
                    if (api_get_configuration_value('allow_careers_in_global_agenda')) {
1290
                        $attributes['career_id'] = $careerId;
1291
                        $attributes['promotion_id'] = $promotionId;
1292
                    }
1293
1294
                    if ($updateContent) {
1295
                        $attributes['content'] = $content;
1296
                    }
1297
                    Database::update(
1298
                        $this->tbl_global_agenda,
1299
                        $attributes,
1300
                        ['id = ?' => $id]
1301
                    );
1302
                }
1303
                break;
1304
        }
1305
1306
        $this->editReminders($id, $remindersList);
1307
1308
        return true;
1309
    }
1310
1311
    /**
1312
     * @param int  $id
1313
     * @param bool $deleteAllItemsFromSerie
1314
     *
1315
     * @throws \Doctrine\ORM\ORMException
1316
     * @throws \Doctrine\ORM\OptimisticLockException
1317
     */
1318
    public function deleteEvent($id, $deleteAllItemsFromSerie = false)
1319
    {
1320
        $em = Database::getManager();
1321
1322
        switch ($this->type) {
1323
            case 'personal':
1324
                $eventInfo = $this->get_event($id);
1325
                if ($eventInfo['user'] == api_get_user_id()) {
1326
                    Database::delete(
1327
                        $this->tbl_personal_agenda,
1328
                        ['id = ?' => $id]
1329
                    );
1330
                } elseif (api_get_configuration_value('agenda_collective_invitations')) {
1331
                    $currentUser = api_get_user_entity(api_get_user_id());
1332
1333
                    $eventRepo = $em->getRepository('ChamiloCoreBundle:PersonalAgenda');
1334
                    $event = $eventRepo->findOneByIdAndInvitee($id, $currentUser);
1335
                    $invitation = $event ? $event->getInvitation() : null;
1336
1337
                    if ($invitation) {
1338
                        $invitation->removeInviteeUser($currentUser);
1339
1340
                        $em->persist($invitation);
1341
                        $em->flush();
1342
                    }
1343
                }
1344
                break;
1345
            case 'course':
1346
                $courseId = api_get_course_int_id();
1347
                $isAllowToEdit = $this->getIsAllowedToEdit();
1348
1349
                if (!empty($courseId) && $isAllowToEdit) {
1350
                    $eventInfo = $this->get_event($id);
1351
                    if ($deleteAllItemsFromSerie) {
1352
                        /* This is one of the children.
1353
                           Getting siblings and delete 'Em all + the father! */
1354
                        if (isset($eventInfo['parent_event_id']) && !empty($eventInfo['parent_event_id'])) {
1355
                            // Removing items.
1356
                            $events = $this->getAllRepeatEvents($eventInfo['parent_event_id']);
1357
                            if (!empty($events)) {
1358
                                foreach ($events as $event) {
1359
                                    $this->deleteEvent($event['id']);
1360
                                }
1361
                            }
1362
                            // Removing parent.
1363
                            $this->deleteEvent($eventInfo['parent_event_id']);
1364
                        } else {
1365
                            // This is the father looking for the children.
1366
                            $events = $this->getAllRepeatEvents($id);
1367
                            if (!empty($events)) {
1368
                                foreach ($events as $event) {
1369
                                    $this->deleteEvent($event['id']);
1370
                                }
1371
                            }
1372
                        }
1373
                    }
1374
1375
                    // Removing from events.
1376
                    Database::delete(
1377
                        $this->tbl_course_agenda,
1378
                        ['id = ? AND c_id = ?' => [$id, $courseId]]
1379
                    );
1380
1381
                    api_item_property_update(
1382
                        $this->course,
1383
                        TOOL_CALENDAR_EVENT,
1384
                        $id,
1385
                        'delete',
1386
                        api_get_user_id()
1387
                    );
1388
1389
                    // Removing from series.
1390
                    Database::delete(
1391
                        $this->table_repeat,
1392
                        [
1393
                            'cal_id = ? AND c_id = ?' => [
1394
                                $id,
1395
                                $courseId,
1396
                            ],
1397
                        ]
1398
                    );
1399
1400
                    if (isset($eventInfo['attachment']) && !empty($eventInfo['attachment'])) {
1401
                        foreach ($eventInfo['attachment'] as $attachment) {
1402
                            self::deleteAttachmentFile(
1403
                                $attachment['id'],
1404
                                $this->course
1405
                            );
1406
                        }
1407
                    }
1408
                }
1409
                break;
1410
            case 'admin':
1411
                if (api_is_platform_admin()) {
1412
                    Database::delete(
1413
                        $this->tbl_global_agenda,
1414
                        ['id = ?' => $id]
1415
                    );
1416
                }
1417
                break;
1418
        }
1419
    }
1420
1421
    public function exportEventMembersToCsv(int $id, $type = "Invitee")
1422
    {
1423
        if (false === api_get_configuration_value('agenda_event_subscriptions') && false === api_get_configuration_value('agenda_collective_invitations')) {
1424
            return;
1425
        }
1426
        if ('personal' !== $this->type) {
1427
            return;
1428
        }
1429
        if ($type === "Invitee") {
1430
            $members = self::getInviteesForPersonalEvent($id, AgendaEventInvitee::class);
1431
        } elseif ($type === "Subscriber") {
1432
            $members = self::getInviteesForPersonalEvent($id, AgendaEventSubscriber::class);
1433
        }
1434
        $data = [];
1435
        $data[] = [
1436
            'OfficialCode',
1437
            'Lastname',
1438
            'Firsname',
1439
            'Email',
1440
        ];
1441
        $count = 1;
1442
        foreach ($members as $member) {
1443
            $user = api_get_user_info($member['id']);
1444
            $data[$count][] = $user['official_code'];
1445
            $data[$count][] = $user['lastname'];
1446
            $data[$count][] = $user['firstname'];
1447
            $data[$count][] = $user['email'];
1448
            $count++;
1449
        }
1450
1451
        return $data;
1452
    }
1453
1454
    public function subscribeCurrentUserToEvent(int $id)
1455
    {
1456
        if (false === api_get_configuration_value('agenda_event_subscriptions')) {
1457
            return;
1458
        }
1459
1460
        if ('personal' !== $this->type) {
1461
            return;
1462
        }
1463
1464
        $em = Database::getManager();
1465
1466
        $currentUser = api_get_user_entity(api_get_user_id());
1467
        $personalEvent = $em->find(PersonalAgenda::class, $id);
1468
1469
        /** @var AgendaEventSubscription $subscription */
1470
        $subscription = $personalEvent ? $personalEvent->getInvitation() : null;
1471
1472
        if (!$subscription) {
1473
            return;
1474
        }
1475
1476
        if ($subscription->getInvitees()->count() >= $subscription->getMaxAttendees()
1477
            && $subscription->getMaxAttendees() > 0
1478
        ) {
1479
            return;
1480
        }
1481
1482
        if (AgendaEventSubscription::SUBSCRIPTION_CLASS === $personalEvent->getSubscriptionVisibility()) {
1483
            $objGroup = new UserGroup();
1484
            $groupList = $objGroup->getUserGroupListByUser($currentUser->getId(), UserGroup::NORMAL_CLASS);
1485
            $groupIdList = array_column($groupList, 'id');
1486
1487
            if (!in_array($personalEvent->getSubscriptionItemId(), $groupIdList)) {
1488
                return;
1489
            }
1490
        }
1491
1492
        $subscriber = (new AgendaEventSubscriber())
1493
            ->setUser($currentUser)
1494
        ;
1495
1496
        $subscription->addInvitee($subscriber);
1497
1498
        $em->flush();
1499
    }
1500
1501
    public function unsubscribeCurrentUserToEvent(int $id)
1502
    {
1503
        if (false === api_get_configuration_value('agenda_event_subscriptions')) {
1504
            return;
1505
        }
1506
1507
        if ('personal' !== $this->type) {
1508
            return;
1509
        }
1510
1511
        $em = Database::getManager();
1512
1513
        $currentUser = api_get_user_entity(api_get_user_id());
1514
        $personalEvent = $em->find(PersonalAgenda::class, $id);
1515
1516
        /** @var AgendaEventSubscription $subscription */
1517
        $subscription = $personalEvent ? $personalEvent->getInvitation() : null;
1518
1519
        if (!$subscription) {
1520
            return;
1521
        }
1522
1523
        $subscription->removeInviteeUser($currentUser);
1524
1525
        $em->flush();
1526
    }
1527
1528
    /**
1529
     * Get agenda events.
1530
     *
1531
     * @param int    $start
1532
     * @param int    $end
1533
     * @param int    $courseId
1534
     * @param int    $groupId
1535
     * @param int    $user_id
1536
     * @param string $format
1537
     *
1538
     * @return array|string
1539
     */
1540
    public function getEvents(
1541
        $start,
1542
        $end,
1543
        $courseId = null,
1544
        $groupId = null,
1545
        $user_id = 0,
1546
        $format = 'json'
1547
    ) {
1548
        switch ($this->type) {
1549
            case 'admin':
1550
                $this->getPlatformEvents($start, $end);
1551
                break;
1552
            case 'course':
1553
                $courseInfo = api_get_course_info_by_id($courseId);
1554
1555
                // Session coach can see all events inside a session.
1556
                if (api_is_coach()) {
1557
                    // Own course
1558
                    $this->getCourseEvents(
1559
                        $start,
1560
                        $end,
1561
                        $courseInfo,
1562
                        $groupId,
1563
                        $this->sessionId,
1564
                        $user_id
1565
                    );
1566
1567
                    // Others
1568
                    $this->getSessionEvents(
1569
                        $start,
1570
                        $end,
1571
                        $this->sessionId,
1572
                        $user_id,
1573
                        $this->eventOtherSessionColor
1574
                    );
1575
                } else {
1576
                    $this->getCourseEvents(
1577
                        $start,
1578
                        $end,
1579
                        $courseInfo,
1580
                        $groupId,
1581
                        $this->sessionId,
1582
                        $user_id
1583
                    );
1584
                }
1585
                break;
1586
            case 'personal':
1587
            default:
1588
                $sessionFilterActive = false;
1589
                if (!empty($this->sessionId)) {
1590
                    $sessionFilterActive = true;
1591
                }
1592
1593
                if ($sessionFilterActive == false) {
1594
                    // Getting personal events
1595
                    $this->getPersonalEvents($start, $end);
1596
1597
                    // Getting platform/admin events
1598
                    $this->getPlatformEvents($start, $end);
1599
                }
1600
1601
                $ignoreVisibility = api_get_configuration_value('personal_agenda_show_all_session_events');
1602
1603
                $session_list = [];
1604
                // Getting course events
1605
                $my_course_list = [];
1606
                if (!api_is_anonymous()) {
1607
                    $session_list = SessionManager::get_sessions_by_user(
1608
                        api_get_user_id(),
1609
                        $ignoreVisibility
1610
                    );
1611
                    $my_course_list = CourseManager::get_courses_list_by_user_id(
1612
                        api_get_user_id(),
1613
                        false
1614
                    );
1615
                }
1616
1617
                if (api_is_drh()) {
1618
                    if (api_drh_can_access_all_session_content()) {
1619
                        $session_list = [];
1620
                        $sessionList = SessionManager::get_sessions_followed_by_drh(
1621
                            api_get_user_id(),
1622
                            null,
1623
                            null,
1624
                            null,
1625
                            true,
1626
                            false
1627
                        );
1628
1629
                        if (!empty($sessionList)) {
1630
                            foreach ($sessionList as $sessionItem) {
1631
                                $sessionId = $sessionItem['id'];
1632
                                $courses = SessionManager::get_course_list_by_session_id($sessionId);
1633
                                $sessionInfo = [
1634
                                    'session_id' => $sessionId,
1635
                                    'courses' => $courses,
1636
                                ];
1637
                                $session_list[] = $sessionInfo;
1638
                            }
1639
                        }
1640
                    }
1641
                }
1642
1643
                if (!empty($session_list)) {
1644
                    foreach ($session_list as $session_item) {
1645
                        if ($sessionFilterActive) {
1646
                            if ($this->sessionId != $session_item['session_id']) {
1647
                                continue;
1648
                            }
1649
                        }
1650
1651
                        $my_courses = $session_item['courses'];
1652
                        $my_session_id = $session_item['session_id'];
1653
1654
                        if (!empty($my_courses)) {
1655
                            foreach ($my_courses as $course_item) {
1656
                                $courseInfo = api_get_course_info_by_id(
1657
                                    $course_item['real_id']
1658
                                );
1659
                                $this->getCourseEvents(
1660
                                    $start,
1661
                                    $end,
1662
                                    $courseInfo,
1663
                                    0,
1664
                                    $my_session_id
1665
                                );
1666
                            }
1667
                        }
1668
                    }
1669
                }
1670
1671
                if (!empty($my_course_list) && $sessionFilterActive == false) {
1672
                    foreach ($my_course_list as $courseInfoItem) {
1673
                        $courseInfo = api_get_course_info_by_id(
1674
                            $courseInfoItem['real_id']
1675
                        );
1676
                        if (isset($courseId) && !empty($courseId)) {
1677
                            if ($courseInfo['real_id'] == $courseId) {
1678
                                $this->getCourseEvents(
1679
                                    $start,
1680
                                    $end,
1681
                                    $courseInfo,
1682
                                    0,
1683
                                    0,
1684
                                    $user_id
1685
                                );
1686
                            }
1687
                        } else {
1688
                            $this->getCourseEvents(
1689
                                $start,
1690
                                $end,
1691
                                $courseInfo,
1692
                                0,
1693
                                0,
1694
                                $user_id
1695
                            );
1696
                        }
1697
                    }
1698
                }
1699
1700
                if ($start && $end) {
1701
                    $this->loadSessionsAsEvents($start, $end);
1702
                }
1703
1704
                break;
1705
        }
1706
1707
        if (api_get_configuration_value('agenda_reminders')) {
1708
            $this->events = array_map(
1709
                function (array $eventInfo) {
1710
                    $id = str_replace(['personal_', 'course_', 'session_'], '', $eventInfo['id']);
1711
1712
                    $eventInfo['reminders'] = $this->parseEventReminders(
1713
                        $this->getEventReminders(
1714
                            $id,
1715
                            'session' === $eventInfo['type'] ? 'course' : $eventInfo['type']
1716
                        )
1717
                    );
1718
1719
                    return $eventInfo;
1720
                },
1721
                $this->events
1722
            );
1723
        }
1724
1725
        $this->cleanEvents();
1726
1727
        switch ($format) {
1728
            case 'json':
1729
                if (empty($this->events)) {
1730
                    return '[]';
1731
                }
1732
1733
                return json_encode($this->events);
1734
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
1735
            case 'array':
1736
                if (empty($this->events)) {
1737
                    return [];
1738
                }
1739
1740
                return $this->events;
1741
                break;
1742
        }
1743
    }
1744
1745
    /**
1746
     * Clean events.
1747
     *
1748
     * @return bool
1749
     */
1750
    public function cleanEvents()
1751
    {
1752
        if (empty($this->events)) {
1753
            return false;
1754
        }
1755
1756
        foreach ($this->events as &$event) {
1757
            $event['description'] = Security::remove_XSS($event['description']);
1758
            $event['title'] = Security::remove_XSS($event['title']);
1759
        }
1760
1761
        return true;
1762
    }
1763
1764
    /**
1765
     * @param int $id
1766
     * @param int $minute_delta
1767
     *
1768
     * @return int
1769
     */
1770
    public function resizeEvent($id, $minute_delta)
1771
    {
1772
        $id = (int) $id;
1773
        $delta = (int) $minute_delta;
1774
        $event = $this->get_event($id);
1775
        if (!empty($event)) {
1776
            switch ($this->type) {
1777
                case 'personal':
1778
                    $sql = "UPDATE $this->tbl_personal_agenda SET
1779
                            enddate = DATE_ADD(enddate, INTERVAL $delta MINUTE)
1780
							WHERE id = ".$id;
1781
                    Database::query($sql);
1782
                    break;
1783
                case 'course':
1784
                    $sql = "UPDATE $this->tbl_course_agenda SET
1785
                            end_date = DATE_ADD(end_date, INTERVAL $delta MINUTE)
1786
							WHERE
1787
							    c_id = ".$this->course['real_id']." AND
1788
							    id = ".$id;
1789
                    Database::query($sql);
1790
                    break;
1791
                case 'admin':
1792
                    $sql = "UPDATE $this->tbl_global_agenda SET
1793
                            end_date = DATE_ADD(end_date, INTERVAL $delta MINUTE)
1794
							WHERE id = ".$id;
1795
                    Database::query($sql);
1796
                    break;
1797
            }
1798
        }
1799
1800
        return 1;
1801
    }
1802
1803
    /**
1804
     * @param int $id
1805
     * @param int $minute_delta minutes
1806
     * @param int $allDay
1807
     *
1808
     * @return int
1809
     */
1810
    public function move_event($id, $minute_delta, $allDay)
1811
    {
1812
        $id = (int) $id;
1813
        $event = $this->get_event($id);
1814
1815
        if (empty($event)) {
1816
            return false;
1817
        }
1818
1819
        // we convert the hour delta into minutes and add the minute delta
1820
        $delta = (int) $minute_delta;
1821
        $allDay = (int) $allDay;
1822
1823
        if (!empty($event)) {
1824
            switch ($this->type) {
1825
                case 'personal':
1826
                    $sql = "UPDATE $this->tbl_personal_agenda SET
1827
                            all_day = $allDay, date = DATE_ADD(date, INTERVAL $delta MINUTE),
1828
                            enddate = DATE_ADD(enddate, INTERVAL $delta MINUTE)
1829
							WHERE id=".$id;
1830
                    Database::query($sql);
1831
                    break;
1832
                case 'course':
1833
                    $sql = "UPDATE $this->tbl_course_agenda SET
1834
                            all_day = $allDay,
1835
                            start_date = DATE_ADD(start_date, INTERVAL $delta MINUTE),
1836
                            end_date = DATE_ADD(end_date, INTERVAL $delta MINUTE)
1837
							WHERE
1838
							    c_id = ".$this->course['real_id']." AND
1839
							    id=".$id;
1840
                    Database::query($sql);
1841
                    break;
1842
                case 'admin':
1843
                    $sql = "UPDATE $this->tbl_global_agenda SET
1844
                            all_day = $allDay,
1845
                            start_date = DATE_ADD(start_date,INTERVAL $delta MINUTE),
1846
                            end_date = DATE_ADD(end_date, INTERVAL $delta MINUTE)
1847
							WHERE id=".$id;
1848
                    Database::query($sql);
1849
                    break;
1850
            }
1851
        }
1852
1853
        return 1;
1854
    }
1855
1856
    /**
1857
     * Gets a single event.
1858
     *
1859
     * @param int $id event id
1860
     *
1861
     * @return array
1862
     */
1863
    public function get_event($id)
1864
    {
1865
        // make sure events of the personal agenda can only be seen by the user himself
1866
        $id = (int) $id;
1867
        $event = null;
1868
        $agendaCollectiveInvitations = api_get_configuration_value('agenda_collective_invitations');
1869
1870
        switch ($this->type) {
1871
            case 'personal':
1872
                $user = api_get_user_entity(api_get_user_id());
1873
                $sql = "SELECT * FROM ".$this->tbl_personal_agenda."
1874
                        WHERE id = $id AND user = ".$user->getId();
1875
                $result = Database::query($sql);
1876
                if (Database::num_rows($result)) {
1877
                    $event = Database::fetch_array($result, 'ASSOC');
1878
                    $event['description'] = $event['text'];
1879
                    $event['content'] = Security::remove_XSS($event['text'], STUDENT);
1880
                    $event['start_date'] = $event['date'];
1881
                    $event['end_date'] = $event['enddate'];
1882
                }
1883
1884
                if (null !== $event) {
1885
                    return $event;
1886
                }
1887
1888
                if ($agendaCollectiveInvitations) {
1889
                    $eventRepo = Database::getManager()->getRepository('ChamiloCoreBundle:PersonalAgenda');
1890
                    $event = $eventRepo->findOneByIdAndInvitee($id, $user);
1891
1892
                    if ($event && $event->isCollective()) {
1893
                        return [
1894
                            'id' => $event->getId(),
1895
                            'user' => $event->getUser(),
1896
                            'title' => $event->getTitle(),
1897
                            'text' => $event->getText(),
1898
                            'date' => $event->getDate()->format('Y-m-d H:i:s'),
1899
                            'enddate' => $event->getEndDate()->format('Y-m-d H:i:s'),
1900
                            'course' => null,
1901
                            'parent_event_id' => $event->getParentEventId(),
1902
                            'all_day' => $event->getAllDay(),
1903
                            'color' => $event->getColor(),
1904
                            'agenda_event_invitation_id' => $event->getInvitation()->getId(),
1905
                            'collective' => $event->isCollective(),
1906
                            'description' => $event->getText(),
1907
                            'content' => Security::remove_XSS($event->getText(), STUDENT),
1908
                            'start_date' => $event->getDate()->format('Y-m-d H:i:s'),
1909
                            'end_date' => $event->getEndDate()->format('Y-m-d H:i:s'),
1910
                        ];
1911
                    }
1912
                }
1913
1914
                return null;
1915
            case 'course':
1916
                if (!empty($this->course['real_id'])) {
1917
                    $sql = "SELECT * FROM ".$this->tbl_course_agenda."
1918
                            WHERE c_id = ".$this->course['real_id']." AND id = ".$id;
1919
                    $result = Database::query($sql);
1920
                    if (Database::num_rows($result)) {
1921
                        $event = Database::fetch_array($result, 'ASSOC');
1922
                        $event['description'] = Security::remove_XSS($event['content'], STUDENT);
1923
1924
                        // Getting send to array
1925
                        $event['send_to'] = $this->getUsersAndGroupSubscribedToEvent(
1926
                            $id,
1927
                            $this->course['real_id'],
1928
                            $this->sessionId
1929
                        );
1930
1931
                        // Getting repeat info
1932
                        $event['repeat_info'] = $this->getRepeatedInfoByEvent(
1933
                            $id,
1934
                            $this->course['real_id']
1935
                        );
1936
1937
                        if (!empty($event['parent_event_id'])) {
1938
                            $event['parent_info'] = $this->get_event($event['parent_event_id']);
1939
                        }
1940
1941
                        $event['attachment'] = $this->getAttachmentList(
1942
                            $id,
1943
                            $this->course
1944
                        );
1945
                    }
1946
                }
1947
                break;
1948
            case 'admin':
1949
            case 'platform':
1950
                $sql = "SELECT * FROM ".$this->tbl_global_agenda."
1951
                        WHERE id = $id";
1952
                $result = Database::query($sql);
1953
                if (Database::num_rows($result)) {
1954
                    $event = Database::fetch_array($result, 'ASSOC');
1955
                    $event['description'] = Security::remove_XSS($event['content']);
1956
                }
1957
                break;
1958
        }
1959
1960
        return $event;
1961
    }
1962
1963
    /**
1964
     * Gets personal events.
1965
     *
1966
     * @param int $start
1967
     * @param int $end
1968
     *
1969
     * @return array
1970
     */
1971
    public function getPersonalEvents($start, $end)
1972
    {
1973
        $start = (int) $start;
1974
        $end = (int) $end;
1975
        $startDate = null;
1976
        $endDate = null;
1977
        $startCondition = '';
1978
        $endCondition = '';
1979
1980
        $agendaCollectiveInvitations = api_get_configuration_value('agenda_collective_invitations');
1981
        $agendaEventSubscriptions = api_get_configuration_value('agenda_event_subscriptions');
1982
        $userIsAdmin = api_is_platform_admin();
1983
1984
        $queryParams = [];
1985
1986
        if ($start !== 0) {
1987
            $queryParams['start_date'] = api_get_utc_datetime($start, true, true);
1988
            $startCondition = "AND pa.date >= :start_date";
1989
        }
1990
        if ($end !== 0) {
1991
            $queryParams['end_date'] = api_get_utc_datetime($end, false, true);
1992
            $endCondition = "AND (pa.enddate <= :end_date OR pa.enddate IS NULL)";
1993
        }
1994
        $user_id = api_get_user_id();
1995
1996
        $queryParams['user_id'] = $user_id;
1997
        $userCondition = "pa.user = :user_id";
1998
1999
        $objGroup = new UserGroup();
2000
2001
        if ($agendaEventSubscriptions) {
2002
            $groupList = $objGroup->getUserGroupListByUser($user_id, UserGroup::NORMAL_CLASS);
2003
2004
            $userCondition = "(
2005
                    $userCondition
2006
                    OR (
2007
                        pa.subscriptionVisibility = ".AgendaEventSubscription::SUBSCRIPTION_ALL;
2008
2009
            if ($groupList) {
2010
                $userCondition .= "
2011
                        OR (
2012
                            pa.subscriptionVisibility = ".AgendaEventSubscription::SUBSCRIPTION_CLASS."
2013
                            AND pa.subscriptionItemId IN (".implode(', ', array_column($groupList, 'id')).")
2014
                        )
2015
                ";
2016
            }
2017
2018
            $userCondition .= "
2019
                    )
2020
                )
2021
            ";
2022
        }
2023
2024
        $sql = "SELECT pa FROM ChamiloCoreBundle:PersonalAgenda AS pa WHERE $userCondition $startCondition $endCondition";
2025
2026
        $result = Database::getManager()
2027
            ->createQuery($sql)
2028
            ->setParameters($queryParams)
2029
            ->getResult();
2030
2031
        $my_events = [];
2032
2033
        /** @var PersonalAgenda $row */
2034
        foreach ($result as $row) {
2035
            $event = [];
2036
            $event['id'] = 'personal_'.$row->getId();
2037
            $event['title'] = $row->getTitle();
2038
            $event['className'] = 'personal';
2039
            $event['borderColor'] = $event['backgroundColor'] = $this->event_personal_color;
2040
            $event['editable'] = $user_id === (int) $row->getUser();
2041
            $event['sent_to'] = get_lang('Me');
2042
            $event['type'] = 'personal';
2043
2044
            if (!empty($row->getDate())) {
2045
                $event['start'] = $this->formatEventDate($row->getDate());
2046
                $event['start_date_localtime'] = api_get_local_time($row->getDate());
2047
            }
2048
2049
            if (!empty($row->getEnddate())) {
2050
                $event['end'] = $this->formatEventDate($row->getEnddate());
2051
                $event['end_date_localtime'] = api_get_local_time($row->getEnddate());
2052
            }
2053
2054
            $event['description'] = $row->getText();
2055
            $event['allDay'] = $row->getAllDay();
2056
            $event['parent_event_id'] = 0;
2057
            $event['has_children'] = 0;
2058
2059
            if ($agendaCollectiveInvitations || $agendaEventSubscriptions) {
2060
                $subscription = $row->getInvitation();
2061
2062
                if ($subscription instanceof AgendaEventSubscription) {
2063
                    $subscribers = $subscription->getInvitees();
2064
2065
                    $event['subscription_visibility'] = $row->getSubscriptionVisibility();
2066
                    $event['max_subscriptions'] = $subscription->getMaxAttendees();
2067
                    $event['can_subscribe'] = $subscribers->count() < $subscription->getMaxAttendees()
2068
                        || $subscription->getMaxAttendees() === 0;
2069
                    $event['user_is_subscribed'] = $subscription->hasUserAsInvitee(api_get_user_entity($user_id));
2070
                    $event['count_subscribers'] = $subscribers->count();
2071
2072
                    if ($userIsAdmin) {
2073
                        $event['subscribers'] = self::getInviteesForPersonalEvent($row->getId(), AgendaEventSubscriber::class);
2074
                    }
2075
2076
                    if (AgendaEventSubscription::SUBSCRIPTION_CLASS === $row->getSubscriptionVisibility()) {
2077
                        $groupInfo = $objGroup->get($row->getSubscriptionItemId());
2078
                        $event['usergroup'] = $groupInfo['name'];
2079
                    }
2080
                } else {
2081
                    $event['collective'] = $row->isCollective();
2082
                    $event['invitees'] = self::getInviteesForPersonalEvent($row->getId());
2083
                }
2084
            }
2085
2086
            $my_events[] = $event;
2087
            $this->events[] = $event;
2088
        }
2089
2090
        if ($agendaCollectiveInvitations) {
2091
            $this->loadEventsAsInvitee(
2092
                api_get_user_entity($user_id),
2093
                $startDate,
2094
                $endDate
2095
            );
2096
        }
2097
2098
        // Add plugin personal events
2099
2100
        $this->plugin = new AppPlugin();
2101
        $plugins = $this->plugin->getInstalledPluginListObject();
2102
        /** @var Plugin $plugin */
2103
        foreach ($plugins as $plugin) {
2104
            if ($plugin->hasPersonalEvents && method_exists($plugin, 'getPersonalEvents')) {
2105
                $pluginEvents = $plugin->getPersonalEvents($this, $start, $end);
2106
2107
                if (!empty($pluginEvents)) {
2108
                    $this->events = array_merge($this->events, $pluginEvents);
2109
                }
2110
            }
2111
        }
2112
2113
        return $my_events;
2114
    }
2115
2116
    public static function getInviteesForPersonalEvent($eventId, $type = AgendaEventInvitee::class): array
2117
    {
2118
        $em = Database::getManager();
2119
        $event = $em->find('ChamiloCoreBundle:PersonalAgenda', $eventId);
2120
2121
        $invitation = $event->getInvitation();
2122
2123
        if ($invitation instanceof AgendaEventSubscription
2124
            && AgendaEventInvitee::class === $type
2125
        ) {
2126
            return [];
2127
        }
2128
2129
        $inviteeRepo = $em->getRepository($type);
2130
        $invitees = $inviteeRepo->findByInvitation($invitation);
2131
2132
        $inviteeList = [];
2133
2134
        foreach ($invitees as $invitee) {
2135
            $inviteeUser = $invitee->getUser();
2136
2137
            $inviteeList[] = [
2138
                'id' => $inviteeUser->getId(),
2139
                'name' => $inviteeUser->getCompleteNameWithUsername(),
2140
            ];
2141
        }
2142
2143
        return $inviteeList;
2144
    }
2145
2146
    /**
2147
     * Get user/group list per event.
2148
     *
2149
     * @param int $eventId
2150
     * @param int $courseId
2151
     * @param int $sessionId
2152
     * @paraù int $sessionId
2153
     *
2154
     * @return array
2155
     */
2156
    public function getUsersAndGroupSubscribedToEvent(
2157
        $eventId,
2158
        $courseId,
2159
        $sessionId
2160
    ) {
2161
        $eventId = (int) $eventId;
2162
        $courseId = (int) $courseId;
2163
        $sessionId = (int) $sessionId;
2164
2165
        $sessionCondition = "ip.session_id = $sessionId";
2166
        if (empty($sessionId)) {
2167
            $sessionCondition = " (ip.session_id = 0 OR ip.session_id IS NULL) ";
2168
        }
2169
2170
        $tlb_course_agenda = Database::get_course_table(TABLE_AGENDA);
2171
        $tbl_property = Database::get_course_table(TABLE_ITEM_PROPERTY);
2172
2173
        // Get sent_tos
2174
        $sql = "SELECT DISTINCT to_user_id, to_group_id
2175
                FROM $tbl_property ip
2176
                INNER JOIN $tlb_course_agenda agenda
2177
                ON (
2178
                  ip.ref = agenda.id AND
2179
                  ip.c_id = agenda.c_id AND
2180
                  ip.tool = '".TOOL_CALENDAR_EVENT."'
2181
                )
2182
                WHERE
2183
                    ref = $eventId AND
2184
                    ip.visibility = '1' AND
2185
                    ip.c_id = $courseId AND
2186
                    $sessionCondition
2187
                ";
2188
2189
        $result = Database::query($sql);
2190
        $users = [];
2191
        $groups = [];
2192
        $everyone = false;
2193
2194
        while ($row = Database::fetch_array($result, 'ASSOC')) {
2195
            if (!empty($row['to_group_id'])) {
2196
                $groups[] = $row['to_group_id'];
2197
            }
2198
            if (!empty($row['to_user_id'])) {
2199
                $users[] = $row['to_user_id'];
2200
            }
2201
2202
            if (empty($groups) && empty($users)) {
2203
                if ($row['to_group_id'] == 0) {
2204
                    $everyone = true;
2205
                }
2206
            }
2207
        }
2208
2209
        return [
2210
            'everyone' => $everyone,
2211
            'users' => $users,
2212
            'groups' => $groups,
2213
        ];
2214
    }
2215
2216
    /**
2217
     * @param int    $start
2218
     * @param int    $end
2219
     * @param int    $sessionId
2220
     * @param int    $userId
2221
     * @param string $color
2222
     *
2223
     * @return array
2224
     */
2225
    public function getSessionEvents(
2226
        $start,
2227
        $end,
2228
        $sessionId = 0,
2229
        $userId = 0,
2230
        $color = ''
2231
    ) {
2232
        $courses = SessionManager::get_course_list_by_session_id($sessionId);
2233
2234
        if (!empty($courses)) {
2235
            foreach ($courses as $course) {
2236
                $this->getCourseEvents(
2237
                    $start,
2238
                    $end,
2239
                    $course,
2240
                    0,
2241
                    $sessionId,
2242
                    0,
2243
                    $color
2244
                );
2245
            }
2246
        }
2247
    }
2248
2249
    /**
2250
     * @param int    $start
2251
     * @param int    $end
2252
     * @param array  $courseInfo
2253
     * @param int    $groupId
2254
     * @param int    $sessionId
2255
     * @param int    $user_id
2256
     * @param string $color
2257
     *
2258
     * @return array
2259
     */
2260
    public function getCourseEvents(
2261
        $start,
2262
        $end,
2263
        $courseInfo,
2264
        $groupId = 0,
2265
        $sessionId = 0,
2266
        $user_id = 0,
2267
        $color = ''
2268
    ) {
2269
        $start = isset($start) && !empty($start) ? api_get_utc_datetime(intval($start)) : null;
2270
        $end = isset($end) && !empty($end) ? api_get_utc_datetime(intval($end)) : null;
2271
2272
        if (empty($courseInfo)) {
2273
            return [];
2274
        }
2275
        $courseId = $courseInfo['real_id'];
2276
2277
        if (empty($courseId)) {
2278
            return [];
2279
        }
2280
2281
        $sessionId = (int) $sessionId;
2282
        $user_id = (int) $user_id;
2283
2284
        $groupList = GroupManager::get_group_list(
2285
            null,
2286
            $courseInfo,
2287
            null,
2288
            $sessionId
2289
        );
2290
2291
        $groupNameList = [];
2292
        if (!empty($groupList)) {
2293
            foreach ($groupList as $group) {
2294
                $groupNameList[$group['iid']] = $group['name'];
2295
            }
2296
        }
2297
2298
        if (api_is_platform_admin() || api_is_allowed_to_edit()) {
2299
            $isAllowToEdit = true;
2300
        } else {
2301
            $isAllowToEdit = CourseManager::is_course_teacher(
2302
                api_get_user_id(),
2303
                $courseInfo['code']
2304
            );
2305
        }
2306
2307
        $isAllowToEditByHrm = false;
2308
        if (!empty($sessionId)) {
2309
            $allowDhrToEdit = api_get_configuration_value('allow_agenda_edit_for_hrm');
2310
            if ($allowDhrToEdit) {
2311
                $isHrm = SessionManager::isUserSubscribedAsHRM($sessionId, api_get_user_id());
2312
                if ($isHrm) {
2313
                    $isAllowToEdit = $isAllowToEditByHrm = true;
2314
                }
2315
            }
2316
        }
2317
2318
        $groupMemberships = [];
2319
        if (!empty($groupId)) {
2320
            $groupMemberships = [$groupId];
2321
        } else {
2322
            if ($isAllowToEdit) {
2323
                if (!empty($groupList)) {
2324
                    // c_item_property.to_group_id field was migrated to use
2325
                    // c_group_info.iid
2326
                    $groupMemberships = array_column($groupList, 'iid');
2327
                }
2328
            } else {
2329
                // get only related groups from user
2330
                $groupMemberships = GroupManager::get_group_ids(
2331
                    $courseId,
2332
                    api_get_user_id()
2333
                );
2334
            }
2335
        }
2336
2337
        $tlb_course_agenda = Database::get_course_table(TABLE_AGENDA);
2338
        $tbl_property = Database::get_course_table(TABLE_ITEM_PROPERTY);
2339
2340
        $shareEventsInSessions = 1 == api_get_course_setting('agenda_share_events_in_sessions', $courseInfo);
2341
2342
        $agendaSessionCondition = str_replace(
2343
            ' AND ',
2344
            '',
2345
            api_get_session_condition($sessionId, true, $shareEventsInSessions, 'agenda.session_id')
2346
        );
2347
        $ipSessionCondition = api_get_session_condition($sessionId, true, $shareEventsInSessions, 'ip.session_id');
2348
2349
        $sessionCondition = "($agendaSessionCondition $ipSessionCondition)";
2350
2351
        if ($isAllowToEdit) {
2352
            // No group filter was asked
2353
            if (empty($groupId)) {
2354
                if (empty($user_id)) {
2355
                    // Show all events not added in group
2356
                    $userCondition = ' (ip.to_group_id IS NULL OR ip.to_group_id = 0) ';
2357
                    // admin see only his stuff
2358
                    if ($this->type === 'personal') {
2359
                        $userCondition = " (ip.to_user_id = ".api_get_user_id()." AND (ip.to_group_id IS NULL OR ip.to_group_id = 0) ) ";
2360
                        $userCondition .= " OR ( (ip.to_user_id = 0 OR ip.to_user_id is NULL)  AND (ip.to_group_id IS NULL OR ip.to_group_id = 0) ) ";
2361
                    }
2362
2363
                    if (!empty($groupMemberships)) {
2364
                        // Show events sent to selected groups
2365
                        $userCondition .= " OR (ip.to_user_id = 0 OR ip.to_user_id is NULL) AND (ip.to_group_id IN (".implode(", ", $groupMemberships).")) ";
2366
                    }
2367
                } else {
2368
                    // Show events of requested user in no group
2369
                    $userCondition = " (ip.to_user_id = $user_id AND (ip.to_group_id IS NULL OR ip.to_group_id = 0)) ";
2370
                    // Show events sent to selected groups
2371
                    if (!empty($groupMemberships)) {
2372
                        $userCondition .= " OR (ip.to_user_id = $user_id) AND (ip.to_group_id IN (".implode(", ", $groupMemberships).")) ";
2373
                    }
2374
                }
2375
            } else {
2376
                // Show only selected groups (depending of user status)
2377
                $userCondition = " (ip.to_user_id = 0 OR ip.to_user_id is NULL) AND (ip.to_group_id IN (".implode(", ", $groupMemberships).")) ";
2378
2379
                if (!empty($groupMemberships)) {
2380
                    // Show send to $user_id in selected groups
2381
                    $userCondition .= " OR (ip.to_user_id = $user_id) AND (ip.to_group_id IN (".implode(", ", $groupMemberships).")) ";
2382
                }
2383
            }
2384
        } else {
2385
            // No group filter was asked
2386
            if (empty($groupId)) {
2387
                // Show events sent to everyone and no group
2388
                $userCondition = ' ( (ip.to_user_id = 0 OR ip.to_user_id is NULL) AND (ip.to_group_id IS NULL OR ip.to_group_id = 0) ';
2389
2390
                // Show events sent to selected groups
2391
                if (!empty($groupMemberships)) {
2392
                    $userCondition .= " OR (ip.to_user_id = 0 OR ip.to_user_id is NULL) AND (ip.to_group_id IN (".implode(", ", $groupMemberships)."))) ";
2393
                } else {
2394
                    $userCondition .= " ) ";
2395
                }
2396
                $userCondition .= " OR (ip.to_user_id = ".api_get_user_id()." AND (ip.to_group_id IS NULL OR ip.to_group_id = 0)) ";
2397
            } else {
2398
                if (!empty($groupMemberships)) {
2399
                    // Show send to everyone - and only selected groups
2400
                    $userCondition = " (ip.to_user_id = 0 OR ip.to_user_id is NULL) AND (ip.to_group_id IN (".implode(", ", $groupMemberships).")) ";
2401
                }
2402
            }
2403
2404
            // Show sent to only me and no group
2405
            if (!empty($groupMemberships)) {
2406
                $userCondition .= " OR (ip.to_user_id = ".api_get_user_id().") AND (ip.to_group_id IN (".implode(", ", $groupMemberships).")) ";
2407
            } else {
2408
                // Show sent to only me and selected groups
2409
            }
2410
        }
2411
2412
        if (api_is_allowed_to_edit()) {
2413
            $visibilityCondition = " (ip.visibility IN ('1', '0'))  ";
2414
        } else {
2415
            $visibilityCondition = " (ip.visibility = '1') ";
2416
        }
2417
2418
        $sql = "SELECT DISTINCT
2419
                    agenda.*,
2420
                    ip.visibility,
2421
                    ip.to_group_id,
2422
                    ip.insert_user_id,
2423
                    ip.ref,
2424
                    to_user_id
2425
                FROM $tlb_course_agenda agenda
2426
                INNER JOIN $tbl_property ip
2427
                ON (
2428
                    agenda.id = ip.ref AND
2429
                    agenda.c_id = ip.c_id AND
2430
                    ip.tool = '".TOOL_CALENDAR_EVENT."'
2431
                )
2432
                WHERE
2433
                    $sessionCondition AND
2434
                    ($userCondition) AND
2435
                    $visibilityCondition AND
2436
                    agenda.c_id = $courseId
2437
        ";
2438
        $dateCondition = '';
2439
        if (!empty($start) && !empty($end)) {
2440
            $dateCondition .= "AND (
2441
                 agenda.start_date BETWEEN '".$start."' AND '".$end."' OR
2442
                 agenda.end_date BETWEEN '".$start."' AND '".$end."' OR
2443
                 (
2444
                     agenda.start_date IS NOT NULL AND agenda.end_date IS NOT NULL AND
2445
                     YEAR(agenda.start_date) = YEAR(agenda.end_date) AND
2446
                     MONTH('$start') BETWEEN MONTH(agenda.start_date) AND MONTH(agenda.end_date)
2447
                 )
2448
            )";
2449
        }
2450
2451
        $sql .= $dateCondition;
2452
        $result = Database::query($sql);
2453
2454
        $coachCanEdit = false;
2455
        if (!empty($sessionId)) {
2456
            $coachCanEdit = api_is_coach($sessionId, $courseId) || api_is_platform_admin();
2457
        }
2458
2459
        if (Database::num_rows($result)) {
2460
            $eventsAdded = array_column($this->events, 'unique_id');
2461
            while ($row = Database::fetch_array($result, 'ASSOC')) {
2462
                $event = [];
2463
                $event['id'] = 'course_'.$row['id'];
2464
                $event['unique_id'] = $row['iid'];
2465
                // To avoid doubles
2466
                if (in_array($event['unique_id'], $eventsAdded)) {
2467
                    continue;
2468
                }
2469
2470
                $eventsAdded[] = $event['unique_id'];
2471
                $eventId = $row['ref'];
2472
                $items = $this->getUsersAndGroupSubscribedToEvent(
2473
                    $eventId,
2474
                    $courseId,
2475
                    $this->sessionId
2476
                );
2477
                $group_to_array = $items['groups'];
2478
                $user_to_array = $items['users'];
2479
                $attachmentList = $this->getAttachmentList(
2480
                    $row['id'],
2481
                    $courseInfo
2482
                );
2483
                $event['attachment'] = '';
2484
                if (!empty($attachmentList)) {
2485
                    foreach ($attachmentList as $attachment) {
2486
                        $has_attachment = Display::return_icon(
2487
                            'attachment.gif',
2488
                            get_lang('Attachment')
2489
                        );
2490
                        $user_filename = $attachment['filename'];
2491
                        $url = api_get_path(WEB_CODE_PATH).'calendar/download.php?file='.$attachment['path'].'&course_id='.$courseId.'&'.api_get_cidreq();
2492
                        $event['attachment'] .= $has_attachment.
2493
                            Display::url(
2494
                                $user_filename,
2495
                                $url
2496
                            ).'<br />';
2497
                    }
2498
                }
2499
2500
                $event['title'] = $row['title'];
2501
                $event['className'] = 'course';
2502
                $event['allDay'] = 'false';
2503
                $event['course_id'] = $courseId;
2504
                $event['borderColor'] = $event['backgroundColor'] = $this->event_course_color;
2505
2506
                $sessionInfo = [];
2507
                if (isset($row['session_id']) && !empty($row['session_id'])) {
2508
                    $sessionInfo = api_get_session_info($sessionId);
2509
                    $event['borderColor'] = $event['backgroundColor'] = $this->event_session_color;
2510
                }
2511
2512
                $event['session_name'] = isset($sessionInfo['name']) ? $sessionInfo['name'] : '';
2513
                $event['course_name'] = isset($courseInfo['title']) ? $courseInfo['title'] : '';
2514
2515
                if (isset($row['to_group_id']) && !empty($row['to_group_id'])) {
2516
                    $event['borderColor'] = $event['backgroundColor'] = $this->event_group_color;
2517
                }
2518
2519
                if (!empty($color)) {
2520
                    $event['borderColor'] = $event['backgroundColor'] = $color;
2521
                }
2522
2523
                if (isset($row['color']) && !empty($row['color'])) {
2524
                    $event['borderColor'] = $event['backgroundColor'] = $row['color'];
2525
                }
2526
2527
                $event['editable'] = false;
2528
                if ($this->getIsAllowedToEdit() && $this->type == 'course') {
2529
                    $event['editable'] = true;
2530
                    if (!empty($sessionId)) {
2531
                        if ($coachCanEdit == false) {
2532
                            $event['editable'] = false;
2533
                        }
2534
                        if ($isAllowToEditByHrm) {
2535
                            $event['editable'] = true;
2536
                        }
2537
                        if ($sessionId != $row['session_id']) {
2538
                            $event['editable'] = false;
2539
                        }
2540
                    }
2541
                    // if user is author then he can edit the item
2542
                    if (api_get_user_id() == $row['insert_user_id']) {
2543
                        $event['editable'] = true;
2544
                    }
2545
                }
2546
2547
                if (!empty($row['start_date'])) {
2548
                    $event['start'] = $this->formatEventDate($row['start_date']);
2549
                    $event['start_date_localtime'] = api_get_local_time($row['start_date']);
2550
                }
2551
                if (!empty($row['end_date'])) {
2552
                    $event['end'] = $this->formatEventDate($row['end_date']);
2553
                    $event['end_date_localtime'] = api_get_local_time($row['end_date']);
2554
                }
2555
2556
                $event['sent_to'] = '';
2557
                $event['type'] = 'course';
2558
                if ($row['session_id'] != 0) {
2559
                    $event['type'] = 'session';
2560
                }
2561
2562
                // Event Sent to a group?
2563
                if (isset($row['to_group_id']) && !empty($row['to_group_id'])) {
2564
                    $sent_to = [];
2565
                    if (!empty($group_to_array)) {
2566
                        foreach ($group_to_array as $group_item) {
2567
                            $sent_to[] = $groupNameList[$group_item];
2568
                        }
2569
                    }
2570
                    $sent_to = implode('@@', $sent_to);
2571
                    $sent_to = str_replace(
2572
                        '@@',
2573
                        '</div><div class="label_tag notice">',
2574
                        $sent_to
2575
                    );
2576
                    $event['sent_to'] = '<div class="label_tag notice">'.$sent_to.'</div>';
2577
                    $event['type'] = 'group';
2578
                    $event['group_id'] = $row['to_group_id'];
2579
                }
2580
2581
                // Event sent to a user?
2582
                if (isset($row['to_user_id'])) {
2583
                    $sent_to = [];
2584
                    if (!empty($user_to_array)) {
2585
                        foreach ($user_to_array as $item) {
2586
                            $user_info = api_get_user_info($item);
2587
                            // Add username as tooltip for $event['sent_to'] - ref #4226
2588
                            $username = api_htmlentities(
2589
                                sprintf(
2590
                                    get_lang('LoginX'),
2591
                                    $user_info['username']
2592
                                ),
2593
                                ENT_QUOTES
2594
                            );
2595
                            $sent_to[] = "<span title='".$username."'>".$user_info['complete_name']."</span>";
2596
                        }
2597
                    }
2598
                    $sent_to = implode('@@', $sent_to);
2599
                    $sent_to = str_replace(
2600
                        '@@',
2601
                        '</div><div class="label_tag notice">',
2602
                        $sent_to
2603
                    );
2604
                    $event['sent_to'] = '<div class="label_tag notice">'.$sent_to.'</div>';
2605
                }
2606
2607
                //Event sent to everyone!
2608
                if (empty($event['sent_to'])) {
2609
                    $event['sent_to'] = '<div class="label_tag notice">'.get_lang('Everyone').'</div>';
2610
                }
2611
2612
                $event['description'] = Security::remove_XSS($row['content']);
2613
                $event['visibility'] = $row['visibility'];
2614
                $event['real_id'] = $row['id'];
2615
                $event['allDay'] = isset($row['all_day']) && $row['all_day'] == 1 ? $row['all_day'] : 0;
2616
                $event['parent_event_id'] = $row['parent_event_id'];
2617
                $event['has_children'] = $this->hasChildren($row['id'], $courseId) ? 1 : 0;
2618
                $event['comment'] = Security::remove_XSS($row['comment']);
2619
                $this->events[] = $event;
2620
            }
2621
        }
2622
2623
        return $this->events;
2624
    }
2625
2626
    /**
2627
     * @param int $start tms
2628
     * @param int $end   tms
2629
     *
2630
     * @return array
2631
     */
2632
    public function getPlatformEvents($start, $end)
2633
    {
2634
        $start = isset($start) && !empty($start) ? api_get_utc_datetime(intval($start)) : null;
2635
        $end = isset($end) && !empty($end) ? api_get_utc_datetime(intval($end)) : null;
2636
        $dateCondition = '';
2637
2638
        if (!empty($start) && !empty($end)) {
2639
            $dateCondition .= "AND (
2640
                 start_date BETWEEN '".$start."' AND '".$end."' OR
2641
                 end_date BETWEEN '".$start."' AND '".$end."' OR
2642
                 (
2643
                     start_date IS NOT NULL AND end_date IS NOT NULL AND
2644
                     YEAR(start_date) = YEAR(end_date) AND
2645
                     MONTH('$start') BETWEEN MONTH(start_date) AND MONTH(end_date)
2646
                 )
2647
            )";
2648
        }
2649
2650
        $access_url_id = api_get_current_access_url_id();
2651
2652
        $sql = "SELECT *
2653
                FROM ".$this->tbl_global_agenda."
2654
                WHERE access_url_id = $access_url_id
2655
                $dateCondition";
2656
        $result = Database::query($sql);
2657
2658
        if (!Database::num_rows($result)) {
2659
            return [];
2660
        }
2661
2662
        $my_events = [];
2663
        $allowCareersInGlobalAgenda = api_get_configuration_value('allow_careers_in_global_agenda');
2664
        $userId = api_get_user_id();
2665
        $userVisibility = SystemAnnouncementManager::getCurrentUserVisibility();
2666
2667
        while ($row = Database::fetch_array($result, 'ASSOC')) {
2668
            $event = [];
2669
            $event['id'] = 'platform_'.$row['id'];
2670
            $event['title'] = $row['title'];
2671
            $event['className'] = 'platform';
2672
            $event['allDay'] = 'false';
2673
            $event['borderColor'] = $event['backgroundColor'] = $this->event_platform_color;
2674
            $event['editable'] = false;
2675
            $event['type'] = 'admin';
2676
2677
            if (api_is_platform_admin() && $this->type === 'admin') {
2678
                $event['editable'] = true;
2679
            }
2680
2681
            if (!empty($row['start_date'])) {
2682
                $event['start'] = $this->formatEventDate($row['start_date']);
2683
                $event['start_date_localtime'] = api_get_local_time($row['start_date']);
2684
            }
2685
2686
            if (!empty($row['end_date'])) {
2687
                $event['end'] = $this->formatEventDate($row['end_date']);
2688
                $event['end_date_localtime'] = api_get_local_time($row['end_date']);
2689
            }
2690
            $event['allDay'] = isset($row['all_day']) && $row['all_day'] == 1 ? $row['all_day'] : 0;
2691
            $event['parent_event_id'] = 0;
2692
            $event['has_children'] = 0;
2693
            $event['description'] = $row['content'];
2694
2695
            if ($allowCareersInGlobalAgenda) {
2696
                $event['career'] = null;
2697
                $event['promotion'] = null;
2698
2699
                $careerId = (int) $row['career_id'];
2700
                $promotionId = (int) $row['promotion_id'];
2701
2702
                $careerPromotionEventIsVisibleForUser = true;
2703
2704
                if (($careerId || $promotionId) && 'admin' !== $this->type) {
2705
                    $careerPromotionEventIsVisibleForUser = SystemAnnouncementManager::isVisibleAnnouncementForUser(
2706
                        $userId,
2707
                        $userVisibility,
2708
                        $careerId,
2709
                        $promotionId
2710
                    );
2711
                }
2712
2713
                if (false === $careerPromotionEventIsVisibleForUser) {
2714
                    continue;
2715
                }
2716
2717
                if (0 !== $careerId) {
2718
                    $careerInfo = (new Career())->get($row['career_id']);
2719
2720
                    unset($careerInfo['status'], $careerInfo['created_at'], $careerInfo['updated_at']);
2721
2722
                    $event['career'] = $careerInfo;
2723
                }
2724
2725
                if (0 !== $promotionId) {
2726
                    $promotionInfo = (new Promotion())->get($row['promotion_id']);
2727
2728
                    unset(
2729
                        $promotionInfo['career_id'],
2730
                        $promotionInfo['status'],
2731
                        $promotionInfo['created_at'],
2732
                        $promotionInfo['updated_at']
2733
                    );
2734
2735
                    $event['promotion'] = $promotionInfo;
2736
                }
2737
            }
2738
2739
            $my_events[] = $event;
2740
            $this->events[] = $event;
2741
        }
2742
2743
        return $my_events;
2744
    }
2745
2746
    /**
2747
     * @param FormValidator $form
2748
     * @param array         $groupList
2749
     * @param array         $userList
2750
     * @param array         $sendTo               array('users' => [1, 2], 'groups' => [3, 4])
2751
     * @param array         $attributes
2752
     * @param bool          $addOnlyItemsInSendTo
2753
     * @param bool          $required
2754
     */
2755
    public function setSendToSelect(
2756
        $form,
2757
        $groupList = [],
2758
        $userList = [],
2759
        $sendTo = [],
2760
        $attributes = [],
2761
        $addOnlyItemsInSendTo = false,
2762
        $required = false
2763
    ) {
2764
        $params = [
2765
            'id' => 'users_to_send_id',
2766
            'data-placeholder' => get_lang('Select'),
2767
            'multiple' => 'multiple',
2768
            'class' => 'multiple-select',
2769
        ];
2770
2771
        if (!empty($attributes)) {
2772
            $params = array_merge($params, $attributes);
2773
            if (empty($params['multiple'])) {
2774
                unset($params['multiple']);
2775
            }
2776
        }
2777
2778
        $sendToGroups = isset($sendTo['groups']) ? $sendTo['groups'] : [];
2779
        $sendToUsers = isset($sendTo['users']) ? $sendTo['users'] : [];
2780
2781
        /** @var HTML_QuickForm_select $select */
2782
        $select = $form->addSelect(
2783
            'users_to_send',
2784
            get_lang('To'),
2785
            null,
2786
            $params
2787
        );
2788
2789
        if ($required) {
2790
            $form->setRequired($select);
2791
        }
2792
2793
        $selectedEveryoneOptions = [];
2794
        if (isset($sendTo['everyone']) && $sendTo['everyone']) {
2795
            $selectedEveryoneOptions = ['selected'];
2796
            $sendToUsers = [];
2797
        }
2798
2799
        $select->addOption(
2800
            get_lang('Everyone'),
2801
            'everyone',
2802
            $selectedEveryoneOptions
2803
        );
2804
2805
        $options = [];
2806
        if (is_array($groupList)) {
2807
            foreach ($groupList as $group) {
2808
                $count_users = isset($group['count_users']) ? $group['count_users'] : $group['userNb'];
2809
                $count_users = " &ndash; $count_users ".get_lang('Users');
2810
                $option = [
2811
                    'text' => $group['name'].$count_users,
2812
                    'value' => "GROUP:".$group['id'],
2813
                ];
2814
                $selected = in_array(
2815
                    $group['id'],
2816
                    $sendToGroups
2817
                ) ? true : false;
2818
                if ($selected) {
2819
                    $option['selected'] = 'selected';
2820
                }
2821
2822
                if ($addOnlyItemsInSendTo) {
2823
                    if ($selected) {
2824
                        $options[] = $option;
2825
                    }
2826
                } else {
2827
                    $options[] = $option;
2828
                }
2829
            }
2830
            $select->addOptGroup($options, get_lang('Groups'));
2831
        }
2832
2833
        // adding the individual users to the select form
2834
        if (is_array($userList)) {
2835
            $options = [];
2836
            foreach ($userList as $user) {
2837
                if ($user['status'] == ANONYMOUS) {
2838
                    continue;
2839
                }
2840
                $option = [
2841
                    'text' => api_get_person_name(
2842
                            $user['firstname'],
2843
                            $user['lastname']
2844
                        ).' ('.$user['username'].')',
2845
                    'value' => "USER:".$user['user_id'],
2846
                ];
2847
2848
                $selected = in_array(
2849
                    $user['user_id'],
2850
                    $sendToUsers
2851
                ) ? true : false;
2852
2853
                if ($selected) {
2854
                    $option['selected'] = 'selected';
2855
                }
2856
2857
                if ($addOnlyItemsInSendTo) {
2858
                    if ($selected) {
2859
                        $options[] = $option;
2860
                    }
2861
                } else {
2862
                    $options[] = $option;
2863
                }
2864
            }
2865
2866
            $select->addOptGroup($options, get_lang('Users'));
2867
        }
2868
    }
2869
2870
    /**
2871
     * Separates the users and groups array
2872
     * users have a value USER:XXX (with XXX the user id
2873
     * groups have a value GROUP:YYY (with YYY the group id)
2874
     * use the 'everyone' key.
2875
     *
2876
     * @author Julio Montoya based in separate_users_groups in agenda.inc.php
2877
     *
2878
     * @param array $to
2879
     *
2880
     * @return array
2881
     */
2882
    public function parseSendToArray($to)
2883
    {
2884
        $groupList = [];
2885
        $userList = [];
2886
        $sendTo = null;
2887
2888
        $sendTo['everyone'] = false;
2889
        if (is_array($to) && count($to) > 0) {
2890
            foreach ($to as $item) {
2891
                if ($item == 'everyone') {
2892
                    $sendTo['everyone'] = true;
2893
                } else {
2894
                    list($type, $id) = explode(':', $item);
2895
                    switch ($type) {
2896
                        case 'GROUP':
2897
                            $groupList[] = $id;
2898
                            break;
2899
                        case 'USER':
2900
                            $userList[] = $id;
2901
                            break;
2902
                    }
2903
                }
2904
            }
2905
            $sendTo['groups'] = $groupList;
2906
            $sendTo['users'] = $userList;
2907
        }
2908
2909
        return $sendTo;
2910
    }
2911
2912
    /**
2913
     * @param int    $eventId
2914
     * @param string $type
2915
     *
2916
     * @return array<int, AgendaReminder>
2917
     */
2918
    public function getEventReminders($eventId, $type = null): array
2919
    {
2920
        $em = Database::getManager();
2921
        $remindersRepo = $em->getRepository('ChamiloCoreBundle:AgendaReminder');
2922
2923
        return $remindersRepo->findBy(
2924
            [
2925
                'eventId' => $eventId,
2926
                'type' => $type ?: $this->type,
2927
            ]
2928
        );
2929
    }
2930
2931
    public function parseEventReminders(array $eventReminders): array
2932
    {
2933
        return array_map(
2934
            function (AgendaReminder $reminder) {
2935
                $interval = $reminder->getDateInterval();
2936
2937
                $reminderInfo = [
2938
                    'id' => $reminder->getId(),
2939
                    'type' => $reminder->getType(),
2940
                    'sent' => $reminder->isSent(),
2941
                    'date_interval' => [$interval->format('%a'), 'd'],
2942
                ];
2943
2944
                if ($interval->i) {
2945
                    $reminderInfo['date_interval'] = [$interval->i, 'i'];
2946
                } elseif ($interval->h) {
2947
                    $reminderInfo['date_interval'] = [$interval->h, 'h'];
2948
                } elseif ($interval->d) {
2949
                    $reminderInfo['date_interval'] = [$interval->d, 'd'];
2950
                }
2951
2952
                return $reminderInfo;
2953
            },
2954
            $eventReminders
2955
        );
2956
    }
2957
2958
    /**
2959
     * @param array $params
2960
     *
2961
     * @return FormValidator
2962
     */
2963
    public function getForm($params = [])
2964
    {
2965
        $action = isset($params['action']) ? Security::remove_XSS($params['action']) : null;
2966
        $id = isset($params['id']) ? (int) $params['id'] : 0;
2967
2968
        $em = Database::getManager();
2969
        $personalEvent = 'personal' === $this->type && $id ? $em->find('ChamiloCoreBundle:PersonalAgenda', $id) : null;
2970
2971
        $url = api_get_self().'?action='.$action.'&id='.$id.'&type='.$this->type;
2972
        if ($this->type == 'course') {
2973
            $url = api_get_self().'?'.api_get_cidreq().'&action='.$action.'&id='.$id.'&type='.$this->type;
2974
        }
2975
2976
        $form = new FormValidator(
2977
            'add_event',
2978
            'post',
2979
            $url,
2980
            null,
2981
            ['enctype' => 'multipart/form-data']
2982
        );
2983
2984
        $idAttach = isset($params['id_attach']) ? (int) $params['id_attach'] : null;
2985
        $groupId = api_get_group_id();
2986
        $form_Title = get_lang('AddCalendarItem');
2987
        if (!empty($id)) {
2988
            $form_Title = get_lang('ModifyCalendarItem');
2989
        }
2990
2991
        $form->addHeader($form_Title);
2992
        $form->addElement('hidden', 'id', $id);
2993
        $form->addElement('hidden', 'action', $action);
2994
        $form->addElement('hidden', 'id_attach', $idAttach);
2995
2996
        $isSubEventEdition = false;
2997
        $isParentFromSerie = false;
2998
        $showAttachmentForm = true;
2999
3000
        if ($this->type == 'course') {
3001
            // Edition mode.
3002
            if (!empty($id)) {
3003
                $showAttachmentForm = false;
3004
                if (isset($params['parent_event_id']) && !empty($params['parent_event_id'])) {
3005
                    $isSubEventEdition = true;
3006
                }
3007
                if (!empty($params['repeat_info'])) {
3008
                    $isParentFromSerie = true;
3009
                }
3010
            }
3011
        }
3012
3013
        if ($isSubEventEdition) {
3014
            $form->addElement(
3015
                'label',
3016
                null,
3017
                Display::return_message(
3018
                    get_lang('EditingThisEventWillRemoveItFromTheSerie'),
3019
                    'warning'
3020
                )
3021
            );
3022
        }
3023
3024
        $form->addElement('text', 'title', get_lang('ItemTitle'));
3025
3026
        if (isset($groupId) && !empty($groupId)) {
3027
            $form->addElement(
3028
                'hidden',
3029
                'users_to_send[]',
3030
                "GROUP:$groupId"
3031
            );
3032
            $form->addElement('hidden', 'to', 'true');
3033
        } else {
3034
            $sendTo = isset($params['send_to']) ? $params['send_to'] : ['everyone' => true];
3035
            if ($this->type == 'course') {
3036
                $this->showToForm($form, $sendTo, [], false, true);
3037
            }
3038
        }
3039
3040
        $form->addDateRangePicker(
3041
            'date_range',
3042
            get_lang('DateRange'),
3043
            false,
3044
            ['id' => 'date_range']
3045
        );
3046
        $form->addElement('checkbox', 'all_day', null, get_lang('AllDay'));
3047
3048
        if ($this->type == 'course') {
3049
            $repeat = $form->addElement(
3050
                'checkbox',
3051
                'repeat',
3052
                null,
3053
                get_lang('RepeatEvent'),
3054
                ['onclick' => 'return plus_repeated_event();']
3055
            );
3056
            $form->addElement(
3057
                'html',
3058
                '<div id="options2" style="display:none">'
3059
            );
3060
            $form->addElement(
3061
                'select',
3062
                'repeat_type',
3063
                get_lang('RepeatType'),
3064
                self::getRepeatTypes()
3065
            );
3066
            $form->addElement(
3067
                'date_picker',
3068
                'repeat_end_day',
3069
                get_lang('RepeatEnd'),
3070
                ['id' => 'repeat_end_date_form']
3071
            );
3072
3073
            if ($isSubEventEdition || $isParentFromSerie) {
3074
                $repeatInfo = $params['repeat_info'];
3075
                if ($isSubEventEdition) {
3076
                    $parentEvent = $params['parent_info'];
3077
                    $repeatInfo = $parentEvent['repeat_info'];
3078
                }
3079
                $params['repeat'] = 1;
3080
                $params['repeat_type'] = $repeatInfo['cal_type'];
3081
                $params['repeat_end_day'] = substr(
3082
                    api_get_local_time($repeatInfo['cal_end']),
3083
                    0,
3084
                    10
3085
                );
3086
3087
                $form->freeze(['repeat_type', 'repeat_end_day']);
3088
                $repeat->_attributes['disabled'] = 'disabled';
3089
            }
3090
            $form->addElement('html', '</div>');
3091
        }
3092
3093
        if (!empty($id)) {
3094
            if (empty($params['end_date'])) {
3095
                $params['date_range'] = $params['end_date'];
3096
            }
3097
3098
            $params['date_range'] =
3099
                substr(api_get_local_time($params['start_date']), 0, 16).' / '.
3100
                substr(api_get_local_time($params['end_date']), 0, 16);
3101
        }
3102
3103
        $toolbar = 'Agenda';
3104
        if (!api_is_allowed_to_edit(null, true)) {
3105
            $toolbar = 'AgendaStudent';
3106
        }
3107
3108
        $form->addElement(
3109
            'html_editor',
3110
            'content',
3111
            get_lang('Description'),
3112
            null,
3113
            [
3114
                'ToolbarSet' => $toolbar,
3115
                'Width' => '100%',
3116
                'Height' => '200',
3117
            ]
3118
        );
3119
3120
        if ($this->type == 'course') {
3121
            $form->addElement('textarea', 'comment', get_lang('Comment'));
3122
            $form->addLabel(
3123
                get_lang('FilesAttachment'),
3124
                '<div id="filepaths" class="file-upload-event">
3125
3126
                        <div id="filepath_1">
3127
                            <input type="file" name="attach_1"/>
3128
3129
                            <label>'.get_lang('Description').'</label>
3130
                            <input class="form-control" type="text" name="legend[]" />
3131
                        </div>
3132
3133
                    </div>'
3134
            );
3135
3136
            $form->addLabel(
3137
                '',
3138
                '<span id="link-more-attach">
3139
                    <a href="javascript://" onclick="return add_image_form()">'.
3140
                get_lang('AddOneMoreFile').'</a>
3141
                 </span>&nbsp;('.sprintf(
3142
                    get_lang('MaximunFileSizeX'),
3143
                    format_file_size(
3144
                        api_get_setting('message_max_upload_filesize')
3145
                    )
3146
                ).')'
3147
            );
3148
3149
            if (isset($params['attachment']) && !empty($params['attachment'])) {
3150
                $attachmentList = $params['attachment'];
3151
                foreach ($attachmentList as $attachment) {
3152
                    $params['file_comment'] = $attachment['comment'];
3153
                    if (!empty($attachment['path'])) {
3154
                        $form->addElement(
3155
                            'checkbox',
3156
                            'delete_attachment['.$attachment['id'].']',
3157
                            null,
3158
                            get_lang(
3159
                                'DeleteAttachment'
3160
                            ).': '.$attachment['filename']
3161
                        );
3162
                    }
3163
                }
3164
            }
3165
3166
            $form->addElement(
3167
                'textarea',
3168
                'file_comment',
3169
                get_lang('FileComment')
3170
            );
3171
        }
3172
3173
        if (empty($id) && 'course' === $this->type) {
3174
            $form->addElement(
3175
                'checkbox',
3176
                'add_announcement',
3177
                null,
3178
                get_lang('AddAnnouncement').'&nbsp('.get_lang('SendMail').')'
3179
            );
3180
        }
3181
3182
        $agendaCollectiveInvitations = api_get_configuration_value('agenda_collective_invitations');
3183
        $agendaEventSubscriptions = api_is_platform_admin()
3184
            && true === api_get_configuration_value('agenda_event_subscriptions');
3185
3186
        $allowCollectiveInvitations = $agendaCollectiveInvitations && 'personal' === $this->type;
3187
        $allowEventSubscriptions = 'personal' === $this->type && $agendaEventSubscriptions;
3188
3189
        if ($allowCollectiveInvitations && $allowEventSubscriptions && !$personalEvent) {
3190
            $form->addRadio(
3191
                'invitation_type',
3192
                get_lang('Allowed'),
3193
                [
3194
                    'invitations' => get_lang('Invitations'),
3195
                    'subscriptions' => get_lang('Subscriptions'),
3196
                ],
3197
                [
3198
                    'onchange' => "$('#invitations-block, #subscriptions-block').hide(); $('#' + this.value + '-block').show();",
3199
                ]
3200
            );
3201
        }
3202
3203
        if ($allowCollectiveInvitations) {
3204
            $this->addCollectiveInvitationsFields($form, $personalEvent);
3205
        }
3206
3207
        if ($agendaEventSubscriptions) {
3208
            $this->addSubscriptionFields($form, $personalEvent);
3209
        }
3210
3211
        if (api_get_configuration_value('agenda_reminders')) {
3212
            $form->addHtml('<div id="notification_list">');
3213
3214
            if ($id) {
3215
                $this->addFieldsForRemindersToForm($id, $form);
3216
            }
3217
3218
            $form->addHtml('</div>');
3219
            $form->addButton('add_notification', get_lang('AddNotification'), 'bell-o')->setType('button');
3220
            $form->addHtml('<hr>');
3221
        }
3222
3223
        if (api_get_configuration_value('allow_careers_in_global_agenda') && 'admin' === $this->type) {
3224
            Career::addCareerFieldsToForm($form);
3225
            $form->addHtml('<hr>');
3226
        }
3227
3228
        if ($id) {
3229
            $form->addButtonUpdate(get_lang('ModifyEvent'));
3230
        } else {
3231
            $form->addButtonSave(get_lang('AgendaAdd'));
3232
        }
3233
3234
        $form->setDefaults($params);
3235
        $form->addRule(
3236
            'date_range',
3237
            get_lang('ThisFieldIsRequired'),
3238
            'required'
3239
        );
3240
        $form->addRule('title', get_lang('ThisFieldIsRequired'), 'required');
3241
3242
        return $form;
3243
    }
3244
3245
    public function addFieldsForRemindersToForm(int $eventId, FormValidator $form)
3246
    {
3247
        $remindersList = $this->parseEventReminders(
3248
            $this->getEventReminders($eventId)
3249
        );
3250
3251
        foreach ($remindersList as $reminderInfo) {
3252
            $form->addHtml('<div class="form-group">');
3253
            $form
3254
                ->addNumeric('notification_count[]', '', ['step' => 1, 'min' => 0])
3255
                ->setValue($reminderInfo['date_interval'][0])
3256
            ;
3257
            $form
3258
                ->addSelect(
3259
                'notification_period[]',
3260
                '',
3261
                    [
3262
                        'i' => get_lang('Minutes'),
3263
                        'h' => get_lang('Hours'),
3264
                        'd' => get_lang('Days'),
3265
                    ]
3266
                )
3267
                ->setValue($reminderInfo['date_interval'][1])
3268
            ;
3269
            $form->addHtml('<div class="col-sm-2"><p class="form-control-static">'.get_lang('Before').'</p></div>');
3270
            $form->addHtml(
3271
                '<div class="text-right col-sm-2">'
3272
                .'<button class="btn btn-default delete-notification" type="button" aria-label="'.get_lang('Delete').'"><em class="fa fa-times"></em></button>'
3273
                .'</div>'
3274
            );
3275
            $form->addHtml('</div>');
3276
        }
3277
3278
        $renderer = $form->defaultRenderer();
3279
        $renderer->setElementTemplate(
3280
            '<div class="col-sm-offset-2 col-sm-3">{element}</div>',
3281
            'notification_count[]'
3282
        );
3283
        $renderer->setElementTemplate(
3284
            '<div class="col-sm-3">{element}</div>',
3285
            'notification_period[]'
3286
        );
3287
    }
3288
3289
    /**
3290
     * @param FormValidator $form
3291
     * @param array         $sendTo               array('everyone' => false, 'users' => [1, 2], 'groups' => [3, 4])
3292
     * @param array         $attributes
3293
     * @param bool          $addOnlyItemsInSendTo
3294
     * @param bool          $required
3295
     *
3296
     * @return bool
3297
     */
3298
    public function showToForm(
3299
        $form,
3300
        $sendTo = [],
3301
        $attributes = [],
3302
        $addOnlyItemsInSendTo = false,
3303
        $required = false
3304
    ) {
3305
        if ($this->type != 'course') {
3306
            return false;
3307
        }
3308
3309
        $order = 'lastname';
3310
        if (api_is_western_name_order()) {
3311
            $order = 'firstname';
3312
        }
3313
3314
        $userList = CourseManager::get_user_list_from_course_code(
3315
            api_get_course_id(),
3316
            $this->sessionId,
3317
            null,
3318
            $order
3319
        );
3320
3321
        $groupList = CourseManager::get_group_list_of_course(
3322
            api_get_course_id(),
3323
            $this->sessionId
3324
        );
3325
3326
        $this->setSendToSelect(
3327
            $form,
3328
            $groupList,
3329
            $userList,
3330
            $sendTo,
3331
            $attributes,
3332
            $addOnlyItemsInSendTo,
3333
            $required
3334
        );
3335
3336
        return true;
3337
    }
3338
3339
    /**
3340
     * @param int   $id
3341
     * @param int   $visibility 0= invisible, 1 visible
3342
     * @param array $courseInfo
3343
     * @param int   $userId
3344
     */
3345
    public static function changeVisibility(
3346
        $id,
3347
        $visibility,
3348
        $courseInfo,
3349
        $userId = null
3350
    ) {
3351
        $id = intval($id);
3352
        if (empty($userId)) {
3353
            $userId = api_get_user_id();
3354
        } else {
3355
            $userId = intval($userId);
3356
        }
3357
3358
        if ($visibility == 0) {
3359
            api_item_property_update(
3360
                $courseInfo,
3361
                TOOL_CALENDAR_EVENT,
3362
                $id,
3363
                'invisible',
3364
                $userId
3365
            );
3366
        } else {
3367
            api_item_property_update(
3368
                $courseInfo,
3369
                TOOL_CALENDAR_EVENT,
3370
                $id,
3371
                'visible',
3372
                $userId
3373
            );
3374
        }
3375
    }
3376
3377
    /**
3378
     * Get repeat types.
3379
     *
3380
     * @return array
3381
     */
3382
    public static function getRepeatTypes()
3383
    {
3384
        return [
3385
            'daily' => get_lang('RepeatDaily'),
3386
            'weekly' => get_lang('RepeatWeekly'),
3387
            'monthlyByDate' => get_lang('RepeatMonthlyByDate'),
3388
            //monthlyByDay"> get_lang('RepeatMonthlyByDay');
3389
            //monthlyByDayR' => get_lang('RepeatMonthlyByDayR'),
3390
            'yearly' => get_lang('RepeatYearly'),
3391
        ];
3392
    }
3393
3394
    /**
3395
     * Show a list with all the attachments according to the post's id.
3396
     *
3397
     * @param int   $eventId
3398
     * @param array $courseInfo
3399
     *
3400
     * @return array with the post info
3401
     */
3402
    public function getAttachmentList($eventId, $courseInfo)
3403
    {
3404
        $tableAttachment = Database::get_course_table(TABLE_AGENDA_ATTACHMENT);
3405
        $courseId = (int) $courseInfo['real_id'];
3406
        $eventId = (int) $eventId;
3407
3408
        $sql = "SELECT id, path, filename, comment
3409
                FROM $tableAttachment
3410
                WHERE
3411
                    c_id = $courseId AND
3412
                    agenda_id = $eventId";
3413
        $result = Database::query($sql);
3414
        $list = [];
3415
        if (Database::num_rows($result) != 0) {
3416
            $list = Database::store_result($result, 'ASSOC');
3417
        }
3418
3419
        return $list;
3420
    }
3421
3422
    /**
3423
     * Show a list with all the attachments according to the post's id.
3424
     *
3425
     * @param int   $attachmentId
3426
     * @param int   $eventId
3427
     * @param array $courseInfo
3428
     *
3429
     * @return array with the post info
3430
     */
3431
    public function getAttachment($attachmentId, $eventId, $courseInfo)
3432
    {
3433
        if (empty($courseInfo) || empty($attachmentId) || empty($eventId)) {
3434
            return [];
3435
        }
3436
3437
        $tableAttachment = Database::get_course_table(TABLE_AGENDA_ATTACHMENT);
3438
        $courseId = (int) $courseInfo['real_id'];
3439
        $eventId = (int) $eventId;
3440
        $attachmentId = (int) $attachmentId;
3441
3442
        $row = [];
3443
        $sql = "SELECT id, path, filename, comment
3444
                FROM $tableAttachment
3445
                WHERE
3446
                    c_id = $courseId AND
3447
                    agenda_id = $eventId AND
3448
                    id = $attachmentId
3449
                ";
3450
        $result = Database::query($sql);
3451
        if (Database::num_rows($result) != 0) {
3452
            $row = Database::fetch_array($result, 'ASSOC');
3453
        }
3454
3455
        return $row;
3456
    }
3457
3458
    /**
3459
     * Add an attachment file into agenda.
3460
     *
3461
     * @param int    $eventId
3462
     * @param array  $fileUserUpload ($_FILES['user_upload'])
3463
     * @param string $comment        about file
3464
     * @param array  $courseInfo
3465
     *
3466
     * @return string
3467
     */
3468
    public function addAttachment(
3469
        $eventId,
3470
        $fileUserUpload,
3471
        $comment,
3472
        $courseInfo
3473
    ) {
3474
        $agenda_table_attachment = Database::get_course_table(TABLE_AGENDA_ATTACHMENT);
3475
        $eventId = (int) $eventId;
3476
3477
        // Storing the attachments
3478
        $upload_ok = false;
3479
        if (!empty($fileUserUpload['name'])) {
3480
            $upload_ok = process_uploaded_file($fileUserUpload);
3481
        }
3482
3483
        if (!empty($upload_ok)) {
3484
            $courseDir = $courseInfo['directory'].'/upload/calendar';
3485
            $sys_course_path = api_get_path(SYS_COURSE_PATH);
3486
            $uploadDir = $sys_course_path.$courseDir;
3487
3488
            // Try to add an extension to the file if it hasn't one
3489
            $new_file_name = add_ext_on_mime(
3490
                stripslashes($fileUserUpload['name']),
3491
                $fileUserUpload['type']
3492
            );
3493
3494
            // user's file name
3495
            $file_name = $fileUserUpload['name'];
3496
3497
            if (!filter_extension($new_file_name)) {
3498
                return Display::return_message(
3499
                    get_lang('UplUnableToSaveFileFilteredExtension'),
3500
                    'error'
3501
                );
3502
            } else {
3503
                $new_file_name = uniqid('');
3504
                $new_path = $uploadDir.'/'.$new_file_name;
3505
                $result = @move_uploaded_file(
3506
                    $fileUserUpload['tmp_name'],
3507
                    $new_path
3508
                );
3509
                $courseId = api_get_course_int_id();
3510
                $size = intval($fileUserUpload['size']);
3511
                // Storing the attachments if any
3512
                if ($result) {
3513
                    $params = [
3514
                        'c_id' => $courseId,
3515
                        'filename' => $file_name,
3516
                        'comment' => $comment,
3517
                        'path' => $new_file_name,
3518
                        'agenda_id' => $eventId,
3519
                        'size' => $size,
3520
                    ];
3521
                    $id = Database::insert($agenda_table_attachment, $params);
3522
                    if ($id) {
3523
                        $sql = "UPDATE $agenda_table_attachment
3524
                                SET id = iid WHERE iid = $id";
3525
                        Database::query($sql);
3526
3527
                        api_item_property_update(
3528
                            $courseInfo,
3529
                            'calendar_event_attachment',
3530
                            $id,
3531
                            'AgendaAttachmentAdded',
3532
                            api_get_user_id()
3533
                        );
3534
                    }
3535
                }
3536
            }
3537
        }
3538
    }
3539
3540
    /**
3541
     * @param int    $attachmentId
3542
     * @param int    $eventId
3543
     * @param array  $fileUserUpload
3544
     * @param string $comment
3545
     * @param array  $courseInfo
3546
     */
3547
    public function updateAttachment(
3548
        $attachmentId,
3549
        $eventId,
3550
        $fileUserUpload,
3551
        $comment,
3552
        $courseInfo
3553
    ) {
3554
        $attachment = $this->getAttachment(
3555
            $attachmentId,
3556
            $eventId,
3557
            $courseInfo
3558
        );
3559
        if (!empty($attachment)) {
3560
            $this->deleteAttachmentFile($attachmentId, $courseInfo);
3561
        }
3562
        $this->addAttachment($eventId, $fileUserUpload, $comment, $courseInfo);
3563
    }
3564
3565
    /**
3566
     * This function delete a attachment file by id.
3567
     *
3568
     * @param int   $attachmentId
3569
     * @param array $courseInfo
3570
     *
3571
     * @return string
3572
     */
3573
    public function deleteAttachmentFile($attachmentId, $courseInfo)
3574
    {
3575
        $table = Database::get_course_table(TABLE_AGENDA_ATTACHMENT);
3576
        $attachmentId = (int) $attachmentId;
3577
        $courseId = $courseInfo['real_id'];
3578
3579
        if (empty($courseId) || empty($attachmentId)) {
3580
            return false;
3581
        }
3582
3583
        $sql = "DELETE FROM $table
3584
                WHERE c_id = $courseId AND id = ".$attachmentId;
3585
        $result = Database::query($sql);
3586
3587
        // update item_property
3588
        api_item_property_update(
3589
            $courseInfo,
3590
            'calendar_event_attachment',
3591
            $attachmentId,
3592
            'AgendaAttachmentDeleted',
3593
            api_get_user_id()
3594
        );
3595
3596
        if (!empty($result)) {
3597
            return Display::return_message(
3598
                get_lang("AttachmentFileDeleteSuccess"),
3599
                'confirmation'
3600
            );
3601
        }
3602
    }
3603
3604
    /**
3605
     * @param int $eventId
3606
     *
3607
     * @return array
3608
     */
3609
    public function getAllRepeatEvents($eventId)
3610
    {
3611
        $events = [];
3612
        $eventId = (int) $eventId;
3613
3614
        switch ($this->type) {
3615
            case 'personal':
3616
                break;
3617
            case 'course':
3618
                if (!empty($this->course['real_id'])) {
3619
                    $sql = "SELECT * FROM ".$this->tbl_course_agenda."
3620
                            WHERE
3621
                                c_id = ".$this->course['real_id']." AND
3622
                                parent_event_id = ".$eventId;
3623
                    $result = Database::query($sql);
3624
                    if (Database::num_rows($result)) {
3625
                        while ($row = Database::fetch_array($result, 'ASSOC')) {
3626
                            $events[] = $row;
3627
                        }
3628
                    }
3629
                }
3630
                break;
3631
        }
3632
3633
        return $events;
3634
    }
3635
3636
    /**
3637
     * @param int $eventId
3638
     * @param int $courseId
3639
     *
3640
     * @return bool
3641
     */
3642
    public function hasChildren($eventId, $courseId)
3643
    {
3644
        $eventId = (int) $eventId;
3645
        $courseId = (int) $courseId;
3646
3647
        $sql = "SELECT count(DISTINCT(id)) as count
3648
                FROM ".$this->tbl_course_agenda."
3649
                WHERE
3650
                    c_id = $courseId AND
3651
                    parent_event_id = $eventId";
3652
        $result = Database::query($sql);
3653
        if (Database::num_rows($result)) {
3654
            $row = Database::fetch_array($result, 'ASSOC');
3655
3656
            return $row['count'] > 0;
3657
        }
3658
3659
        return false;
3660
    }
3661
3662
    public function displayActions(string $view, ?string $filter = ''): string
3663
    {
3664
        $groupInfo = GroupManager::get_group_properties(api_get_group_id());
3665
        $groupIid = $groupInfo['iid'] ?? 0;
3666
3667
        $codePath = api_get_path(WEB_CODE_PATH);
3668
3669
        $currentUserId = api_get_user_id();
3670
        $cidReq = api_get_cidreq();
3671
3672
        $actionsLeft = Display::url(
3673
            Display::return_icon('calendar.png', get_lang('Calendar'), [], ICON_SIZE_MEDIUM),
3674
            $codePath."calendar/agenda_js.php?type={$this->type}&$cidReq"
3675
        );
3676
        $actionsLeft .= Display::url(
3677
            Display::return_icon('week.png', get_lang('AgendaList'), [], ICON_SIZE_MEDIUM),
3678
            $codePath."calendar/agenda_list.php?type={$this->type}&$cidReq"
3679
        );
3680
3681
        $isAllowedToEdit = api_is_allowed_to_edit(false, true);
3682
3683
        $form = '';
3684
        if ($isAllowedToEdit
3685
            || ('personal' === $this->type && !api_is_anonymous() && 'true' === api_get_setting('allow_personal_agenda'))
3686
            || (
3687
                '1' === api_get_course_setting('allow_user_edit_agenda') && !api_is_anonymous() &&
3688
                api_is_allowed_to_session_edit(false, true))
3689
            || (
3690
                GroupManager::user_has_access($currentUserId, $groupIid, GroupManager::GROUP_TOOL_CALENDAR)
3691
                && GroupManager::is_tutor_of_group($currentUserId, $groupInfo)
3692
            )
3693
        ) {
3694
            $actionsLeft .= Display::url(
3695
                Display::return_icon('new_event.png', get_lang('AgendaAdd'), [], ICON_SIZE_MEDIUM),
3696
                $codePath."calendar/agenda.php?action=add&type={$this->type}&$cidReq"
3697
            );
3698
3699
            $actionsLeft .= Display::url(
3700
                Display::return_icon('import_calendar.png', get_lang('ICalFileImport'), [], ICON_SIZE_MEDIUM),
3701
                $codePath."calendar/agenda.php?action=importical&type={$this->type}&$cidReq"
3702
            );
3703
3704
            if ($this->type === 'course') {
3705
                if (!isset($_GET['action'])) {
3706
                    $form = new FormValidator(
3707
                        'form-search',
3708
                        'post',
3709
                        '',
3710
                        '',
3711
                        [],
3712
                        FormValidator::LAYOUT_INLINE
3713
                    );
3714
                    $attributes = [
3715
                        'multiple' => false,
3716
                        'id' => 'select_form_id_search',
3717
                    ];
3718
                    $selectedValues = $this->parseAgendaFilter($filter);
3719
                    $this->showToForm($form, $selectedValues, $attributes);
3720
                    $form = $form->returnForm();
3721
                }
3722
3723
                if (true === api_get_configuration_value('agenda_reminders') && $isAllowedToEdit) {
3724
                    $actionsLeft .= Display::url(
3725
                        Display::return_icon(
3726
                            'course_request_pending.png',
3727
                            get_lang('ImportCourseEvents'),
3728
                            [],
3729
                            ICON_SIZE_MEDIUM
3730
                        ),
3731
                        $codePath."calendar/agenda.php?action=import_course_agenda_reminders&type={$this->type}&$cidReq"
3732
                    );
3733
                }
3734
            }
3735
        }
3736
3737
        if ($this->type === 'personal' && !api_is_anonymous()) {
3738
            $actionsLeft .= Display::url(
3739
                Display::return_icon('1day.png', get_lang('SessionsPlanCalendar'), [], ICON_SIZE_MEDIUM),
3740
                $codePath.'calendar/planification.php'
3741
            );
3742
3743
            if (api_is_student_boss() || api_is_platform_admin()) {
3744
                $actionsLeft .= Display::url(
3745
                    Display::return_icon('calendar-user.png', get_lang('MyStudentsSchedule'), [], ICON_SIZE_MEDIUM),
3746
                    $codePath.'mySpace/calendar_plan.php'
3747
                );
3748
            }
3749
        }
3750
3751
        if (api_is_platform_admin()
3752
            || api_is_teacher()
3753
            || api_is_student_boss()
3754
            || api_is_drh()
3755
            || api_is_session_admin()
3756
            || api_is_coach()
3757
        ) {
3758
            if ($this->type == 'personal') {
3759
                $form = '';
3760
                if (!isset($_GET['action'])) {
3761
                    $form = new FormValidator(
3762
                        'form-search',
3763
                        'get',
3764
                        api_get_self().'?type=personal&',
3765
                        '',
3766
                        [],
3767
                        FormValidator::LAYOUT_INLINE
3768
                    );
3769
3770
                    $sessions = [];
3771
3772
                    if (api_is_drh()) {
3773
                        $sessionList = SessionManager::get_sessions_followed_by_drh($currentUserId);
3774
                        if (!empty($sessionList)) {
3775
                            foreach ($sessionList as $sessionItem) {
3776
                                $sessions[$sessionItem['id']] = strip_tags($sessionItem['name']);
3777
                            }
3778
                        }
3779
                    } else {
3780
                        $sessions = SessionManager::get_sessions_by_user($currentUserId);
3781
                        $sessions = array_column($sessions, 'session_name', 'session_id');
3782
                    }
3783
3784
                    $form->addHidden('type', 'personal');
3785
                    $sessions = ['0' => get_lang('SelectAnOption')] + $sessions;
3786
3787
                    $form->addSelect(
3788
                        'session_id',
3789
                        get_lang('Session'),
3790
                        $sessions,
3791
                        ['id' => 'session_id', 'onchange' => 'submit();']
3792
                    );
3793
3794
                    $form->addButton('reset', get_lang('Reset'), 'eraser');
3795
                    $form = $form->returnForm();
3796
                }
3797
            }
3798
        }
3799
3800
        $actionsRight = '';
3801
        if ($view == 'calendar') {
3802
            $actionsRight .= $form;
3803
        }
3804
3805
        return Display::toolbarAction(
3806
            'toolbar-agenda',
3807
            [$actionsLeft, $actionsRight]
3808
        );
3809
    }
3810
3811
    /**
3812
     * @return FormValidator
3813
     */
3814
    public function getImportCalendarForm()
3815
    {
3816
        $form = new FormValidator(
3817
            'frm_import_ical',
3818
            'post',
3819
            api_get_self().'?action=importical&type='.$this->type,
3820
            ['enctype' => 'multipart/form-data']
3821
        );
3822
        $form->addHeader(get_lang('ICalFileImport'));
3823
        $form->addElement('file', 'ical_import', get_lang('ICalFileImport'));
3824
        $form->addRule(
3825
            'ical_import',
3826
            get_lang('ThisFieldIsRequired'),
3827
            'required'
3828
        );
3829
        $form->addButtonImport(get_lang('Import'), 'ical_submit');
3830
3831
        return $form;
3832
    }
3833
3834
    /**
3835
     * @param array $courseInfo
3836
     * @param $file
3837
     *
3838
     * @return false|string
3839
     */
3840
    public function importEventFile($courseInfo, $file)
3841
    {
3842
        $charset = api_get_system_encoding();
3843
        $filepath = api_get_path(SYS_ARCHIVE_PATH).$file['name'];
3844
        $messages = [];
3845
3846
        if (!@move_uploaded_file($file['tmp_name'], $filepath)) {
3847
            error_log(
3848
                'Problem moving uploaded file: '.$file['error'].' in '.__FILE__.' line '.__LINE__
3849
            );
3850
3851
            return false;
3852
        }
3853
3854
        $data = file_get_contents($filepath);
3855
3856
        $trans = [
3857
            'DAILY' => 'daily',
3858
            'WEEKLY' => 'weekly',
3859
            'MONTHLY' => 'monthlyByDate',
3860
            'YEARLY' => 'yearly',
3861
        ];
3862
        $sentTo = ['everyone' => true];
3863
        $calendar = Sabre\VObject\Reader::read($data);
3864
        $currentTimeZone = api_get_timezone();
3865
        if (!empty($calendar->VEVENT)) {
3866
            /** @var Sabre\VObject\Component\VEvent $event */
3867
            foreach ($calendar->VEVENT as $event) {
3868
                $tempDate = $event->DTSTART->getValue();
3869
                if ('Z' == substr($tempDate, -1) && 'UTC' != date('e', strtotime($tempDate))) {
3870
                    $event->DTSTART->setValue(gmdate('Ymd\THis\Z', strtotime($tempDate)));
3871
                }
3872
                $tempDate = $event->DTEND->getValue();
3873
                if ('Z' == substr($tempDate, -1) && 'UTC' != date('e', strtotime($tempDate))) {
3874
                    $event->DTEND->setValue(gmdate('Ymd\THis\Z', strtotime($tempDate)));
3875
                }
3876
                $start = $event->DTSTART->getDateTime();
3877
                $end = $event->DTEND->getDateTime();
3878
                //Sabre\VObject\DateTimeParser::parseDateTime(string $dt, \Sabre\VObject\DateTimeZone $tz)
3879
3880
                $startDateTime = api_get_local_time(
3881
                    $start->format('Y-m-d H:i:s'),
3882
                    $currentTimeZone,
3883
                    $start->format('e')
3884
                );
3885
                $endDateTime = api_get_local_time(
3886
                    $end->format('Y-m-d H:i'),
3887
                    $currentTimeZone,
3888
                    $end->format('e')
3889
                );
3890
                $title = api_convert_encoding(
3891
                    (string) $event->summary,
3892
                    $charset,
3893
                    'UTF-8'
3894
                );
3895
                $description = api_convert_encoding(
3896
                    (string) $event->description,
3897
                    $charset,
3898
                    'UTF-8'
3899
                );
3900
3901
                $id = $this->addEvent(
3902
                    $startDateTime,
3903
                    $endDateTime,
3904
                    'false',
3905
                    $title,
3906
                    $description,
3907
                    $sentTo
3908
                );
3909
3910
                $messages[] = " $title - ".$startDateTime." - ".$endDateTime;
3911
3912
                //$attendee = (string)$event->attendee;
3913
                /** @var Sabre\VObject\Property\ICalendar\Recur $repeat */
3914
                $repeat = $event->RRULE;
3915
                if ($id && !empty($repeat)) {
3916
                    $repeat = $repeat->getParts();
3917
                    $freq = $trans[$repeat['FREQ']];
3918
3919
                    if (isset($repeat['UNTIL']) && !empty($repeat['UNTIL'])) {
3920
                        // Check if datetime or just date (strlen == 8)
3921
                        if (strlen($repeat['UNTIL']) == 8) {
3922
                            // Fix the datetime format to avoid exception in the next step
3923
                            $repeat['UNTIL'] .= 'T000000';
3924
                        }
3925
                        $until = Sabre\VObject\DateTimeParser::parseDateTime(
3926
                            $repeat['UNTIL'],
3927
                            new DateTimeZone($currentTimeZone)
3928
                        );
3929
                        $until = $until->format('Y-m-d H:i:s');
3930
                        $this->addRepeatedItem(
3931
                            $id,
3932
                            $freq,
3933
                            $until,
3934
                            $sentTo
3935
                        );
3936
                    }
3937
3938
                    if (!empty($repeat['COUNT'])) {
3939
                        /*$count = $repeat['COUNT'];
3940
                        $interval = $repeat['INTERVAL'];
3941
                        $endDate = null;
3942
                        switch($freq) {
3943
                            case 'daily':
3944
                                $start = api_strtotime($startDateTime);
3945
                                $date = new DateTime($startDateTime);
3946
                                $days = $count * $interval;
3947
                                var_dump($days);
3948
                                $date->add(new DateInterval("P".$days."D"));
3949
                                $endDate = $date->format('Y-m-d H:i');
3950
                                //$endDate = $count *
3951
                                for ($i = 0; $i < $count; $i++) {
3952
                                    $days = 86400 * 7
3953
                                }
3954
                            }
3955
                        }*/
3956
                        //$res = agenda_add_repeat_item($courseInfo, $id, $freq, $count, $attendee);
3957
                        /*$this->addRepeatedItem(
3958
                            $id,
3959
                            $freq,
3960
                            $endDate,
3961
                            $sentTo
3962
                        );*/
3963
                    }
3964
                }
3965
            }
3966
        }
3967
3968
        if (!empty($messages)) {
3969
            $messages = implode('<br /> ', $messages);
3970
        } else {
3971
            $messages = get_lang('NoAgendaItems');
3972
        }
3973
3974
        return $messages;
3975
    }
3976
3977
    /**
3978
     * Parse filter turns USER:12 to ['users' => [12])] or G:1 ['groups' => [1]].
3979
     *
3980
     * @param int $filter
3981
     *
3982
     * @return array
3983
     */
3984
    public function parseAgendaFilter($filter)
3985
    {
3986
        $everyone = false;
3987
        $groupId = null;
3988
        $userId = null;
3989
3990
        if ($filter == 'everyone') {
3991
            $everyone = true;
3992
        } else {
3993
            if (substr($filter, 0, 1) == 'G') {
3994
                $groupId = str_replace('GROUP:', '', $filter);
3995
            } else {
3996
                $userId = str_replace('USER:', '', $filter);
3997
            }
3998
        }
3999
        if (empty($userId) && empty($groupId)) {
4000
            $everyone = true;
4001
        }
4002
4003
        return [
4004
            'everyone' => $everyone,
4005
            'users' => [$userId],
4006
            'groups' => [$groupId],
4007
        ];
4008
    }
4009
4010
    /**
4011
     *    This function retrieves all the agenda items of all the courses the user is subscribed to.
4012
     */
4013
    public static function get_myagendaitems(
4014
        $user_id,
4015
        $courses_dbs,
4016
        $month,
4017
        $year
4018
    ) {
4019
        $user_id = intval($user_id);
4020
4021
        $items = [];
4022
        $my_list = [];
4023
4024
        // get agenda-items for every course
4025
        foreach ($courses_dbs as $key => $array_course_info) {
4026
            //databases of the courses
4027
            $TABLEAGENDA = Database::get_course_table(TABLE_AGENDA);
4028
            $TABLE_ITEMPROPERTY = Database::get_course_table(
4029
                TABLE_ITEM_PROPERTY
4030
            );
4031
4032
            $group_memberships = GroupManager::get_group_ids(
4033
                $array_course_info['real_id'],
4034
                $user_id
4035
            );
4036
            $course_user_status = CourseManager::getUserInCourseStatus(
4037
                $user_id,
4038
                $array_course_info['real_id']
4039
            );
4040
            // if the user is administrator of that course we show all the agenda items
4041
            if ($course_user_status == '1') {
4042
                //echo "course admin";
4043
                $sqlquery = "SELECT DISTINCT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref
4044
							FROM ".$TABLEAGENDA." agenda,
4045
								 ".$TABLE_ITEMPROPERTY." ip
4046
							WHERE agenda.id = ip.ref
4047
							AND MONTH(agenda.start_date)='".$month."'
4048
							AND YEAR(agenda.start_date)='".$year."'
4049
							AND ip.tool='".TOOL_CALENDAR_EVENT."'
4050
							AND ip.visibility='1'
4051
							GROUP BY agenda.id
4052
							ORDER BY start_date ";
4053
            } else {
4054
                // if the user is not an administrator of that course
4055
                if (is_array($group_memberships) && count(
4056
                        $group_memberships
4057
                    ) > 0
4058
                ) {
4059
                    $sqlquery = "SELECT	agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref
4060
								FROM ".$TABLEAGENDA." agenda,
4061
									".$TABLE_ITEMPROPERTY." ip
4062
								WHERE agenda.id = ip.ref
4063
								AND MONTH(agenda.start_date)='".$month."'
4064
								AND YEAR(agenda.start_date)='".$year."'
4065
								AND ip.tool='".TOOL_CALENDAR_EVENT."'
4066
								AND	( ip.to_user_id='".$user_id."' OR (ip.to_group_id IS NULL OR ip.to_group_id IN (0, ".implode(
4067
                            ", ",
4068
                            $group_memberships
4069
                        ).")) )
4070
								AND ip.visibility='1'
4071
								ORDER BY start_date ";
4072
                } else {
4073
                    $sqlquery = "SELECT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref
4074
								FROM ".$TABLEAGENDA." agenda,
4075
									".$TABLE_ITEMPROPERTY." ip
4076
								WHERE agenda.id = ip.ref
4077
								AND MONTH(agenda.start_date)='".$month."'
4078
								AND YEAR(agenda.start_date)='".$year."'
4079
								AND ip.tool='".TOOL_CALENDAR_EVENT."'
4080
								AND ( ip.to_user_id='".$user_id."' OR ip.to_group_id='0' OR ip.to_group_id IS NULL)
4081
								AND ip.visibility='1'
4082
								ORDER BY start_date ";
4083
                }
4084
            }
4085
            $result = Database::query($sqlquery);
4086
4087
            while ($item = Database::fetch_array($result, 'ASSOC')) {
4088
                $agendaday = -1;
4089
                if (!empty($item['start_date'])) {
4090
                    $item['start_date'] = api_get_local_time(
4091
                        $item['start_date']
4092
                    );
4093
                    $item['start_date_tms'] = api_strtotime(
4094
                        $item['start_date']
4095
                    );
4096
                    $agendaday = date("j", $item['start_date_tms']);
4097
                }
4098
                if (!empty($item['end_date'])) {
4099
                    $item['end_date'] = api_get_local_time($item['end_date']);
4100
                }
4101
4102
                $url = api_get_path(
4103
                        WEB_CODE_PATH
4104
                    )."calendar/agenda.php?cidReq=".urlencode(
4105
                        $array_course_info["code"]
4106
                    )."&day=$agendaday&month=$month&year=$year#$agendaday";
4107
4108
                $item['url'] = $url;
4109
                $item['course_name'] = $array_course_info['title'];
4110
                $item['calendar_type'] = 'course';
4111
                $item['course_id'] = $array_course_info['course_id'];
4112
4113
                $my_list[$agendaday][] = $item;
4114
            }
4115
        }
4116
4117
        // sorting by hour for every day
4118
        $agendaitems = [];
4119
        foreach ($items as $agendaday => $tmpitems) {
4120
            if (!isset($agendaitems[$agendaday])) {
4121
                $agendaitems[$agendaday] = '';
4122
            }
4123
            sort($tmpitems);
4124
            foreach ($tmpitems as $val) {
4125
                $agendaitems[$agendaday] .= $val;
4126
            }
4127
        }
4128
4129
        return $my_list;
4130
    }
4131
4132
    /**
4133
     * This function retrieves one personal agenda item returns it.
4134
     *
4135
     * @param    array    The array containing existing events. We add to this array.
4136
     * @param    int        Day
4137
     * @param    int        Month
4138
     * @param    int        Year (4 digits)
4139
     * @param    int        Week number
4140
     * @param    string    Type of view (month_view, week_view, day_view)
4141
     *
4142
     * @return array The results of the database query, or null if not found
4143
     */
4144
    public static function get_global_agenda_items(
4145
        $agendaitems,
4146
        $day,
4147
        $month,
4148
        $year,
4149
        $week,
4150
        $type
4151
    ) {
4152
        $tbl_global_agenda = Database::get_main_table(
4153
            TABLE_MAIN_SYSTEM_CALENDAR
4154
        );
4155
        $month = intval($month);
4156
        $year = intval($year);
4157
        $week = intval($week);
4158
        $day = intval($day);
4159
        // 1. creating the SQL statement for getting the personal agenda items in MONTH view
4160
4161
        $current_access_url_id = api_get_current_access_url_id();
4162
4163
        if ($type == "month_view" || $type == "") {
4164
            // We are in month view
4165
            $sql = "SELECT * FROM ".$tbl_global_agenda."
4166
                    WHERE
4167
                        MONTH(start_date) = ".$month." AND
4168
                        YEAR(start_date) = ".$year."  AND
4169
                        access_url_id = $current_access_url_id
4170
                    ORDER BY start_date ASC";
4171
        }
4172
        // 2. creating the SQL statement for getting the personal agenda items in WEEK view
4173
        if ($type == "week_view") { // we are in week view
4174
            $start_end_day_of_week = self::calculate_start_end_of_week(
4175
                $week,
4176
                $year
4177
            );
4178
            $start_day = $start_end_day_of_week['start']['day'];
4179
            $start_month = $start_end_day_of_week['start']['month'];
4180
            $start_year = $start_end_day_of_week['start']['year'];
4181
            $end_day = $start_end_day_of_week['end']['day'];
4182
            $end_month = $start_end_day_of_week['end']['month'];
4183
            $end_year = $start_end_day_of_week['end']['year'];
4184
            // in sql statements you have to use year-month-day for date calculations
4185
            $start_filter = $start_year."-".$start_month."-".$start_day." 00:00:00";
4186
            $start_filter = api_get_utc_datetime($start_filter);
4187
4188
            $end_filter = $end_year."-".$end_month."-".$end_day." 23:59:59";
4189
            $end_filter = api_get_utc_datetime($end_filter);
4190
            $sql = " SELECT * FROM ".$tbl_global_agenda." WHERE start_date>='".$start_filter."' AND start_date<='".$end_filter."' AND  access_url_id = $current_access_url_id ";
4191
        }
4192
        // 3. creating the SQL statement for getting the personal agenda items in DAY view
4193
        if ($type == "day_view") { // we are in day view
4194
            // we could use mysql date() function but this is only available from 4.1 and higher
4195
            $start_filter = $year."-".$month."-".$day." 00:00:00";
4196
            $start_filter = api_get_utc_datetime($start_filter);
4197
4198
            $end_filter = $year."-".$month."-".$day." 23:59:59";
4199
            $end_filter = api_get_utc_datetime($end_filter);
4200
            $sql = " SELECT * FROM ".$tbl_global_agenda." WHERE start_date>='".$start_filter."' AND start_date<='".$end_filter."'  AND  access_url_id = $current_access_url_id";
4201
        }
4202
4203
        $result = Database::query($sql);
4204
4205
        while ($item = Database::fetch_array($result)) {
4206
            if (!empty($item['start_date'])) {
4207
                $item['start_date'] = api_get_local_time($item['start_date']);
4208
                $item['start_date_tms'] = api_strtotime($item['start_date']);
4209
            }
4210
            if (!empty($item['end_date'])) {
4211
                $item['end_date'] = api_get_local_time($item['end_date']);
4212
            }
4213
4214
            // we break the date field in the database into a date and a time part
4215
            $agenda_db_date = explode(" ", $item['start_date']);
4216
            $date = $agenda_db_date[0];
4217
            $time = $agenda_db_date[1];
4218
            // we divide the date part into a day, a month and a year
4219
            $agendadate = explode("-", $date);
4220
            $year = intval($agendadate[0]);
4221
            $month = intval($agendadate[1]);
4222
            $day = intval($agendadate[2]);
4223
            // we divide the time part into hour, minutes, seconds
4224
            $agendatime = explode(":", $time);
4225
            $hour = $agendatime[0];
4226
            $minute = $agendatime[1];
4227
            $second = $agendatime[2];
4228
4229
            if ($type == 'month_view') {
4230
                $item['calendar_type'] = 'global';
4231
                $agendaitems[$day][] = $item;
4232
                continue;
4233
            }
4234
4235
            $start_time = api_format_date(
4236
                $item['start_date'],
4237
                TIME_NO_SEC_FORMAT
4238
            );
4239
            $end_time = '';
4240
            if (!empty($item['end_date'])) {
4241
                $end_time = ' - '.api_format_date(
4242
                        $item['end_date'],
4243
                        DATE_TIME_FORMAT_LONG
4244
                    );
4245
            }
4246
4247
            // if the student has specified a course we a add a link to that course
4248
            if ($item['course'] != "") {
4249
                $url = api_get_path(
4250
                        WEB_CODE_PATH
4251
                    )."admin/agenda.php?cidReq=".urlencode(
4252
                        $item['course']
4253
                    )."&day=$day&month=$month&year=$year#$day"; // RH  //Patrick Cool: to highlight the relevant agenda item
4254
                $course_link = "<a href=\"$url\" title=\"".$item['course']."\">".$item['course']."</a>";
4255
            } else {
4256
                $course_link = "";
4257
            }
4258
            // Creating the array that will be returned. If we have week or month view we have an array with the date as the key
4259
            // if we have a day_view we use a half hour as index => key 33 = 16h30
4260
            if ($type !== "day_view") {
4261
                // This is the array construction for the WEEK or MONTH view
4262
                //Display the Agenda global in the tab agenda (administrator)
4263
                $agendaitems[$day] .= "<i>$start_time $end_time</i>&nbsp;-&nbsp;";
4264
                $agendaitems[$day] .= "<b>".get_lang('GlobalEvent')."</b>";
4265
                $agendaitems[$day] .= "<div>".$item['title']."</div><br>";
4266
            } else {
4267
                // this is the array construction for the DAY view
4268
                $halfhour = 2 * $agendatime['0'];
4269
                if ($agendatime['1'] >= '30') {
4270
                    $halfhour = $halfhour + 1;
4271
                }
4272
                if (!is_array($agendaitems[$halfhour])) {
4273
                    $content = $agendaitems[$halfhour];
4274
                }
4275
                $agendaitems[$halfhour] = $content."<div><i>$hour:$minute</i> <b>".get_lang(
4276
                        'GlobalEvent'
4277
                    ).":  </b>".$item['title']."</div>";
4278
            }
4279
        }
4280
4281
        return $agendaitems;
4282
    }
4283
4284
    /**
4285
     * This function retrieves all the personal agenda items and add them to the agenda items found by the other
4286
     * functions.
4287
     */
4288
    public static function get_personal_agenda_items(
4289
        $user_id,
4290
        $agendaitems,
4291
        $day,
4292
        $month,
4293
        $year,
4294
        $week,
4295
        $type
4296
    ) {
4297
        $tbl_personal_agenda = Database::get_main_table(TABLE_PERSONAL_AGENDA);
4298
        $user_id = intval($user_id);
4299
4300
        // 1. creating the SQL statement for getting the personal agenda items in MONTH view
4301
        if ($type === "month_view" || $type === "") {
4302
            // we are in month view
4303
            $sql = "SELECT * FROM $tbl_personal_agenda
4304
                    WHERE
4305
                        user='".$user_id."' AND
4306
                        MONTH(date)='".$month."' AND
4307
                        YEAR(date) = '".$year."'
4308
                     ORDER BY date ASC";
4309
        }
4310
4311
        // 2. creating the SQL statement for getting the personal agenda items in WEEK view
4312
        // we are in week view
4313
        if ($type == "week_view") {
4314
            $start_end_day_of_week = self::calculate_start_end_of_week(
4315
                $week,
4316
                $year
4317
            );
4318
            $start_day = $start_end_day_of_week['start']['day'];
4319
            $start_month = $start_end_day_of_week['start']['month'];
4320
            $start_year = $start_end_day_of_week['start']['year'];
4321
            $end_day = $start_end_day_of_week['end']['day'];
4322
            $end_month = $start_end_day_of_week['end']['month'];
4323
            $end_year = $start_end_day_of_week['end']['year'];
4324
            // in sql statements you have to use year-month-day for date calculations
4325
            $start_filter = $start_year."-".$start_month."-".$start_day." 00:00:00";
4326
            $start_filter = api_get_utc_datetime($start_filter);
4327
            $end_filter = $end_year."-".$end_month."-".$end_day." 23:59:59";
4328
            $end_filter = api_get_utc_datetime($end_filter);
4329
            $sql = " SELECT * FROM ".$tbl_personal_agenda." WHERE user='".$user_id."' AND date>='".$start_filter."' AND date<='".$end_filter."'";
4330
        }
4331
        // 3. creating the SQL statement for getting the personal agenda items in DAY view
4332
        if ($type == "day_view") {
4333
            // we are in day view
4334
            // we could use mysql date() function but this is only available from 4.1 and higher
4335
            $start_filter = $year."-".$month."-".$day." 00:00:00";
4336
            $start_filter = api_get_utc_datetime($start_filter);
4337
            $end_filter = $year."-".$month."-".$day." 23:59:59";
4338
            $end_filter = api_get_utc_datetime($end_filter);
4339
            $sql = " SELECT * FROM ".$tbl_personal_agenda." WHERE user='".$user_id."' AND date>='".$start_filter."' AND date<='".$end_filter."'";
4340
        }
4341
4342
        $result = Database::query($sql);
4343
        while ($item = Database::fetch_array($result, 'ASSOC')) {
4344
            $time_minute = api_convert_and_format_date(
4345
                $item['date'],
4346
                TIME_NO_SEC_FORMAT
4347
            );
4348
            $item['date'] = api_get_local_time($item['date']);
4349
            $item['start_date_tms'] = api_strtotime($item['date']);
4350
            $item['content'] = $item['text'];
4351
4352
            // we break the date field in the database into a date and a time part
4353
            $agenda_db_date = explode(" ", $item['date']);
4354
            $date = $agenda_db_date[0];
4355
            $time = $agenda_db_date[1];
4356
            // we divide the date part into a day, a month and a year
4357
            $agendadate = explode("-", $item['date']);
4358
            $year = intval($agendadate[0]);
4359
            $month = intval($agendadate[1]);
4360
            $day = intval($agendadate[2]);
4361
            // we divide the time part into hour, minutes, seconds
4362
            $agendatime = explode(":", $time);
4363
4364
            $hour = $agendatime[0];
4365
            $minute = $agendatime[1];
4366
            $second = $agendatime[2];
4367
4368
            if ($type == 'month_view') {
4369
                $item['calendar_type'] = 'personal';
4370
                $item['start_date'] = $item['date'];
4371
                $agendaitems[$day][] = $item;
4372
                continue;
4373
            }
4374
4375
            // if the student has specified a course we a add a link to that course
4376
            if ($item['course'] != "") {
4377
                $url = api_get_path(
4378
                        WEB_CODE_PATH
4379
                    )."calendar/agenda.php?cidReq=".urlencode(
4380
                        $item['course']
4381
                    )."&day=$day&month=$month&year=$year#$day"; // RH  //Patrick Cool: to highlight the relevant agenda item
4382
                $course_link = "<a href=\"$url\" title=\"".$item['course']."\">".$item['course']."</a>";
4383
            } else {
4384
                $course_link = "";
4385
            }
4386
            // Creating the array that will be returned. If we have week or month view we have an array with the date as the key
4387
            // if we have a day_view we use a half hour as index => key 33 = 16h30
4388
            if ($type !== "day_view") {
4389
                // This is the array construction for the WEEK or MONTH view
4390
4391
                //Display events in agenda
4392
                $agendaitems[$day] .= "<div><i>$time_minute</i> $course_link <a href=\"myagenda.php?action=view&view=personal&day=$day&month=$month&year=$year&id=".$item['id']."#".$item['id']."\" class=\"personal_agenda\">".$item['title']."</a></div><br />";
4393
            } else {
4394
                // this is the array construction for the DAY view
4395
                $halfhour = 2 * $agendatime['0'];
4396
                if ($agendatime['1'] >= '30') {
4397
                    $halfhour = $halfhour + 1;
4398
                }
4399
4400
                //Display events by list
4401
                $agendaitems[$halfhour] .= "<div><i>$time_minute</i> $course_link <a href=\"myagenda.php?action=view&view=personal&day=$day&month=$month&year=$year&id=".$item['id']."#".$item['id']."\" class=\"personal_agenda\">".$item['title']."</a></div>";
4402
            }
4403
        }
4404
4405
        return $agendaitems;
4406
    }
4407
4408
    /**
4409
     * Show the monthcalender of the given month.
4410
     *
4411
     * @param    array    Agendaitems
4412
     * @param    int    Month number
4413
     * @param    int    Year number
4414
     * @param    array    Array of strings containing long week day names (deprecated, you can send an empty array
4415
     *                          instead)
4416
     * @param    string    The month name
4417
     */
4418
    public static function display_mymonthcalendar(
4419
        $user_id,
4420
        $agendaitems,
4421
        $month,
4422
        $year,
4423
        $weekdaynames,
4424
        $monthName,
4425
        $show_content = true
4426
    ) {
4427
        global $DaysShort, $course_path;
4428
        //Handle leap year
4429
        $numberofdays = [
4430
            0,
4431
            31,
4432
            28,
4433
            31,
4434
            30,
4435
            31,
4436
            30,
4437
            31,
4438
            31,
4439
            30,
4440
            31,
4441
            30,
4442
            31,
4443
        ];
4444
        if (($year % 400 == 0) or ($year % 4 == 0 and $year % 100 != 0)) {
4445
            $numberofdays[2] = 29;
4446
        }
4447
        //Get the first day of the month
4448
        $dayone = getdate(mktime(0, 0, 0, $month, 1, $year));
4449
        //Start the week on monday
4450
        $startdayofweek = $dayone['wday'] != 0 ? ($dayone['wday'] - 1) : 6;
4451
        $g_cc = (isset($_GET['courseCode']) ? $_GET['courseCode'] : '');
4452
4453
        $next_month = ($month == 1 ? 12 : $month - 1);
4454
        $prev_month = ($month == 12 ? 1 : $month + 1);
4455
4456
        $next_year = ($month == 1 ? $year - 1 : $year);
4457
        $prev_year = ($month == 12 ? $year + 1 : $year);
4458
4459
        if ($show_content) {
4460
            $back_url = Display::url(
4461
                get_lang('Previous'),
4462
                api_get_self()."?coursePath=".urlencode(
4463
                    $course_path
4464
                )."&courseCode=".Security::remove_XSS(
4465
                    $g_cc
4466
                )."&action=view&view=month&month=".$next_month."&year=".$next_year
4467
            );
4468
            $next_url = Display::url(
4469
                get_lang('Next'),
4470
                api_get_self()."?coursePath=".urlencode(
4471
                    $course_path
4472
                )."&courseCode=".Security::remove_XSS(
4473
                    $g_cc
4474
                )."&action=view&view=month&month=".$prev_month."&year=".$prev_year
4475
            );
4476
        } else {
4477
            $back_url = Display::url(
4478
                get_lang('Previous'),
4479
                '',
4480
                [
4481
                    'onclick' => "load_calendar('".$user_id."','".$next_month."', '".$next_year."'); ",
4482
                    'class' => 'btn ui-button ui-widget ui-state-default',
4483
                ]
4484
            );
4485
            $next_url = Display::url(
4486
                get_lang('Next'),
4487
                '',
4488
                [
4489
                    'onclick' => "load_calendar('".$user_id."','".$prev_month."', '".$prev_year."'); ",
4490
                    'class' => 'pull-right btn ui-button ui-widget ui-state-default',
4491
                ]
4492
            );
4493
        }
4494
        $html = '';
4495
        $html .= '<div class="actions">';
4496
        $html .= '<div class="row">';
4497
        $html .= '<div class="col-md-4">'.$back_url.'</div>';
4498
        $html .= '<div class="col-md-4"><p class="agenda-title text-center">'.$monthName." ".$year.'</p></div>';
4499
        $html .= '<div class="col-md-4">'.$next_url.'</div>';
4500
        $html .= '</div>';
4501
        $html .= '</div>';
4502
        $html .= '<table id="agenda_list2" class="table table-bordered">';
4503
        $html .= '<tr>';
4504
        for ($ii = 1; $ii < 8; $ii++) {
4505
            $html .= '<td class="weekdays">'.$DaysShort[$ii % 7].'</td>';
4506
        }
4507
        $html .= '</tr>';
4508
4509
        $curday = -1;
4510
        $today = getdate();
4511
        while ($curday <= $numberofdays[$month]) {
4512
            $html .= "<tr>";
4513
            for ($ii = 0; $ii < 7; $ii++) {
4514
                if (($curday == -1) && ($ii == $startdayofweek)) {
4515
                    $curday = 1;
4516
                }
4517
                if (($curday > 0) && ($curday <= $numberofdays[$month])) {
4518
                    $bgcolor = $class = 'class="days_week"';
4519
                    $dayheader = Display::div(
4520
                        $curday,
4521
                        ['class' => 'agenda_day']
4522
                    );
4523
                    if (($curday == $today['mday']) && ($year == $today['year']) && ($month == $today['mon'])) {
4524
                        $class = "class=\"days_today\" style=\"width:10%;\"";
4525
                    }
4526
4527
                    $html .= "<td ".$class.">".$dayheader;
4528
4529
                    if (!empty($agendaitems[$curday])) {
4530
                        $items = $agendaitems[$curday];
4531
                        $items = msort($items, 'start_date_tms');
4532
4533
                        foreach ($items as $value) {
4534
                            $value['title'] = Security::remove_XSS(
4535
                                $value['title']
4536
                            );
4537
                            $start_time = api_format_date(
4538
                                $value['start_date'],
4539
                                TIME_NO_SEC_FORMAT
4540
                            );
4541
                            $end_time = '';
4542
4543
                            if (!empty($value['end_date'])) {
4544
                                $end_time = '-&nbsp;<i>'.api_format_date(
4545
                                        $value['end_date'],
4546
                                        DATE_TIME_FORMAT_LONG
4547
                                    ).'</i>';
4548
                            }
4549
                            $complete_time = '<i>'.api_format_date(
4550
                                    $value['start_date'],
4551
                                    DATE_TIME_FORMAT_LONG
4552
                                ).'</i>&nbsp;'.$end_time;
4553
                            $time = '<i>'.$start_time.'</i>';
4554
4555
                            switch ($value['calendar_type']) {
4556
                                case 'personal':
4557
                                    $bg_color = '#D0E7F4';
4558
                                    $icon = Display::return_icon(
4559
                                        'user.png',
4560
                                        get_lang('MyAgenda'),
4561
                                        [],
4562
                                        ICON_SIZE_SMALL
4563
                                    );
4564
                                    break;
4565
                                case 'global':
4566
                                    $bg_color = '#FFBC89';
4567
                                    $icon = Display::return_icon(
4568
                                        'view_remove.png',
4569
                                        get_lang('GlobalEvent'),
4570
                                        [],
4571
                                        ICON_SIZE_SMALL
4572
                                    );
4573
                                    break;
4574
                                case 'course':
4575
                                    $bg_color = '#CAFFAA';
4576
                                    $icon_name = 'course.png';
4577
                                    if (!empty($value['session_id'])) {
4578
                                        $icon_name = 'session.png';
4579
                                    }
4580
                                    if ($show_content) {
4581
                                        $icon = Display::url(
4582
                                            Display::return_icon(
4583
                                                $icon_name,
4584
                                                $value['course_name'].' '.get_lang(
4585
                                                    'Course'
4586
                                                ),
4587
                                                [],
4588
                                                ICON_SIZE_SMALL
4589
                                            ),
4590
                                            $value['url']
4591
                                        );
4592
                                    } else {
4593
                                        $icon = Display::return_icon(
4594
                                            $icon_name,
4595
                                            $value['course_name'].' '.get_lang(
4596
                                                'Course'
4597
                                            ),
4598
                                            [],
4599
                                            ICON_SIZE_SMALL
4600
                                        );
4601
                                    }
4602
                                    break;
4603
                                default:
4604
                                    break;
4605
                            }
4606
4607
                            $result = '<div class="rounded_div_agenda" style="background-color:'.$bg_color.';">';
4608
4609
                            if ($show_content) {
4610
                                //Setting a personal event to green
4611
                                $icon = Display::div(
4612
                                    $icon,
4613
                                    ['style' => 'float:right']
4614
                                );
4615
4616
                                $link = $value['calendar_type'].'_'.$value['id'].'_'.$value['course_id'].'_'.$value['session_id'];
4617
4618
                                //Link to bubble
4619
                                $url = Display::url(
4620
                                    cut($value['title'], 40),
4621
                                    '#',
4622
                                    ['id' => $link, 'class' => 'opener']
4623
                                );
4624
                                $result .= $time.' '.$icon.' '.Display::div(
4625
                                        $url
4626
                                    );
4627
4628
                                //Hidden content
4629
                                $content = Display::div(
4630
                                    $icon.Display::tag(
4631
                                        'h2',
4632
                                        $value['course_name']
4633
                                    ).'<hr />'.Display::tag(
4634
                                        'h3',
4635
                                        $value['title']
4636
                                    ).$complete_time.'<hr />'.Security::remove_XSS(
4637
                                        $value['content']
4638
                                    )
4639
                                );
4640
4641
                                //Main div
4642
                                $result .= Display::div(
4643
                                    $content,
4644
                                    [
4645
                                        'id' => 'main_'.$link,
4646
                                        'class' => 'dialog',
4647
                                        'style' => 'display:none',
4648
                                    ]
4649
                                );
4650
                                $result .= '</div>';
4651
                                $html .= $result;
4652
                            } else {
4653
                                $html .= $result .= $icon.'</div>';
4654
                            }
4655
                        }
4656
                    }
4657
                    $html .= "</td>";
4658
                    $curday++;
4659
                } else {
4660
                    $html .= "<td></td>";
4661
                }
4662
            }
4663
            $html .= "</tr>";
4664
        }
4665
        $html .= "</table>";
4666
        echo $html;
4667
    }
4668
4669
    /**
4670
     * Get personal agenda items between two dates (=all events from all registered courses).
4671
     *
4672
     * @param int $user_id user ID of the user
4673
     * @param    string    Optional start date in datetime format (if no start date is given, uses today)
4674
     * @param    string    Optional end date in datetime format (if no date is given, uses one year from now)
4675
     *
4676
     * @return array array of events ordered by start date, in
4677
     *               [0]('datestart','dateend','title'),[1]('datestart','dateend','title','link','coursetitle') format,
4678
     *               where datestart and dateend are in yyyyMMddhhmmss format
4679
     *
4680
     * @deprecated use agenda events
4681
     */
4682
    public static function get_personal_agenda_items_between_dates(
4683
        $user_id,
4684
        $date_start = '',
4685
        $date_end = ''
4686
    ) {
4687
        $items = [];
4688
        if ($user_id != strval(intval($user_id))) {
4689
            return $items;
4690
        }
4691
        if (empty($date_start)) {
4692
            $date_start = date('Y-m-d H:i:s');
4693
        }
4694
        if (empty($date_end)) {
4695
            $date_end = date(
4696
                'Y-m-d H:i:s',
4697
                mktime(0, 0, 0, date("m"), date("d"), date("Y") + 1)
4698
            );
4699
        }
4700
        $expr = '/\d{4}-\d{2}-\d{2}\ \d{2}:\d{2}:\d{2}/';
4701
        if (!preg_match($expr, $date_start)) {
4702
            return $items;
4703
        }
4704
        if (!preg_match($expr, $date_end)) {
4705
            return $items;
4706
        }
4707
4708
        // get agenda-items for every course
4709
        $courses = api_get_user_courses($user_id, false);
4710
        foreach ($courses as $id => $course) {
4711
            $c = api_get_course_info_by_id($course['real_id']);
4712
            //databases of the courses
4713
            $t_a = Database::get_course_table(TABLE_AGENDA, $course['db']);
4714
            $t_ip = Database::get_course_table(
4715
                TABLE_ITEM_PROPERTY,
4716
                $course['db']
4717
            );
4718
            // get the groups to which the user belong
4719
            $group_memberships = GroupManager::get_group_ids(
4720
                $course['db'],
4721
                $user_id
4722
            );
4723
            // if the user is administrator of that course we show all the agenda items
4724
            if ($course['status'] == '1') {
4725
                //echo "course admin";
4726
                $sqlquery = "SELECT ".
4727
                    " DISTINCT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref ".
4728
                    " FROM ".$t_a." agenda, ".
4729
                    $t_ip." ip ".
4730
                    " WHERE agenda.id = ip.ref ".
4731
                    " AND agenda.start_date>='$date_start' ".
4732
                    " AND agenda.end_date<='$date_end' ".
4733
                    " AND ip.tool='".TOOL_CALENDAR_EVENT."' ".
4734
                    " AND ip.visibility='1' ".
4735
                    " GROUP BY agenda.id ".
4736
                    " ORDER BY start_date ";
4737
            } else {
4738
                // if the user is not an administrator of that course, then...
4739
                if (is_array($group_memberships) && count(
4740
                        $group_memberships
4741
                    ) > 0
4742
                ) {
4743
                    $sqlquery = "SELECT ".
4744
                        "DISTINCT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref ".
4745
                        " FROM ".$t_a." agenda, ".
4746
                        $t_ip." ip ".
4747
                        " WHERE agenda.id = ip.ref ".
4748
                        " AND agenda.start_date>='$date_start' ".
4749
                        " AND agenda.end_date<='$date_end' ".
4750
                        " AND ip.tool='".TOOL_CALENDAR_EVENT."' ".
4751
                        " AND	( ip.to_user_id='".$user_id."' OR (ip.to_group_id IS NULL OR ip.to_group_id IN (0, ".implode(
4752
                            ", ",
4753
                            $group_memberships
4754
                        ).")) ) ".
4755
                        " AND ip.visibility='1' ".
4756
                        " ORDER BY start_date ";
4757
                } else {
4758
                    $sqlquery = "SELECT ".
4759
                        "DISTINCT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref ".
4760
                        " FROM ".$t_a." agenda, ".
4761
                        $t_ip." ip ".
4762
                        " WHERE agenda.id = ip.ref ".
4763
                        " AND agenda.start_date>='$date_start' ".
4764
                        " AND agenda.end_date<='$date_end' ".
4765
                        " AND ip.tool='".TOOL_CALENDAR_EVENT."' ".
4766
                        " AND ( ip.to_user_id='".$user_id."' OR ip.to_group_id='0' OR ip.to_group_id IS NULL) ".
4767
                        " AND ip.visibility='1' ".
4768
                        " ORDER BY start_date ";
4769
                }
4770
            }
4771
4772
            $result = Database::query($sqlquery);
4773
            while ($item = Database::fetch_array($result)) {
4774
                $agendaday = date("j", strtotime($item['start_date']));
4775
                $month = date("n", strtotime($item['start_date']));
4776
                $year = date("Y", strtotime($item['start_date']));
4777
                $URL = api_get_path(
4778
                        WEB_PATH
4779
                    )."main/calendar/agenda.php?cidReq=".urlencode(
4780
                        $course["code"]
4781
                    )."&day=$agendaday&month=$month&year=$year#$agendaday";
4782
                list($year, $month, $day, $hour, $min, $sec) = explode(
4783
                    '[-: ]',
4784
                    $item['start_date']
4785
                );
4786
                $start_date = $year.$month.$day.$hour.$min;
4787
                list($year, $month, $day, $hour, $min, $sec) = explode(
4788
                    '[-: ]',
4789
                    $item['end_date']
4790
                );
4791
                $end_date = $year.$month.$day.$hour.$min;
4792
4793
                $items[] = [
4794
                    'datestart' => $start_date,
4795
                    'dateend' => $end_date,
4796
                    'title' => $item['title'],
4797
                    'link' => $URL,
4798
                    'coursetitle' => $c['name'],
4799
                ];
4800
            }
4801
        }
4802
4803
        return $items;
4804
    }
4805
4806
    /**
4807
     * This function calculates the startdate of the week (monday)
4808
     * and the enddate of the week (sunday)
4809
     * and returns it as an array.
4810
     */
4811
    public static function calculate_start_end_of_week($week_number, $year)
4812
    {
4813
        // determine the start and end date
4814
        // step 1: we calculate a timestamp for a day in this week
4815
        $random_day_in_week = mktime(
4816
                0,
4817
                0,
4818
                0,
4819
                1,
4820
                1,
4821
                $year
4822
            ) + ($week_number) * (7 * 24 * 60 * 60); // we calculate a random day in this week
4823
        // step 2: we which day this is (0=sunday, 1=monday, ...)
4824
        $number_day_in_week = date('w', $random_day_in_week);
4825
        // step 3: we calculate the timestamp of the monday of the week we are in
4826
        $start_timestamp = $random_day_in_week - (($number_day_in_week - 1) * 24 * 60 * 60);
4827
        // step 4: we calculate the timestamp of the sunday of the week we are in
4828
        $end_timestamp = $random_day_in_week + ((7 - $number_day_in_week + 1) * 24 * 60 * 60) - 3600;
4829
        // step 5: calculating the start_day, end_day, start_month, end_month, start_year, end_year
4830
        $start_day = date('j', $start_timestamp);
4831
        $start_month = date('n', $start_timestamp);
4832
        $start_year = date('Y', $start_timestamp);
4833
        $end_day = date('j', $end_timestamp);
4834
        $end_month = date('n', $end_timestamp);
4835
        $end_year = date('Y', $end_timestamp);
4836
        $start_end_array['start']['day'] = $start_day;
4837
        $start_end_array['start']['month'] = $start_month;
4838
        $start_end_array['start']['year'] = $start_year;
4839
        $start_end_array['end']['day'] = $end_day;
4840
        $start_end_array['end']['month'] = $end_month;
4841
        $start_end_array['end']['year'] = $end_year;
4842
4843
        return $start_end_array;
4844
    }
4845
4846
    /**
4847
     * @return bool
4848
     */
4849
    public function getIsAllowedToEdit()
4850
    {
4851
        return $this->isAllowedToEdit;
4852
    }
4853
4854
    /**
4855
     * @param bool $isAllowedToEdit
4856
     */
4857
    public function setIsAllowedToEdit($isAllowedToEdit)
4858
    {
4859
        $this->isAllowedToEdit = $isAllowedToEdit;
4860
    }
4861
4862
    /**
4863
     * Format needed for the Fullcalendar js lib.
4864
     *
4865
     * @param string $utcTime
4866
     *
4867
     * @return bool|string
4868
     */
4869
    public function formatEventDate($utcTime)
4870
    {
4871
        if ($utcTime instanceof DateTime) {
4872
            $eventDate = $utcTime;
4873
        } else {
4874
            $utcTimeZone = new DateTimeZone('UTC');
4875
            $eventDate = new DateTime($utcTime, $utcTimeZone);
4876
        }
4877
4878
        $platformTimeZone = new DateTimeZone(api_get_timezone());
4879
4880
        $eventDate->setTimezone($platformTimeZone);
4881
4882
        return $eventDate->format(DateTime::ISO8601);
4883
    }
4884
4885
    /**
4886
     * @throws \Doctrine\ORM\OptimisticLockException
4887
     * @throws \Doctrine\ORM\ORMException
4888
     * @throws \Doctrine\ORM\TransactionRequiredException
4889
     */
4890
    public static function saveCollectiveProperties(array $inviteeUserList, bool $isCollective, int $eventId)
4891
    {
4892
        if (empty($inviteeUserList)) {
4893
            return;
4894
        }
4895
4896
        $em = Database::getManager();
4897
4898
        $event = $em->find('ChamiloCoreBundle:PersonalAgenda', $eventId);
4899
4900
        $invitation = $event->getInvitation();
4901
4902
        if ($invitation instanceof AgendaEventSubscription) {
4903
            return;
4904
        }
4905
4906
        if (!$invitation) {
4907
            $invitation = new AgendaEventInvitation();
4908
            $invitation->setCreator(api_get_user_entity(api_get_user_id()));
4909
4910
            $event->setInvitation($invitation);
4911
        }
4912
4913
        $event->setCollective($isCollective);
4914
4915
        foreach ($inviteeUserList as $inviteeId) {
4916
            $userInvitee = api_get_user_entity($inviteeId);
4917
4918
            if (!$invitation->hasUserAsInvitee($userInvitee)) {
4919
                $invitee = new AgendaEventInvitee();
4920
                $invitee
4921
                    ->setUser($userInvitee)
4922
                    ->setInvitation($invitation)
4923
                ;
4924
4925
                $em->persist($invitee);
4926
            }
4927
        }
4928
4929
        $inviteesToRemove = $invitation->getInvitees()
4930
            ->filter(function (AgendaEventInvitee $invitee) use ($inviteeUserList): bool {
4931
                $userInvitee = $invitee->getUser();
4932
4933
                return !in_array($userInvitee->getUserId(), $inviteeUserList);
4934
            });
4935
4936
        foreach ($inviteesToRemove as $invitee) {
4937
            $em->remove($invitee);
4938
        }
4939
4940
        $em->flush();
4941
    }
4942
4943
    public static function getJsForReminders(string $cssSelectorBtnAdd): string
4944
    {
4945
        return '
4946
            var template = \'<div class="form-group">\' +
4947
                \'<div class="col-sm-offset-2 col-sm-3">\' +
4948
                \'<input min="0" step="1" id="notification_count[]" type="number" class=" form-control" name="notification_count[]">\' +
4949
                \'</div>\' +
4950
                \'<div class="col-sm-3">\' +
4951
                \'<select class="form-control" name="notification_period[]" id="form_notification_period[]">\' +
4952
                \'<option value="i">'.get_lang('Minutes').'</option>\' +
4953
                \'<option value="h">'.get_lang('Hours').'</option>\' +
4954
                \'<option value="d">'.get_lang('Days').'</option>\' +
4955
                \'</select>\' +
4956
                \'</div>\' +
4957
                \'<div class="col-sm-2"><p class="form-control-static">'.get_lang('Before').'</p></div>\' +
4958
                \'<div class="text-right col-sm-2">\' +
4959
                \'<button class="btn btn-default delete-notification" type="button" aria-label="'.get_lang('Delete').'"><em class="fa fa-times"></em></button>\' +
4960
                \'</div>\' +
4961
                \'</div>\';
4962
4963
            $("'.$cssSelectorBtnAdd.'").on("click", function (e) {
4964
                e.preventDefault();
4965
4966
                $(template).appendTo("#notification_list");
4967
                $("#notification_list select").selectpicker("refresh");
4968
            });
4969
4970
            $("#notification_list").on("click", ".delete-notification", function (e) {
4971
                e.preventDefault();
4972
4973
                $(this).parents(".form-group").remove();
4974
            });';
4975
    }
4976
4977
    public static function returnGoogleCalendarUrl(int $userId): ?string
4978
    {
4979
        $extraFieldInfo = UserManager::get_extra_user_data_by_field($userId, 'google_calendar_url');
4980
4981
        if (empty($extraFieldInfo) || empty($extraFieldInfo['google_calendar_url'])) {
4982
            return null;
4983
        }
4984
4985
        return $extraFieldInfo['google_calendar_url'];
4986
    }
4987
4988
    public static function returnFullCalendarExtraSettings(): ?string
4989
    {
4990
        $settings = api_get_configuration_value('fullcalendar_settings');
4991
4992
        if (empty($settings) || empty($settings['settings'])) {
4993
            return null;
4994
        }
4995
4996
        $encoded = json_encode($settings['settings']);
4997
4998
        return substr($encoded, 1, -1).',';
4999
    }
5000
5001
    public static function returnOnHoverInfo()
5002
    {
5003
        $onHoverInfo = api_get_configuration_value('agenda_on_hover_info');
5004
5005
        if (!empty($onHoverInfo)) {
5006
            return $onHoverInfo['options'];
5007
        }
5008
5009
        return [
5010
            'comment' => true,
5011
            'description' => true,
5012
        ];
5013
    }
5014
5015
    private function addCollectiveInvitationsFields(FormValidator $form, ?PersonalAgenda $personalEvent)
5016
    {
5017
        $invitees = [];
5018
        $isCollective = false;
5019
        $withInvitation = false;
5020
5021
        if ($personalEvent) {
5022
            $eventInvitation = $personalEvent->getInvitation();
5023
            $withInvitation = $eventInvitation && !($eventInvitation instanceof AgendaEventSubscription);
5024
5025
            if ($withInvitation) {
5026
                foreach ($eventInvitation->getInvitees() as $invitee) {
5027
                    $inviteeUser = $invitee->getUser();
5028
5029
                    $invitees[$inviteeUser->getId()] = $inviteeUser->getCompleteNameWithUsername();
5030
                }
5031
            }
5032
5033
            $isCollective = $personalEvent->isCollective();
5034
        }
5035
5036
        $form->addHtml(
5037
            '<div id="invitations-block" style="display: '.($withInvitation ? 'block;' : 'none;').'">'
5038
        );
5039
        $form->addHeader(get_lang('Invitations'));
5040
        $form->addSelectAjax(
5041
            'invitees',
5042
            get_lang('Invitees'),
5043
            $invitees,
5044
            [
5045
                'multiple' => 'multiple',
5046
                'url' => api_get_path(WEB_AJAX_PATH).'message.ajax.php?a=find_users',
5047
            ]
5048
        );
5049
        $form->addCheckBox('collective', '', get_lang('IsItEditableByTheInvitees'));
5050
        $form->addHtml('<hr>');
5051
        $form->addHtml('</div>');
5052
5053
        $form->setDefaults([
5054
            'invitees' => array_keys($invitees),
5055
            'collective' => $isCollective,
5056
        ]);
5057
    }
5058
5059
    private function addSubscriptionFields(FormValidator $form, ?PersonalAgenda $personalEvent)
5060
    {
5061
        $subscribers = [];
5062
        $withSubscription = false;
5063
        $maxSubscriptions = 0;
5064
        $groupId = null;
5065
5066
        if ($personalEvent) {
5067
            $eventInvitation = $personalEvent->getInvitation();
5068
            $withSubscription = $eventInvitation instanceof AgendaEventSubscription;
5069
            $maxSubscriptions = $withSubscription ? $eventInvitation->getMaxAttendees() : 0;
5070
            $groupId = $personalEvent->getSubscriptionItemId();
5071
5072
            $subscribers = self::getInviteesForPersonalEvent($personalEvent->getId(), AgendaEventSubscriber::class);
5073
            $subscribers = array_combine(
5074
                array_column($subscribers, 'id'),
5075
                array_column($subscribers, 'name')
5076
            );
5077
        }
5078
5079
        $form->addHtml(
5080
            '<div id="subscriptions-block" style="display: '.($withSubscription ? 'block;' : 'none;').'">'
5081
        );
5082
        $form->addHeader(get_lang('Subscriptions'));
5083
        $form->addSelect(
5084
            'subscription_visibility',
5085
            get_lang('AllowSubscriptions'),
5086
            [
5087
                AgendaEventSubscription::SUBSCRIPTION_NO => get_lang('No'),
5088
                AgendaEventSubscription::SUBSCRIPTION_ALL => get_lang('AllUsersOfThePlatform'),
5089
                AgendaEventSubscription::SUBSCRIPTION_CLASS => get_lang('UsersInsideClass'),
5090
            ]
5091
        );
5092
        $slctItem = $form->addSelectAjax(
5093
            'subscription_item',
5094
            get_lang('SocialGroup').' / '.get_lang('Class'),
5095
            [],
5096
            [
5097
                'url' => api_get_path(WEB_AJAX_PATH).'usergroup.ajax.php?a=get_class_by_keyword',
5098
                'disabled' => 'disabled',
5099
            ]
5100
        );
5101
5102
        $form->addNumeric(
5103
            'max_subscriptions',
5104
            ['', get_lang('MaxSubscriptionsLeaveEmptyToNotLimit')],
5105
            [
5106
                'disabled' => 'disabled',
5107
                'step' => 1,
5108
                'min' => 0,
5109
                'value' => 0,
5110
            ]
5111
        );
5112
        $form->addHtml("<script>
5113
            $(function () {
5114
                $('#add_event_subscription_visibility')
5115
                    .on('change', function () {
5116
                        $('#max_subscriptions').prop('disabled', this.value == 0);
5117
                        $('#add_event_subscription_item').prop('disabled', this.value != 2);
5118
                    })
5119
                    .trigger('change');
5120
            })
5121
            </script>
5122
        ");
5123
5124
        $form->addSelect(
5125
            'subscribers',
5126
            get_lang('Subscribers'),
5127
            $subscribers,
5128
            ['multiple' => 'multiple']
5129
        );
5130
5131
        $form->setDefaults([
5132
            'subscribers' => array_keys($subscribers),
5133
            'max_subscriptions' => $maxSubscriptions,
5134
        ]);
5135
5136
        if ($groupId) {
5137
            $objUserGroup = new UserGroup();
5138
5139
            $groupInfo = $objUserGroup->get($groupId);
5140
5141
            $slctItem->addOption($groupInfo['name'], $groupId);
5142
        }
5143
5144
        $form->addHtml('</div>');
5145
    }
5146
5147
    private function editReminders(int $eventId, array $reminderList = [])
5148
    {
5149
        if (false === api_get_configuration_value('agenda_reminders')) {
5150
            return;
5151
        }
5152
5153
        $eventReminders = $this->parseEventReminders(
5154
            $this->getEventReminders($eventId)
5155
        );
5156
        $eventIntervalList = array_column($eventReminders, 'date_interval');
5157
5158
        foreach ($eventIntervalList as $eventIntervalInfo) {
5159
            if (!in_array($eventIntervalInfo, $reminderList)) {
5160
                $this->removeReminders($eventId, $eventIntervalInfo[0], $eventIntervalInfo[1]);
5161
            }
5162
        }
5163
5164
        foreach ($reminderList as $reminderInfo) {
5165
            if (!in_array($reminderInfo, $eventIntervalList)) {
5166
                $this->addReminder($eventId, $reminderInfo[0], $reminderInfo[1]);
5167
            }
5168
        }
5169
    }
5170
5171
    private static function isUserInvitedInEvent(int $id, int $userId): bool
5172
    {
5173
        $user = api_get_user_entity($userId);
5174
5175
        $event = Database::getManager()
5176
            ->getRepository('ChamiloCoreBundle:PersonalAgenda')
5177
            ->findOneByIdAndInvitee($id, $user)
5178
        ;
5179
5180
        return null !== $event;
5181
    }
5182
5183
    private function loadEventsAsInvitee(User $user, ?DateTime $startDate, ?DateTime $endDate)
5184
    {
5185
        $em = Database::getManager();
5186
        $eventRepo = $em->getRepository('ChamiloCoreBundle:PersonalAgenda');
5187
        $events = $eventRepo->getEventsForInvitee($user, $startDate, $endDate);
5188
5189
        foreach ($events as $event) {
5190
            $eventInfo = [];
5191
            $eventInfo['id'] = 'personal_'.$event->getId();
5192
            $eventInfo['title'] = $event->getTitle();
5193
            $eventInfo['className'] = 'personal';
5194
            $eventInfo['borderColor'] = $eventInfo['backgroundColor'] = $this->event_personal_color;
5195
            $eventInfo['editable'] = $event->isCollective();
5196
            $eventInfo['sent_to'] = get_lang('Me');
5197
            $eventInfo['type'] = 'personal';
5198
5199
            if ($event->getDate()) {
5200
                $eventInfo['start'] = $this->formatEventDate($event->getDate()->format('Y-m-d H:i:s'));
5201
                $eventInfo['start_date_localtime'] = api_get_local_time($event->getDate());
5202
            }
5203
5204
            if ($event->getEnddate()) {
5205
                $eventInfo['end'] = $this->formatEventDate($event->getEnddate()->format('Y-m-d H:i:s'));
5206
                $eventInfo['end_date_localtime'] = api_get_local_time($event->getEnddate());
5207
            }
5208
5209
            $eventInfo['description'] = $event->getText();
5210
            $eventInfo['allDay'] = $event->getAllDay();
5211
            $eventInfo['parent_event_id'] = 0;
5212
            $eventInfo['has_children'] = 0;
5213
            $eventInfo['collective'] = $event->isCollective();
5214
            $eventInfo['invitees'] = [];
5215
5216
            $invitation = $event->getInvitation();
5217
5218
            if ($invitation) {
5219
                foreach ($invitation->getInvitees() as $invitee) {
5220
                    $inviteeUser = $invitee->getUser();
5221
5222
                    if (!is_null($inviteeUser)) {
5223
                        $eventInfo['invitees'][] = [
5224
                            'id' => $inviteeUser->getId(),
5225
                            'name' => $inviteeUser->getCompleteNameWithUsername(),
5226
                        ];
5227
                    }
5228
                }
5229
            }
5230
5231
            $this->events[] = $eventInfo;
5232
        }
5233
    }
5234
5235
    /**
5236
     * @throws Exception
5237
     */
5238
    private function convertSessionWithDuration(int $userId, array $sessionInfo, DateTime $start, DateTime $end): array
5239
    {
5240
        $courseAccess = CourseManager::getFirstCourseAccessPerSessionAndUser(
5241
            $sessionInfo['session_id'],
5242
            $userId
5243
        );
5244
5245
        if (empty($courseAccess)) {
5246
            throw new Exception();
5247
        }
5248
5249
        $firstAccessDate = new DateTime($courseAccess['login_course_date'], new DateTimeZone('UTC'));
5250
        $lastAccessDate = clone $firstAccessDate;
5251
        $lastAccessDate->modify('+'.$sessionInfo['duration'].' days');
5252
5253
        if ($firstAccessDate->format('Y-m-d H:i:s') > $start
5254
            && $lastAccessDate->format('Y-m-d H:i:s') < $end
5255
        ) {
5256
            throw new Exception();
5257
        }
5258
5259
        $courseList = SessionManager::get_course_list_by_session_id($sessionInfo['id']);
5260
        $firstCourse = current($courseList);
5261
5262
        return [
5263
            'id' => 'session_'.$sessionInfo['id'],
5264
            'session_id' => $sessionInfo['id'],
5265
            'title' => $sessionInfo['name'],
5266
            'description' => $sessionInfo['show_description'] ? $sessionInfo['description'] : '',
5267
            'className' => 'personal',
5268
            'borderColor' => $this->event_personal_color,
5269
            'backgroundColor' => $this->event_personal_color,
5270
            'editable' => false,
5271
            'sent_to' => get_lang('Me'),
5272
            'type' => 'session',
5273
            'start' => $firstAccessDate->format(DateTime::ISO8601),
5274
            'start_date_localtime' => api_get_local_time($firstAccessDate),
5275
            'end' => $lastAccessDate->format(DateTime::ISO8601),
5276
            'end_date_localtime' => api_get_local_time($lastAccessDate),
5277
            'allDay' => 0,
5278
            'parent_event_id' => 0,
5279
            'has_children' => 0,
5280
            'course_url' => api_get_course_url($firstCourse['code'], $sessionInfo['id']),
5281
        ];
5282
    }
5283
5284
    /**
5285
     * @throws Exception
5286
     */
5287
    private function convertSessionWithDates(array $sessionInfo, DateTime $start, DateTime $end): array
5288
    {
5289
        if ($sessionInfo['display_start_date'] < $start
5290
            && $sessionInfo['display_end_date'] > $end
5291
        ) {
5292
            throw new Exception();
5293
        }
5294
5295
        $courseList = SessionManager::get_course_list_by_session_id($sessionInfo['id']);
5296
        $firstCourse = current($courseList);
5297
5298
        return [
5299
            'id' => 'session_'.$sessionInfo['id'],
5300
            'session_id' => $sessionInfo['id'],
5301
            'title' => $sessionInfo['name'],
5302
            'description' => $sessionInfo['show_description'] ? $sessionInfo['description'] : '',
5303
            'className' => 'personal',
5304
            'borderColor' => $this->event_personal_color,
5305
            'backgroundColor' => $this->event_personal_color,
5306
            'editable' => false,
5307
            'sent_to' => get_lang('Me'),
5308
            'type' => 'session_subscription',
5309
            'start' => $sessionInfo['display_start_date'],
5310
            'start_date_localtime' => $sessionInfo['display_start_date']
5311
                ? $this->formatEventDate($sessionInfo['display_start_date'])
5312
                : '',
5313
            'end' => $sessionInfo['display_end_date'],
5314
            'end_date_localtime' => $sessionInfo['display_end_date']
5315
                ? $this->formatEventDate($sessionInfo['display_end_date'])
5316
                : '',
5317
            'allDay' => 0,
5318
            'parent_event_id' => 0,
5319
            'has_children' => 0,
5320
            'course_url' => api_get_course_url($firstCourse['code'], $sessionInfo['id']),
5321
        ];
5322
    }
5323
5324
    private function loadSessionsAsEvents(int $start, int $end)
5325
    {
5326
        if (false === api_get_configuration_value('personal_calendar_show_sessions_occupation')) {
5327
            return;
5328
        }
5329
5330
        $start = api_get_utc_datetime($start, false, true);
5331
        $end = api_get_utc_datetime($end, false, true);
5332
        $userInfo = api_get_user_info();
5333
        $sessionList = SessionManager::getSessionsFollowedByUser($userInfo['id'], $userInfo['status']);
5334
5335
        foreach ($sessionList as $sessionInfo) {
5336
            if (!empty($sessionInfo['duration'])) {
5337
                try {
5338
                    $this->events[] = $this->convertSessionWithDuration($userInfo['id'], $sessionInfo, $start, $end);
5339
                } catch (Exception $e) {
5340
                    continue;
5341
                }
5342
5343
                continue;
5344
            }
5345
5346
            if (empty($sessionInfo['display_start_date']) || empty($sessionInfo['display_end_date'])) {
5347
                continue;
5348
            }
5349
5350
            try {
5351
                $this->events[] = $this->convertSessionWithDates($sessionInfo, $start, $end);
5352
            } catch (Exception $e) {
5353
                continue;
5354
            }
5355
        }
5356
    }
5357
}
5358