Passed
Pull Request — 1.11.x (#4204)
by Angel Fernando Quiroz
09:51
created

Agenda::editEvent()   F

Complexity

Conditions 51
Paths 8280

Size

Total Lines 348
Code Lines 210

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 1
Metric Value
eloc 210
c 4
b 0
f 1
dl 0
loc 348
rs 0
cc 51
nop 19
nc 8280

How to fix   Long Method    Complexity    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Many Parameters

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

There are several approaches to avoid long parameter lists:

1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
use Chamilo\CoreBundle\Entity\AgendaEventInvitation;
6
use Chamilo\CoreBundle\Entity\AgendaEventInvitee;
7
use Chamilo\CoreBundle\Entity\AgendaReminder;
8
use Chamilo\UserBundle\Entity\User;
9
10
/**
11
 * Class Agenda.
12
 *
13
 * @author: Julio Montoya <[email protected]>
14
 */
15
class Agenda
16
{
17
    public $events = [];
18
    /** @var string Current type */
19
    public $type = 'personal';
20
    public $types = ['personal', 'admin', 'course'];
21
    public $sessionId = 0;
22
    public $senderId;
23
    /** @var array */
24
    public $course;
25
    /** @var string */
26
    public $comment;
27
    public $eventStudentPublicationColor;
28
    /** @var array */
29
    private $sessionInfo;
30
    /** @var bool */
31
    private $isAllowedToEdit;
32
33
    /**
34
     * Constructor.
35
     *
36
     * @param string $type
37
     * @param int    $senderId  Optional The user sender ID
38
     * @param int    $courseId  Optional. The course ID
39
     * @param int    $sessionId Optional The session ID
40
     */
41
    public function __construct(
42
        $type,
43
        $senderId = 0,
44
        $courseId = 0,
45
        $sessionId = 0
46
    ) {
47
        // Table definitions
48
        $this->tbl_global_agenda = Database::get_main_table(TABLE_MAIN_SYSTEM_CALENDAR);
49
        $this->tbl_personal_agenda = Database::get_main_table(TABLE_PERSONAL_AGENDA);
50
        $this->tbl_course_agenda = Database::get_course_table(TABLE_AGENDA);
51
        $this->table_repeat = Database::get_course_table(TABLE_AGENDA_REPEAT);
52
53
        $this->setType($type);
54
        $this->setSenderId($senderId ?: api_get_user_id());
55
        $isAllowToEdit = false;
56
57
        switch ($type) {
58
            case 'course':
59
                $sessionId = $sessionId ?: api_get_session_id();
60
                $sessionInfo = api_get_session_info($sessionId);
61
                $this->setSessionId($sessionId);
62
                $this->setSessionInfo($sessionInfo);
63
64
                // Setting the course object if we are in a course
65
                $courseInfo = api_get_course_info_by_id($courseId);
66
                if (!empty($courseInfo)) {
67
                    $this->set_course($courseInfo);
68
                }
69
70
                // Check if teacher/admin rights.
71
                $isAllowToEdit = api_is_allowed_to_edit(false, true);
72
                // Check course setting.
73
                if (api_get_course_setting('allow_user_edit_agenda') == '1'
74
                    && api_is_allowed_in_course()
75
                ) {
76
                    $isAllowToEdit = true;
77
                }
78
79
                $groupId = api_get_group_id();
80
                if (!empty($groupId)) {
81
                    $groupInfo = GroupManager::get_group_properties($groupId);
82
                    $userHasAccess = GroupManager::user_has_access(
83
                        api_get_user_id(),
84
                        $groupInfo['iid'],
85
                        GroupManager::GROUP_TOOL_CALENDAR
86
                    );
87
                    $isTutor = GroupManager::is_tutor_of_group(
88
                        api_get_user_id(),
89
                        $groupInfo
90
                    );
91
92
                    $isGroupAccess = $userHasAccess || $isTutor;
93
                    $isAllowToEdit = false;
94
                    if ($isGroupAccess) {
95
                        $isAllowToEdit = true;
96
                    }
97
                }
98
99
                if (false === $isAllowToEdit && !empty($sessionId)) {
100
                    $allowDhrToEdit = api_get_configuration_value('allow_agenda_edit_for_hrm');
101
                    if ($allowDhrToEdit) {
102
                        $isHrm = SessionManager::isUserSubscribedAsHRM($sessionId, api_get_user_id());
103
                        if ($isHrm) {
104
                            $isAllowToEdit = true;
105
                        }
106
                    }
107
                }
108
                break;
109
            case 'admin':
110
                $isAllowToEdit = api_is_platform_admin();
111
                break;
112
            case 'personal':
113
                $isAllowToEdit = !api_is_anonymous();
114
                break;
115
        }
116
117
        $this->setIsAllowedToEdit($isAllowToEdit);
118
        $this->events = [];
119
        $agendaColors = array_merge(
120
            [
121
                'platform' => 'red', //red
122
                'course' => '#458B00', //green
123
                'group' => '#A0522D', //siena
124
                'session' => '#00496D', // kind of green
125
                'other_session' => '#999', // kind of green
126
                'personal' => 'steel blue', //steel blue
127
                'student_publication' => '#FF8C00', //DarkOrange
128
            ],
129
            api_get_configuration_value('agenda_colors') ?: []
130
        );
131
132
        // Event colors
133
        $this->event_platform_color = $agendaColors['platform'];
134
        $this->event_course_color = $agendaColors['course'];
135
        $this->event_group_color = $agendaColors['group'];
136
        $this->event_session_color = $agendaColors['session'];
137
        $this->eventOtherSessionColor = $agendaColors['other_session'];
138
        $this->event_personal_color = $agendaColors['personal'];
139
        $this->eventStudentPublicationColor = $agendaColors['student_publication'];
140
    }
141
142
    /**
143
     * @param int $senderId
144
     */
145
    public function setSenderId($senderId)
146
    {
147
        $this->senderId = (int) $senderId;
148
    }
149
150
    /**
151
     * @return int
152
     */
153
    public function getSenderId()
154
    {
155
        return $this->senderId;
156
    }
157
158
    /**
159
     * @param string $type can be 'personal', 'admin'  or  'course'
160
     */
161
    public function setType($type)
162
    {
163
        $type = (string) trim($type);
164
        $typeList = $this->getTypes();
165
        if (in_array($type, $typeList, true)) {
166
            $this->type = $type;
167
        }
168
    }
169
170
    /**
171
     * Returns the type previously set (and filtered) through setType
172
     * If setType() was not called, then type defaults to "personal" as
173
     * set in the class definition.
174
     */
175
    public function getType()
176
    {
177
        if (isset($this->type)) {
178
            return $this->type;
179
        }
180
    }
181
182
    /**
183
     * @param int $id
184
     */
185
    public function setSessionId($id)
186
    {
187
        $this->sessionId = (int) $id;
188
    }
189
190
    /**
191
     * @param array $sessionInfo
192
     */
193
    public function setSessionInfo($sessionInfo)
194
    {
195
        $this->sessionInfo = $sessionInfo;
196
    }
197
198
    /**
199
     * @return int $id
200
     */
201
    public function getSessionId()
202
    {
203
        return $this->sessionId;
204
    }
205
206
    /**
207
     * @param array $courseInfo
208
     */
209
    public function set_course($courseInfo)
210
    {
211
        $this->course = $courseInfo;
212
    }
213
214
    /**
215
     * @return array
216
     */
217
    public function getTypes()
218
    {
219
        return $this->types;
220
    }
221
222
    /**
223
     * Adds an event to the calendar.
224
     *
225
     * @param string $start                 datetime format: 2012-06-14 09:00:00 in local time
226
     * @param string $end                   datetime format: 2012-06-14 09:00:00 in local time
227
     * @param string $allDay                (true, false)
228
     * @param string $title
229
     * @param string $content
230
     * @param array  $usersToSend           array('everyone') or a list of user/group ids
231
     * @param bool   $addAsAnnouncement     event as a *course* announcement
232
     * @param int    $parentEventId
233
     * @param array  $attachmentArray       array of $_FILES['']
234
     * @param array  $attachmentCommentList
235
     * @param string $eventComment
236
     * @param string $color
237
     *
238
     * @return int
239
     */
240
    public function addEvent(
241
        $start,
242
        $end,
243
        $allDay,
244
        $title,
245
        $content,
246
        $usersToSend = [],
247
        $addAsAnnouncement = false,
248
        $parentEventId = null,
249
        $attachmentArray = [],
250
        $attachmentCommentList = [],
251
        $eventComment = null,
252
        $color = '',
253
        array $inviteesList = [],
254
        bool $isCollective = false,
255
        array $reminders = [],
256
        int $careerId = 0,
257
        int $promotionId = 0
258
    ) {
259
        $start = api_get_utc_datetime($start);
260
        $end = api_get_utc_datetime($end);
261
        $allDay = isset($allDay) && ($allDay === 'true' || $allDay == 1) ? 1 : 0;
262
        $id = null;
263
264
        switch ($this->type) {
265
            case 'personal':
266
                $attributes = [
267
                    'user' => api_get_user_id(),
268
                    'title' => $title,
269
                    'text' => $content,
270
                    'date' => $start,
271
                    'enddate' => $end,
272
                    'all_day' => $allDay,
273
                    'color' => $color,
274
                ];
275
276
                $id = Database::insert(
277
                    $this->tbl_personal_agenda,
278
                    $attributes
279
                );
280
281
                if (api_get_configuration_value('agenda_collective_invitations')) {
282
                    Agenda::saveCollectiveProperties($inviteesList, $isCollective, $id);
283
                }
284
                break;
285
            case 'course':
286
                $attributes = [
287
                    'title' => $title,
288
                    'content' => $content,
289
                    'start_date' => $start,
290
                    'end_date' => $end,
291
                    'all_day' => $allDay,
292
                    'session_id' => $this->getSessionId(),
293
                    'c_id' => $this->course['real_id'],
294
                    'comment' => $eventComment,
295
                    'color' => $color,
296
                ];
297
298
                if (!empty($parentEventId)) {
299
                    $attributes['parent_event_id'] = $parentEventId;
300
                }
301
302
                $senderId = $this->getSenderId();
303
                $sessionId = $this->getSessionId();
304
305
                // Simple course event.
306
                $id = Database::insert($this->tbl_course_agenda, $attributes);
307
308
                if ($id) {
309
                    $sql = "UPDATE ".$this->tbl_course_agenda." SET id = iid WHERE iid = $id";
310
                    Database::query($sql);
311
312
                    $groupId = api_get_group_id();
313
                    $groupInfo = [];
314
                    if ($groupId) {
315
                        $groupInfo = GroupManager::get_group_properties(
316
                            $groupId
317
                        );
318
                    }
319
320
                    if (!empty($usersToSend)) {
321
                        $sendTo = $this->parseSendToArray($usersToSend);
322
                        if ($sendTo['everyone']) {
323
                            api_item_property_update(
324
                                $this->course,
325
                                TOOL_CALENDAR_EVENT,
326
                                $id,
327
                                'AgendaAdded',
328
                                $senderId,
329
                                $groupInfo,
330
                                '',
331
                                $start,
332
                                $end,
333
                                $sessionId
334
                            );
335
                            api_item_property_update(
336
                                $this->course,
337
                                TOOL_CALENDAR_EVENT,
338
                                $id,
339
                                'visible',
340
                                $senderId,
341
                                $groupInfo,
342
                                '',
343
                                $start,
344
                                $end,
345
                                $sessionId
346
                            );
347
                        } else {
348
                            // Storing the selected groups
349
                            if (!empty($sendTo['groups'])) {
350
                                foreach ($sendTo['groups'] as $group) {
351
                                    $groupInfoItem = [];
352
                                    if ($group) {
353
                                        $groupInfoItem = GroupManager::get_group_properties($group);
354
                                    }
355
356
                                    api_item_property_update(
357
                                        $this->course,
358
                                        TOOL_CALENDAR_EVENT,
359
                                        $id,
360
                                        'AgendaAdded',
361
                                        $senderId,
362
                                        $groupInfoItem,
363
                                        0,
364
                                        $start,
365
                                        $end,
366
                                        $sessionId
367
                                    );
368
369
                                    api_item_property_update(
370
                                        $this->course,
371
                                        TOOL_CALENDAR_EVENT,
372
                                        $id,
373
                                        'visible',
374
                                        $senderId,
375
                                        $groupInfoItem,
376
                                        0,
377
                                        $start,
378
                                        $end,
379
                                        $sessionId
380
                                    );
381
                                }
382
                            }
383
384
                            // storing the selected users
385
                            if (!empty($sendTo['users'])) {
386
                                foreach ($sendTo['users'] as $userId) {
387
                                    api_item_property_update(
388
                                        $this->course,
389
                                        TOOL_CALENDAR_EVENT,
390
                                        $id,
391
                                        'AgendaAdded',
392
                                        $senderId,
393
                                        $groupInfo,
394
                                        $userId,
395
                                        $start,
396
                                        $end,
397
                                        $sessionId
398
                                    );
399
400
                                    api_item_property_update(
401
                                        $this->course,
402
                                        TOOL_CALENDAR_EVENT,
403
                                        $id,
404
                                        'visible',
405
                                        $senderId,
406
                                        $groupInfo,
407
                                        $userId,
408
                                        $start,
409
                                        $end,
410
                                        $sessionId
411
                                    );
412
                                }
413
                            }
414
                        }
415
                    }
416
417
                    // Add announcement.
418
                    if ($addAsAnnouncement) {
419
                        $this->storeAgendaEventAsAnnouncement(
420
                            $id,
421
                            $usersToSend
422
                        );
423
                    }
424
425
                    // Add attachment.
426
                    if (isset($attachmentArray) && !empty($attachmentArray)) {
427
                        $counter = 0;
428
                        foreach ($attachmentArray as $attachmentItem) {
429
                            $this->addAttachment(
430
                                $id,
431
                                $attachmentItem,
432
                                $attachmentCommentList[$counter],
433
                                $this->course
434
                            );
435
                            $counter++;
436
                        }
437
                    }
438
                }
439
                break;
440
            case 'admin':
441
                if (api_is_platform_admin()) {
442
                    $attributes = [
443
                        'title' => $title,
444
                        'content' => $content,
445
                        'start_date' => $start,
446
                        'end_date' => $end,
447
                        'all_day' => $allDay,
448
                        'access_url_id' => api_get_current_access_url_id(),
449
                    ];
450
451
                    if (api_get_configuration_value('allow_carrers_in_global_agenda')) {
452
                        $attributes['career_id'] = $careerId;
453
                        $attributes['promotion_id'] = $promotionId;
454
                    }
455
456
                    $id = Database::insert(
457
                        $this->tbl_global_agenda,
458
                        $attributes
459
                    );
460
                }
461
                break;
462
        }
463
464
        if (api_get_configuration_value('agenda_reminders')) {
465
            foreach ($reminders as $reminder) {
466
                $this->addReminder($id, $reminder[0], $reminder[1]);
467
            }
468
        }
469
470
        return $id;
471
    }
472
473
    /**
474
     * @throws Exception
475
     */
476
    public function addReminder($eventId, $count, $period)
477
    {
478
        switch ($period) {
479
            case 'i':
480
                $dateInterval = DateInterval::createFromDateString("$count minutes");
481
                break;
482
            case 'h':
483
                $dateInterval = DateInterval::createFromDateString("$count hours");
484
                break;
485
            case 'd':
486
                $dateInterval = DateInterval::createFromDateString("$count days");
487
                break;
488
            default:
489
                return null;
490
        }
491
492
        $agendaReminder = new AgendaReminder();
493
        $agendaReminder
494
            ->setType($this->type)
495
            ->setEventId($eventId)
496
            ->setDateInterval($dateInterval)
497
        ;
498
499
        $em = Database::getManager();
500
        $em->persist($agendaReminder);
501
        $em->flush();
502
    }
503
504
    public function removeReminders(int $eventId, int $count, string $period)
505
    {
506
        switch ($period) {
507
            case 'i':
508
                $dateInterval = DateInterval::createFromDateString("$count minutes");
509
                break;
510
            case 'h':
511
                $dateInterval = DateInterval::createFromDateString("$count hours");
512
                break;
513
            case 'd':
514
                $dateInterval = DateInterval::createFromDateString("$count days");
515
                break;
516
            default:
517
                return null;
518
        }
519
520
        Database::getManager()
521
            ->createQuery(
522
                'DELETE FROM ChamiloCoreBundle:AgendaReminder ar
523
                WHERE ar.eventId = :eventId AND ar.type = :type AND ar.dateInterval = :dateInterval'
524
            )
525
            ->setParameters(
526
                [
527
                    'eventId' => $eventId,
528
                    'type' => $this->type,
529
                    'dateInterval' => $dateInterval,
530
                ]
531
            )
532
            ->execute();
533
    }
534
535
    public function getReminder(int $eventId, int $count, string $period)
536
    {
537
        switch ($period) {
538
            case 'i':
539
                $dateInterval = DateInterval::createFromDateString("$count minutes");
540
                break;
541
            case 'h':
542
                $dateInterval = DateInterval::createFromDateString("$count hours");
543
                break;
544
            case 'd':
545
                $dateInterval = DateInterval::createFromDateString("$count days");
546
                break;
547
            default:
548
                return null;
549
        }
550
551
        $em = Database::getManager();
552
        $remindersRepo = $em->getRepository('ChamiloCoreBundle:AgendaReminder');
553
554
        return $remindersRepo->findOneBy(
555
            [
556
                'type' => $this->type,
557
                'dateInterval' => $dateInterval,
558
                'eventId' => $eventId,
559
            ]
560
        );
561
    }
562
563
    /**
564
     * @param int $eventId
565
     * @param int $courseId
566
     *
567
     * @return array
568
     */
569
    public function getRepeatedInfoByEvent($eventId, $courseId)
570
    {
571
        $repeatTable = Database::get_course_table(TABLE_AGENDA_REPEAT);
572
        $eventId = (int) $eventId;
573
        $courseId = (int) $courseId;
574
        $sql = "SELECT * FROM $repeatTable
575
                WHERE c_id = $courseId AND cal_id = $eventId";
576
        $res = Database::query($sql);
577
        $repeatInfo = [];
578
        if (Database::num_rows($res) > 0) {
579
            $repeatInfo = Database::fetch_array($res, 'ASSOC');
580
        }
581
582
        return $repeatInfo;
583
    }
584
585
    /**
586
     * @param string $type
587
     * @param string $startEvent      in UTC
588
     * @param string $endEvent        in UTC
589
     * @param string $repeatUntilDate in UTC
590
     *
591
     * @throws Exception
592
     *
593
     * @return array with local times
594
     */
595
    public function generateDatesByType($type, $startEvent, $endEvent, $repeatUntilDate)
596
    {
597
        $continue = true;
598
        $repeatUntilDate = new DateTime($repeatUntilDate, new DateTimeZone('UTC'));
599
        $loopMax = 365;
600
        $counter = 0;
601
        $list = [];
602
603
        switch ($type) {
604
            case 'daily':
605
                $interval = 'P1D';
606
                break;
607
            case 'weekly':
608
                $interval = 'P1W';
609
                break;
610
            case 'monthlyByDate':
611
                $interval = 'P1M';
612
                break;
613
            case 'monthlyByDay':
614
                // not yet implemented
615
                break;
616
            case 'monthlyByDayR':
617
                // not yet implemented
618
                break;
619
            case 'yearly':
620
                $interval = 'P1Y';
621
                break;
622
        }
623
624
        if (empty($interval)) {
625
            return [];
626
        }
627
        $timeZone = api_get_timezone();
628
629
        while ($continue) {
630
            $startDate = new DateTime($startEvent, new DateTimeZone('UTC'));
631
            $endDate = new DateTime($endEvent, new DateTimeZone('UTC'));
632
633
            $startDate->add(new DateInterval($interval));
634
            $endDate->add(new DateInterval($interval));
635
636
            $newStartDate = $startDate->format('Y-m-d H:i:s');
637
            $newEndDate = $endDate->format('Y-m-d H:i:s');
638
639
            $startEvent = $newStartDate;
640
            $endEvent = $newEndDate;
641
642
            if ($endDate > $repeatUntilDate) {
643
                break;
644
            }
645
646
            // @todo remove comment code
647
            // The code below was not adpating to saving light time but was doubling the difference with UTC time.
648
            // Might be necessary to adapt to update saving light time difference.
649
            /*            $startDateInLocal = new DateTime($newStartDate, new DateTimeZone($timeZone));
650
                        if ($startDateInLocal->format('I') == 0) {
651
                            // Is saving time? Then fix UTC time to add time
652
                            $seconds = $startDateInLocal->getOffset();
653
                            $startDate->add(new DateInterval("PT".$seconds."S"));
654
                            //$startDateFixed = $startDate->format('Y-m-d H:i:s');
655
                            //$startDateInLocalFixed = new DateTime($startDateFixed, new DateTimeZone($timeZone));
656
                            //$newStartDate = $startDateInLocalFixed->format('Y-m-d H:i:s');
657
                            //$newStartDate = $startDate->setTimezone(new DateTimeZone($timeZone))->format('Y-m-d H:i:s');
658
                        }
659
660
                        $endDateInLocal = new DateTime($newEndDate, new DateTimeZone($timeZone));
661
                        if ($endDateInLocal->format('I') == 0) {
662
                            // Is saving time? Then fix UTC time to add time
663
                            $seconds = $endDateInLocal->getOffset();
664
                            $endDate->add(new DateInterval("PT".$seconds."S"));
665
                            //$endDateFixed = $endDate->format('Y-m-d H:i:s');
666
                            //$endDateInLocalFixed = new DateTime($endDateFixed, new DateTimeZone($timeZone));
667
                            //$newEndDate = $endDateInLocalFixed->format('Y-m-d H:i:s');
668
                    }
669
            */
670
            $newStartDate = $startDate->setTimezone(new DateTimeZone($timeZone))->format('Y-m-d H:i:s');
671
            $newEndDate = $endDate->setTimezone(new DateTimeZone($timeZone))->format('Y-m-d H:i:s');
672
            $list[] = ['start' => $newStartDate, 'end' => $newEndDate];
673
            $counter++;
674
675
            // just in case stop if more than $loopMax
676
            if ($counter > $loopMax) {
677
                break;
678
            }
679
        }
680
681
        return $list;
682
    }
683
684
    /**
685
     * @param int    $eventId
686
     * @param string $type
687
     * @param string $end     in UTC
688
     * @param array  $sentTo
689
     *
690
     * @return bool
691
     */
692
    public function addRepeatedItem($eventId, $type, $end, $sentTo = [])
693
    {
694
        $t_agenda = Database::get_course_table(TABLE_AGENDA);
695
        $t_agenda_r = Database::get_course_table(TABLE_AGENDA_REPEAT);
696
697
        if (empty($this->course)) {
698
            return false;
699
        }
700
701
        $courseId = $this->course['real_id'];
702
        $eventId = (int) $eventId;
703
704
        $sql = "SELECT title, content, start_date, end_date, all_day
705
                FROM $t_agenda
706
                WHERE c_id = $courseId AND id = $eventId";
707
        $res = Database::query($sql);
708
709
        if (Database::num_rows($res) !== 1) {
710
            return false;
711
        }
712
713
        $typeList = [
714
            'daily',
715
            'weekly',
716
            'monthlyByDate',
717
            'monthlyByDay',
718
            'monthlyByDayR',
719
            'yearly',
720
        ];
721
722
        if (!in_array($type, $typeList)) {
723
            return false;
724
        }
725
726
        $now = time();
727
728
        // The event has to repeat *in the future*. We don't allow repeated
729
        // events in the past.
730
        $endTimeStamp = api_strtotime($end, 'UTC');
731
732
        if ($endTimeStamp < $now) {
733
            return false;
734
        }
735
736
        $row = Database::fetch_array($res);
737
738
        $title = $row['title'];
739
        $content = $row['content'];
740
        $allDay = $row['all_day'];
741
742
        $type = Database::escape_string($type);
743
        $end = Database::escape_string($end);
744
745
        $sql = "INSERT INTO $t_agenda_r (c_id, cal_id, cal_type, cal_end)
746
                VALUES ($courseId, '$eventId', '$type', '$endTimeStamp')";
747
        Database::query($sql);
748
749
        $generatedDates = $this->generateDatesByType($type, $row['start_date'], $row['end_date'], $end);
750
751
        if (empty($generatedDates)) {
752
            return false;
753
        }
754
755
        foreach ($generatedDates as $dateInfo) {
756
//            $start = api_get_local_time($dateInfo['start']);
757
//            $end = api_get_local_time($dateInfo['end']);
758
            // On line 529 in function generateDatesByType there is a @todo remove comment code
759
            // just before the part updating the date in local time so keep both synchronised
760
            $start = $dateInfo['start'];
761
            $end = $dateInfo['end'];
762
763
            $this->addEvent(
764
                $start,
765
                $end,
766
                $allDay,
767
                $title,
768
                $content,
769
                $sentTo,
770
                false,
771
                $eventId
772
            );
773
        }
774
775
        return true;
776
    }
777
778
    /**
779
     * @param int   $item_id
780
     * @param array $sentTo
781
     *
782
     * @return int
783
     */
784
    public function storeAgendaEventAsAnnouncement($item_id, $sentTo = [])
785
    {
786
        $table_agenda = Database::get_course_table(TABLE_AGENDA);
787
        $courseId = api_get_course_int_id();
788
789
        // Check params
790
        if (empty($item_id) || $item_id != strval(intval($item_id))) {
791
            return -1;
792
        }
793
794
        // Get the agenda item.
795
        $item_id = intval($item_id);
796
        $sql = "SELECT * FROM $table_agenda
797
                WHERE c_id = $courseId AND id = ".$item_id;
798
        $res = Database::query($sql);
799
800
        if (Database::num_rows($res) > 0) {
801
            $row = Database::fetch_array($res, 'ASSOC');
802
803
            // Sending announcement
804
            if (!empty($sentTo)) {
805
                $id = AnnouncementManager::add_announcement(
806
                    api_get_course_info(),
807
                    api_get_session_id(),
808
                    $row['title'],
809
                    $row['content'],
810
                    $sentTo,
811
                    null,
812
                    null,
813
                    $row['end_date']
814
                );
815
816
                AnnouncementManager::sendEmail(
817
                    api_get_course_info(),
818
                    api_get_session_id(),
819
                    $id
820
                );
821
822
                return $id;
823
            }
824
        }
825
826
        return -1;
827
    }
828
829
    /**
830
     * Edits an event.
831
     *
832
     * @param int    $id
833
     * @param string $start                 datetime format: 2012-06-14 09:00:00
834
     * @param string $end                   datetime format: 2012-06-14 09:00:00
835
     * @param int    $allDay                is all day 'true' or 'false'
836
     * @param string $title
837
     * @param string $content
838
     * @param array  $usersToSend
839
     * @param array  $attachmentArray
840
     * @param array  $attachmentCommentList
841
     * @param string $comment
842
     * @param string $color
843
     * @param bool   $addAnnouncement
844
     * @param bool   $updateContent
845
     * @param int    $authorId
846
     *
847
     * @return bool
848
     */
849
    public function editEvent(
850
        $id,
851
        $start,
852
        $end,
853
        $allDay,
854
        $title,
855
        $content,
856
        $usersToSend = [],
857
        $attachmentArray = [],
858
        $attachmentCommentList = [],
859
        $comment = null,
860
        $color = '',
861
        $addAnnouncement = false,
862
        $updateContent = true,
863
        $authorId = 0,
864
        array $inviteesList = [],
865
        bool $isCollective = false,
866
        array $remindersList = [],
867
        int $careerId = 0,
868
        int $promotionId = 0
869
    ) {
870
        $id = (int) $id;
871
        $start = api_get_utc_datetime($start);
872
        $end = api_get_utc_datetime($end);
873
        $allDay = isset($allDay) && $allDay == 'true' ? 1 : 0;
874
        $currentUserId = api_get_user_id();
875
        $authorId = empty($authorId) ? $currentUserId : (int) $authorId;
876
877
        switch ($this->type) {
878
            case 'personal':
879
                $eventInfo = $this->get_event($id);
880
                if ($eventInfo['user'] != $currentUserId
881
                    && (
882
                        api_get_configuration_value('agenda_collective_invitations')
883
                            && !self::isUserInvitedInEvent($id, $currentUserId)
884
                    )
885
                ) {
886
                    break;
887
                }
888
                $attributes = [
889
                    'title' => $title,
890
                    'date' => $start,
891
                    'enddate' => $end,
892
                    'all_day' => $allDay,
893
                ];
894
895
                if ($updateContent) {
896
                    $attributes['text'] = $content;
897
                }
898
899
                if (!empty($color)) {
900
                    $attributes['color'] = $color;
901
                }
902
903
                Database::update(
904
                    $this->tbl_personal_agenda,
905
                    $attributes,
906
                    ['id = ?' => $id]
907
                );
908
909
                if (api_get_configuration_value('agenda_collective_invitations')) {
910
                    Agenda::saveCollectiveProperties($inviteesList, $isCollective, $id);
911
                }
912
                break;
913
            case 'course':
914
                $eventInfo = $this->get_event($id);
915
916
                if (empty($eventInfo)) {
917
                    return false;
918
                }
919
920
                $groupId = api_get_group_id();
921
                $groupIid = 0;
922
                $groupInfo = [];
923
                if ($groupId) {
924
                    $groupInfo = GroupManager::get_group_properties($groupId);
925
                    if ($groupInfo) {
926
                        $groupIid = $groupInfo['iid'];
927
                    }
928
                }
929
930
                $courseId = $this->course['real_id'];
931
932
                if (empty($courseId)) {
933
                    return false;
934
                }
935
936
                if (!$this->getIsAllowedToEdit()) {
937
                    return false;
938
                }
939
940
                $attributes = [
941
                    'title' => $title,
942
                    'start_date' => $start,
943
                    'end_date' => $end,
944
                    'all_day' => $allDay,
945
                    'comment' => $comment,
946
                ];
947
948
                if ($updateContent) {
949
                    $attributes['content'] = $content;
950
                }
951
952
                if (!empty($color)) {
953
                    $attributes['color'] = $color;
954
                }
955
956
                Database::update(
957
                    $this->tbl_course_agenda,
958
                    $attributes,
959
                    [
960
                        'id = ? AND c_id = ? AND session_id = ? ' => [
961
                            $id,
962
                            $courseId,
963
                            $this->sessionId,
964
                        ],
965
                    ]
966
                );
967
968
                if (!empty($usersToSend)) {
969
                    $sendTo = $this->parseSendToArray($usersToSend);
970
971
                    $usersToDelete = array_diff(
972
                        $eventInfo['send_to']['users'],
973
                        $sendTo['users']
974
                    );
975
                    $usersToAdd = array_diff(
976
                        $sendTo['users'],
977
                        $eventInfo['send_to']['users']
978
                    );
979
980
                    $groupsToDelete = array_diff(
981
                        $eventInfo['send_to']['groups'],
982
                        $sendTo['groups']
983
                    );
984
                    $groupToAdd = array_diff(
985
                        $sendTo['groups'],
986
                        $eventInfo['send_to']['groups']
987
                    );
988
989
                    if ($sendTo['everyone']) {
990
                        // Delete all from group
991
                        if (isset($eventInfo['send_to']['groups']) &&
992
                            !empty($eventInfo['send_to']['groups'])
993
                        ) {
994
                            foreach ($eventInfo['send_to']['groups'] as $group) {
995
                                $groupIidItem = 0;
996
                                if ($group) {
997
                                    $groupInfoItem = GroupManager::get_group_properties(
998
                                        $group
999
                                    );
1000
                                    if ($groupInfoItem) {
1001
                                        $groupIidItem = $groupInfoItem['iid'];
1002
                                    }
1003
                                }
1004
1005
                                api_item_property_delete(
1006
                                    $this->course,
1007
                                    TOOL_CALENDAR_EVENT,
1008
                                    $id,
1009
                                    0,
1010
                                    $groupIidItem,
1011
                                    $this->sessionId
1012
                                );
1013
                            }
1014
                        }
1015
1016
                        // Storing the selected users.
1017
                        if (isset($eventInfo['send_to']['users']) &&
1018
                            !empty($eventInfo['send_to']['users'])
1019
                        ) {
1020
                            foreach ($eventInfo['send_to']['users'] as $userId) {
1021
                                api_item_property_delete(
1022
                                    $this->course,
1023
                                    TOOL_CALENDAR_EVENT,
1024
                                    $id,
1025
                                    $userId,
1026
                                    $groupIid,
1027
                                    $this->sessionId
1028
                                );
1029
                            }
1030
                        }
1031
1032
                        // Add to everyone only.
1033
                        api_item_property_update(
1034
                            $this->course,
1035
                            TOOL_CALENDAR_EVENT,
1036
                            $id,
1037
                            'visible',
1038
                            $authorId,
1039
                            $groupInfo,
1040
                            null,
1041
                            $start,
1042
                            $end,
1043
                            $this->sessionId
1044
                        );
1045
                    } else {
1046
                        // Delete "everyone".
1047
                        api_item_property_delete(
1048
                            $this->course,
1049
                            TOOL_CALENDAR_EVENT,
1050
                            $id,
1051
                            0,
1052
                            0,
1053
                            $this->sessionId
1054
                        );
1055
1056
                        // Add groups
1057
                        if (!empty($groupToAdd)) {
1058
                            foreach ($groupToAdd as $group) {
1059
                                $groupInfoItem = [];
1060
                                if ($group) {
1061
                                    $groupInfoItem = GroupManager::get_group_properties(
1062
                                        $group
1063
                                    );
1064
                                }
1065
1066
                                api_item_property_update(
1067
                                    $this->course,
1068
                                    TOOL_CALENDAR_EVENT,
1069
                                    $id,
1070
                                    'visible',
1071
                                    $authorId,
1072
                                    $groupInfoItem,
1073
                                    0,
1074
                                    $start,
1075
                                    $end,
1076
                                    $this->sessionId
1077
                                );
1078
                            }
1079
                        }
1080
1081
                        // Delete groups.
1082
                        if (!empty($groupsToDelete)) {
1083
                            foreach ($groupsToDelete as $group) {
1084
                                $groupIidItem = 0;
1085
                                $groupInfoItem = [];
1086
                                if ($group) {
1087
                                    $groupInfoItem = GroupManager::get_group_properties(
1088
                                        $group
1089
                                    );
1090
                                    if ($groupInfoItem) {
1091
                                        $groupIidItem = $groupInfoItem['iid'];
1092
                                    }
1093
                                }
1094
1095
                                api_item_property_delete(
1096
                                    $this->course,
1097
                                    TOOL_CALENDAR_EVENT,
1098
                                    $id,
1099
                                    0,
1100
                                    $groupIidItem,
1101
                                    $this->sessionId
1102
                                );
1103
                            }
1104
                        }
1105
1106
                        // Add users.
1107
                        if (!empty($usersToAdd)) {
1108
                            foreach ($usersToAdd as $userId) {
1109
                                api_item_property_update(
1110
                                    $this->course,
1111
                                    TOOL_CALENDAR_EVENT,
1112
                                    $id,
1113
                                    'visible',
1114
                                    $authorId,
1115
                                    $groupInfo,
1116
                                    $userId,
1117
                                    $start,
1118
                                    $end,
1119
                                    $this->sessionId
1120
                                );
1121
                            }
1122
                        }
1123
1124
                        // Delete users.
1125
                        if (!empty($usersToDelete)) {
1126
                            foreach ($usersToDelete as $userId) {
1127
                                api_item_property_delete(
1128
                                    $this->course,
1129
                                    TOOL_CALENDAR_EVENT,
1130
                                    $id,
1131
                                    $userId,
1132
                                    $groupInfo,
1133
                                    $this->sessionId
1134
                                );
1135
                            }
1136
                        }
1137
                    }
1138
                }
1139
1140
                // Add announcement.
1141
                if (isset($addAnnouncement) && !empty($addAnnouncement)) {
1142
                    $this->storeAgendaEventAsAnnouncement(
1143
                        $id,
1144
                        $usersToSend
1145
                    );
1146
                }
1147
1148
                // Add attachment.
1149
                if (isset($attachmentArray) && !empty($attachmentArray)) {
1150
                    $counter = 0;
1151
                    foreach ($attachmentArray as $attachmentItem) {
1152
                        if (empty($attachmentItems['id'])) {
1153
                            continue;
1154
                        }
1155
1156
                        $this->updateAttachment(
1157
                            $attachmentItem['id'],
1158
                            $id,
1159
                            $attachmentItem,
1160
                            $attachmentCommentList[$counter],
1161
                            $this->course
1162
                        );
1163
                        $counter++;
1164
                    }
1165
                }
1166
                break;
1167
            case 'admin':
1168
            case 'platform':
1169
                if (api_is_platform_admin()) {
1170
                    $attributes = [
1171
                        'title' => $title,
1172
                        'start_date' => $start,
1173
                        'end_date' => $end,
1174
                        'all_day' => $allDay,
1175
                    ];
1176
1177
                    if (api_get_configuration_value('allow_carrers_in_global_agenda')) {
1178
                        $attributes['career_id'] = $careerId;
1179
                        $attributes['promotion_id'] = $promotionId;
1180
                    }
1181
1182
                    if ($updateContent) {
1183
                        $attributes['content'] = $content;
1184
                    }
1185
                    Database::update(
1186
                        $this->tbl_global_agenda,
1187
                        $attributes,
1188
                        ['id = ?' => $id]
1189
                    );
1190
                }
1191
                break;
1192
        }
1193
1194
        $this->editReminders($id, $remindersList);
1195
1196
        return true;
1197
    }
1198
1199
    /**
1200
     * @param int  $id
1201
     * @param bool $deleteAllItemsFromSerie
1202
     *
1203
     * @throws \Doctrine\ORM\ORMException
1204
     * @throws \Doctrine\ORM\OptimisticLockException
1205
     */
1206
    public function deleteEvent($id, $deleteAllItemsFromSerie = false)
1207
    {
1208
        $em = Database::getManager();
1209
1210
        switch ($this->type) {
1211
            case 'personal':
1212
                $eventInfo = $this->get_event($id);
1213
                if ($eventInfo['user'] == api_get_user_id()) {
1214
                    Database::delete(
1215
                        $this->tbl_personal_agenda,
1216
                        ['id = ?' => $id]
1217
                    );
1218
                } elseif (api_get_configuration_value('agenda_collective_invitations')) {
1219
                    $currentUser = api_get_user_entity(api_get_user_id());
1220
1221
                    $eventRepo = $em->getRepository('ChamiloCoreBundle:PersonalAgenda');
1222
                    $event = $eventRepo->findOneByIdAndInvitee($id, $currentUser);
1223
                    $invitation = $event ? $event->getInvitation() : null;
1224
1225
                    if ($invitation) {
1226
                        $invitation->removeInviteeUser($currentUser);
1227
1228
                        $em->persist($invitation);
1229
                        $em->flush();
1230
                    }
1231
                }
1232
                break;
1233
            case 'course':
1234
                $courseId = api_get_course_int_id();
1235
                $isAllowToEdit = $this->getIsAllowedToEdit();
1236
1237
                if (!empty($courseId) && $isAllowToEdit) {
1238
                    $eventInfo = $this->get_event($id);
1239
                    if ($deleteAllItemsFromSerie) {
1240
                        /* This is one of the children.
1241
                           Getting siblings and delete 'Em all + the father! */
1242
                        if (isset($eventInfo['parent_event_id']) && !empty($eventInfo['parent_event_id'])) {
1243
                            // Removing items.
1244
                            $events = $this->getAllRepeatEvents($eventInfo['parent_event_id']);
1245
                            if (!empty($events)) {
1246
                                foreach ($events as $event) {
1247
                                    $this->deleteEvent($event['id']);
1248
                                }
1249
                            }
1250
                            // Removing parent.
1251
                            $this->deleteEvent($eventInfo['parent_event_id']);
1252
                        } else {
1253
                            // This is the father looking for the children.
1254
                            $events = $this->getAllRepeatEvents($id);
1255
                            if (!empty($events)) {
1256
                                foreach ($events as $event) {
1257
                                    $this->deleteEvent($event['id']);
1258
                                }
1259
                            }
1260
                        }
1261
                    }
1262
1263
                    // Removing from events.
1264
                    Database::delete(
1265
                        $this->tbl_course_agenda,
1266
                        ['id = ? AND c_id = ?' => [$id, $courseId]]
1267
                    );
1268
1269
                    api_item_property_update(
1270
                        $this->course,
1271
                        TOOL_CALENDAR_EVENT,
1272
                        $id,
1273
                        'delete',
1274
                        api_get_user_id()
1275
                    );
1276
1277
                    // Removing from series.
1278
                    Database::delete(
1279
                        $this->table_repeat,
1280
                        [
1281
                            'cal_id = ? AND c_id = ?' => [
1282
                                $id,
1283
                                $courseId,
1284
                            ],
1285
                        ]
1286
                    );
1287
1288
                    if (isset($eventInfo['attachment']) && !empty($eventInfo['attachment'])) {
1289
                        foreach ($eventInfo['attachment'] as $attachment) {
1290
                            self::deleteAttachmentFile(
1291
                                $attachment['id'],
1292
                                $this->course
1293
                            );
1294
                        }
1295
                    }
1296
                }
1297
                break;
1298
            case 'admin':
1299
                if (api_is_platform_admin()) {
1300
                    Database::delete(
1301
                        $this->tbl_global_agenda,
1302
                        ['id = ?' => $id]
1303
                    );
1304
                }
1305
                break;
1306
        }
1307
    }
1308
1309
    /**
1310
     * Get agenda events.
1311
     *
1312
     * @param int    $start
1313
     * @param int    $end
1314
     * @param int    $courseId
1315
     * @param int    $groupId
1316
     * @param int    $user_id
1317
     * @param string $format
1318
     *
1319
     * @return array|string
1320
     */
1321
    public function getEvents(
1322
        $start,
1323
        $end,
1324
        $courseId = null,
1325
        $groupId = null,
1326
        $user_id = 0,
1327
        $format = 'json'
1328
    ) {
1329
        switch ($this->type) {
1330
            case 'admin':
1331
                $this->getPlatformEvents($start, $end);
1332
                break;
1333
            case 'course':
1334
                $courseInfo = api_get_course_info_by_id($courseId);
1335
1336
                // Session coach can see all events inside a session.
1337
                if (api_is_coach()) {
1338
                    // Own course
1339
                    $this->getCourseEvents(
1340
                        $start,
1341
                        $end,
1342
                        $courseInfo,
1343
                        $groupId,
1344
                        $this->sessionId,
1345
                        $user_id
1346
                    );
1347
1348
                    // Others
1349
                    $this->getSessionEvents(
1350
                        $start,
1351
                        $end,
1352
                        $this->sessionId,
1353
                        $user_id,
1354
                        $this->eventOtherSessionColor
1355
                    );
1356
                } else {
1357
                    $this->getCourseEvents(
1358
                        $start,
1359
                        $end,
1360
                        $courseInfo,
1361
                        $groupId,
1362
                        $this->sessionId,
1363
                        $user_id
1364
                    );
1365
                }
1366
                break;
1367
            case 'personal':
1368
            default:
1369
                $sessionFilterActive = false;
1370
                if (!empty($this->sessionId)) {
1371
                    $sessionFilterActive = true;
1372
                }
1373
1374
                if ($sessionFilterActive == false) {
1375
                    // Getting personal events
1376
                    $this->getPersonalEvents($start, $end);
1377
1378
                    // Getting platform/admin events
1379
                    $this->getPlatformEvents($start, $end);
1380
                }
1381
1382
                $ignoreVisibility = api_get_configuration_value('personal_agenda_show_all_session_events');
1383
1384
                $session_list = [];
1385
                // Getting course events
1386
                $my_course_list = [];
1387
                if (!api_is_anonymous()) {
1388
                    $session_list = SessionManager::get_sessions_by_user(
1389
                        api_get_user_id(),
1390
                        $ignoreVisibility
1391
                    );
1392
                    $my_course_list = CourseManager::get_courses_list_by_user_id(
1393
                        api_get_user_id(),
1394
                        false
1395
                    );
1396
                }
1397
1398
                if (api_is_drh()) {
1399
                    if (api_drh_can_access_all_session_content()) {
1400
                        $session_list = [];
1401
                        $sessionList = SessionManager::get_sessions_followed_by_drh(
1402
                            api_get_user_id(),
1403
                            null,
1404
                            null,
1405
                            null,
1406
                            true,
1407
                            false
1408
                        );
1409
1410
                        if (!empty($sessionList)) {
1411
                            foreach ($sessionList as $sessionItem) {
1412
                                $sessionId = $sessionItem['id'];
1413
                                $courses = SessionManager::get_course_list_by_session_id($sessionId);
1414
                                $sessionInfo = [
1415
                                    'session_id' => $sessionId,
1416
                                    'courses' => $courses,
1417
                                ];
1418
                                $session_list[] = $sessionInfo;
1419
                            }
1420
                        }
1421
                    }
1422
                }
1423
1424
                if (!empty($session_list)) {
1425
                    foreach ($session_list as $session_item) {
1426
                        if ($sessionFilterActive) {
1427
                            if ($this->sessionId != $session_item['session_id']) {
1428
                                continue;
1429
                            }
1430
                        }
1431
1432
                        $my_courses = $session_item['courses'];
1433
                        $my_session_id = $session_item['session_id'];
1434
1435
                        if (!empty($my_courses)) {
1436
                            foreach ($my_courses as $course_item) {
1437
                                $courseInfo = api_get_course_info_by_id(
1438
                                    $course_item['real_id']
1439
                                );
1440
                                $this->getCourseEvents(
1441
                                    $start,
1442
                                    $end,
1443
                                    $courseInfo,
1444
                                    0,
1445
                                    $my_session_id
1446
                                );
1447
                            }
1448
                        }
1449
                    }
1450
                }
1451
1452
                if (!empty($my_course_list) && $sessionFilterActive == false) {
1453
                    foreach ($my_course_list as $courseInfoItem) {
1454
                        $courseInfo = api_get_course_info_by_id(
1455
                            $courseInfoItem['real_id']
1456
                        );
1457
                        if (isset($courseId) && !empty($courseId)) {
1458
                            if ($courseInfo['real_id'] == $courseId) {
1459
                                $this->getCourseEvents(
1460
                                    $start,
1461
                                    $end,
1462
                                    $courseInfo,
1463
                                    0,
1464
                                    0,
1465
                                    $user_id
1466
                                );
1467
                            }
1468
                        } else {
1469
                            $this->getCourseEvents(
1470
                                $start,
1471
                                $end,
1472
                                $courseInfo,
1473
                                0,
1474
                                0,
1475
                                $user_id
1476
                            );
1477
                        }
1478
                    }
1479
                }
1480
1481
                if ($start && $end) {
1482
                    $this->loadSessionsAsEvents($start, $end);
1483
                }
1484
1485
                break;
1486
        }
1487
1488
        if (api_get_configuration_value('agenda_reminders')) {
1489
            $this->events = array_map(
1490
                function (array $eventInfo) {
1491
                    $id = str_replace(['personal_', 'course_', 'session_'], '', $eventInfo['id']);
1492
1493
                    $eventInfo['reminders'] = $this->parseEventReminders(
1494
                        $this->getEventReminders(
1495
                            $id,
1496
                            'session' === $eventInfo['type'] ? 'course' : $eventInfo['type']
1497
                        )
1498
                    );
1499
1500
                    return $eventInfo;
1501
                },
1502
                $this->events
1503
            );
1504
        }
1505
1506
        $this->cleanEvents();
1507
1508
        switch ($format) {
1509
            case 'json':
1510
                if (empty($this->events)) {
1511
                    return '[]';
1512
                }
1513
1514
                return json_encode($this->events);
1515
                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...
1516
            case 'array':
1517
                if (empty($this->events)) {
1518
                    return [];
1519
                }
1520
1521
                return $this->events;
1522
                break;
1523
        }
1524
    }
1525
1526
    /**
1527
     * Clean events.
1528
     *
1529
     * @return bool
1530
     */
1531
    public function cleanEvents()
1532
    {
1533
        if (empty($this->events)) {
1534
            return false;
1535
        }
1536
1537
        foreach ($this->events as &$event) {
1538
            $event['description'] = Security::remove_XSS($event['description']);
1539
            $event['title'] = Security::remove_XSS($event['title']);
1540
        }
1541
1542
        return true;
1543
    }
1544
1545
    /**
1546
     * @param int $id
1547
     * @param int $minute_delta
1548
     *
1549
     * @return int
1550
     */
1551
    public function resizeEvent($id, $minute_delta)
1552
    {
1553
        $id = (int) $id;
1554
        $delta = (int) $minute_delta;
1555
        $event = $this->get_event($id);
1556
        if (!empty($event)) {
1557
            switch ($this->type) {
1558
                case 'personal':
1559
                    $sql = "UPDATE $this->tbl_personal_agenda SET
1560
                            enddate = DATE_ADD(enddate, INTERVAL $delta MINUTE)
1561
							WHERE id = ".$id;
1562
                    Database::query($sql);
1563
                    break;
1564
                case 'course':
1565
                    $sql = "UPDATE $this->tbl_course_agenda SET
1566
                            end_date = DATE_ADD(end_date, INTERVAL $delta MINUTE)
1567
							WHERE
1568
							    c_id = ".$this->course['real_id']." AND
1569
							    id = ".$id;
1570
                    Database::query($sql);
1571
                    break;
1572
                case 'admin':
1573
                    $sql = "UPDATE $this->tbl_global_agenda SET
1574
                            end_date = DATE_ADD(end_date, INTERVAL $delta MINUTE)
1575
							WHERE id = ".$id;
1576
                    Database::query($sql);
1577
                    break;
1578
            }
1579
        }
1580
1581
        return 1;
1582
    }
1583
1584
    /**
1585
     * @param int $id
1586
     * @param int $minute_delta minutes
1587
     * @param int $allDay
1588
     *
1589
     * @return int
1590
     */
1591
    public function move_event($id, $minute_delta, $allDay)
1592
    {
1593
        $id = (int) $id;
1594
        $event = $this->get_event($id);
1595
1596
        if (empty($event)) {
1597
            return false;
1598
        }
1599
1600
        // we convert the hour delta into minutes and add the minute delta
1601
        $delta = (int) $minute_delta;
1602
        $allDay = (int) $allDay;
1603
1604
        if (!empty($event)) {
1605
            switch ($this->type) {
1606
                case 'personal':
1607
                    $sql = "UPDATE $this->tbl_personal_agenda SET
1608
                            all_day = $allDay, date = DATE_ADD(date, INTERVAL $delta MINUTE),
1609
                            enddate = DATE_ADD(enddate, INTERVAL $delta MINUTE)
1610
							WHERE id=".$id;
1611
                    Database::query($sql);
1612
                    break;
1613
                case 'course':
1614
                    $sql = "UPDATE $this->tbl_course_agenda SET
1615
                            all_day = $allDay,
1616
                            start_date = DATE_ADD(start_date, INTERVAL $delta MINUTE),
1617
                            end_date = DATE_ADD(end_date, INTERVAL $delta MINUTE)
1618
							WHERE
1619
							    c_id = ".$this->course['real_id']." AND
1620
							    id=".$id;
1621
                    Database::query($sql);
1622
                    break;
1623
                case 'admin':
1624
                    $sql = "UPDATE $this->tbl_global_agenda SET
1625
                            all_day = $allDay,
1626
                            start_date = DATE_ADD(start_date,INTERVAL $delta MINUTE),
1627
                            end_date = DATE_ADD(end_date, INTERVAL $delta MINUTE)
1628
							WHERE id=".$id;
1629
                    Database::query($sql);
1630
                    break;
1631
            }
1632
        }
1633
1634
        return 1;
1635
    }
1636
1637
    /**
1638
     * Gets a single event.
1639
     *
1640
     * @param int $id event id
1641
     *
1642
     * @return array
1643
     */
1644
    public function get_event($id)
1645
    {
1646
        // make sure events of the personal agenda can only be seen by the user himself
1647
        $id = (int) $id;
1648
        $event = null;
1649
        $agendaCollectiveInvitations = api_get_configuration_value('agenda_collective_invitations');
1650
1651
        switch ($this->type) {
1652
            case 'personal':
1653
                $user = api_get_user_entity(api_get_user_id());
1654
                $sql = "SELECT * FROM ".$this->tbl_personal_agenda."
1655
                        WHERE id = $id AND user = ".$user->getId();
1656
                $result = Database::query($sql);
1657
                if (Database::num_rows($result)) {
1658
                    $event = Database::fetch_array($result, 'ASSOC');
1659
                    $event['description'] = $event['text'];
1660
                    $event['content'] = $event['text'];
1661
                    $event['start_date'] = $event['date'];
1662
                    $event['end_date'] = $event['enddate'];
1663
                }
1664
1665
                if (null !== $event) {
1666
                    return $event;
1667
                }
1668
1669
                if ($agendaCollectiveInvitations) {
1670
                    $eventRepo = Database::getManager()->getRepository('ChamiloCoreBundle:PersonalAgenda');
1671
                    $event = $eventRepo->findOneByIdAndInvitee($id, $user);
1672
1673
                    if ($event && $event->isCollective()) {
1674
                        return [
1675
                            'id' => $event->getId(),
1676
                            'user' => $event->getUser(),
1677
                            'title' => $event->getTitle(),
1678
                            'text' => $event->getText(),
1679
                            'date' => $event->getDate()->format('Y-m-d H:i:s'),
1680
                            'enddate' => $event->getEndDate()->format('Y-m-d H:i:s'),
1681
                            'course' => null,
1682
                            'parent_event_id' => $event->getParentEventId(),
1683
                            'all_day' => $event->getAllDay(),
1684
                            'color' => $event->getColor(),
1685
                            'agenda_event_invitation_id' => $event->getInvitation()->getId(),
1686
                            'collective' => $event->isCollective(),
1687
                            'description' => $event->getText(),
1688
                            'content' => $event->getText(),
1689
                            'start_date' => $event->getDate()->format('Y-m-d H:i:s'),
1690
                            'end_date' => $event->getEndDate()->format('Y-m-d H:i:s'),
1691
                        ];
1692
                    }
1693
                }
1694
1695
                return null;
1696
            case 'course':
1697
                if (!empty($this->course['real_id'])) {
1698
                    $sql = "SELECT * FROM ".$this->tbl_course_agenda."
1699
                            WHERE c_id = ".$this->course['real_id']." AND id = ".$id;
1700
                    $result = Database::query($sql);
1701
                    if (Database::num_rows($result)) {
1702
                        $event = Database::fetch_array($result, 'ASSOC');
1703
                        $event['description'] = $event['content'];
1704
1705
                        // Getting send to array
1706
                        $event['send_to'] = $this->getUsersAndGroupSubscribedToEvent(
1707
                            $id,
1708
                            $this->course['real_id'],
1709
                            $this->sessionId
1710
                        );
1711
1712
                        // Getting repeat info
1713
                        $event['repeat_info'] = $this->getRepeatedInfoByEvent(
1714
                            $id,
1715
                            $this->course['real_id']
1716
                        );
1717
1718
                        if (!empty($event['parent_event_id'])) {
1719
                            $event['parent_info'] = $this->get_event($event['parent_event_id']);
1720
                        }
1721
1722
                        $event['attachment'] = $this->getAttachmentList(
1723
                            $id,
1724
                            $this->course
1725
                        );
1726
                    }
1727
                }
1728
                break;
1729
            case 'admin':
1730
            case 'platform':
1731
                $sql = "SELECT * FROM ".$this->tbl_global_agenda."
1732
                        WHERE id = $id";
1733
                $result = Database::query($sql);
1734
                if (Database::num_rows($result)) {
1735
                    $event = Database::fetch_array($result, 'ASSOC');
1736
                    $event['description'] = $event['content'];
1737
                }
1738
                break;
1739
        }
1740
1741
        return $event;
1742
    }
1743
1744
    /**
1745
     * Gets personal events.
1746
     *
1747
     * @param int $start
1748
     * @param int $end
1749
     *
1750
     * @return array
1751
     */
1752
    public function getPersonalEvents($start, $end)
1753
    {
1754
        $start = (int) $start;
1755
        $end = (int) $end;
1756
        $startDate = null;
1757
        $endDate = null;
1758
        $startCondition = '';
1759
        $endCondition = '';
1760
1761
        $agendaCollectiveInvitations = api_get_configuration_value('agenda_collective_invitations');
1762
1763
        if ($start !== 0) {
1764
            $startDate = api_get_utc_datetime($start, true, true);
1765
            $startCondition = "AND date >= '".$startDate->format('Y-m-d H:i:s')."'";
1766
        }
1767
        if ($start !== 0) {
1768
            $endDate = api_get_utc_datetime($end, false, true);
1769
            $endCondition = "AND (enddate <= '".$endDate->format('Y-m-d H:i:s')."' OR enddate IS NULL)";
1770
        }
1771
        $user_id = api_get_user_id();
1772
1773
        $sql = "SELECT * FROM ".$this->tbl_personal_agenda."
1774
                WHERE user = $user_id $startCondition $endCondition";
1775
1776
        $result = Database::query($sql);
1777
        $my_events = [];
1778
        if (Database::num_rows($result)) {
1779
            while ($row = Database::fetch_array($result, 'ASSOC')) {
1780
                $event = [];
1781
                $event['id'] = 'personal_'.$row['id'];
1782
                $event['title'] = $row['title'];
1783
                $event['className'] = 'personal';
1784
                $event['borderColor'] = $event['backgroundColor'] = $this->event_personal_color;
1785
                $event['editable'] = true;
1786
                $event['sent_to'] = get_lang('Me');
1787
                $event['type'] = 'personal';
1788
1789
                if (!empty($row['date'])) {
1790
                    $event['start'] = $this->formatEventDate($row['date']);
1791
                    $event['start_date_localtime'] = api_get_local_time($row['date']);
1792
                }
1793
1794
                if (!empty($row['enddate'])) {
1795
                    $event['end'] = $this->formatEventDate($row['enddate']);
1796
                    $event['end_date_localtime'] = api_get_local_time($row['enddate']);
1797
                }
1798
1799
                $event['description'] = $row['text'];
1800
                $event['allDay'] = isset($row['all_day']) && $row['all_day'] == 1 ? $row['all_day'] : 0;
1801
                $event['parent_event_id'] = 0;
1802
                $event['has_children'] = 0;
1803
1804
                if ($agendaCollectiveInvitations) {
1805
                    $event['collective'] = (bool) $row['collective'];
1806
                    $event['invitees'] = self::getInviteesForPersonalEvent($row['id']);
1807
                }
1808
1809
                $my_events[] = $event;
1810
                $this->events[] = $event;
1811
            }
1812
        }
1813
1814
        if ($agendaCollectiveInvitations) {
1815
            $this->loadEventsAsInvitee(
1816
                api_get_user_entity($user_id),
1817
                $startDate,
1818
                $endDate
1819
            );
1820
        }
1821
1822
        // Add plugin personal events
1823
1824
        $this->plugin = new AppPlugin();
1825
        $plugins = $this->plugin->getInstalledPluginListObject();
1826
        /** @var Plugin $plugin */
1827
        foreach ($plugins as $plugin) {
1828
            if ($plugin->hasPersonalEvents && method_exists($plugin, 'getPersonalEvents')) {
1829
                $pluginEvents = $plugin->getPersonalEvents($this, $start, $end);
1830
1831
                if (!empty($pluginEvents)) {
1832
                    $this->events = array_merge($this->events, $pluginEvents);
1833
                }
1834
            }
1835
        }
1836
1837
        return $my_events;
1838
    }
1839
1840
    public static function getInviteesForPersonalEvent($eventId): array
1841
    {
1842
        $em = Database::getManager();
1843
        $event = $em->find('ChamiloCoreBundle:PersonalAgenda', $eventId);
1844
1845
        $inviteeRepo = $em->getRepository('ChamiloCoreBundle:AgendaEventInvitee');
1846
        $invitees = $inviteeRepo->findByInvitation($event->getInvitation());
1847
1848
        $inviteeList = [];
1849
1850
        foreach ($invitees as $invitee) {
1851
            $inviteeUser = $invitee->getUser();
1852
1853
            $inviteeList[] = [
1854
                'id' => $inviteeUser->getId(),
1855
                'name' => $inviteeUser->getCompleteNameWithUsername(),
1856
            ];
1857
        }
1858
1859
        return $inviteeList;
1860
    }
1861
1862
    /**
1863
     * Get user/group list per event.
1864
     *
1865
     * @param int $eventId
1866
     * @param int $courseId
1867
     * @param int $sessionId
1868
     * @paraù int $sessionId
1869
     *
1870
     * @return array
1871
     */
1872
    public function getUsersAndGroupSubscribedToEvent(
1873
        $eventId,
1874
        $courseId,
1875
        $sessionId
1876
    ) {
1877
        $eventId = (int) $eventId;
1878
        $courseId = (int) $courseId;
1879
        $sessionId = (int) $sessionId;
1880
1881
        $sessionCondition = "ip.session_id = $sessionId";
1882
        if (empty($sessionId)) {
1883
            $sessionCondition = " (ip.session_id = 0 OR ip.session_id IS NULL) ";
1884
        }
1885
1886
        $tlb_course_agenda = Database::get_course_table(TABLE_AGENDA);
1887
        $tbl_property = Database::get_course_table(TABLE_ITEM_PROPERTY);
1888
1889
        // Get sent_tos
1890
        $sql = "SELECT DISTINCT to_user_id, to_group_id
1891
                FROM $tbl_property ip
1892
                INNER JOIN $tlb_course_agenda agenda
1893
                ON (
1894
                  ip.ref = agenda.id AND
1895
                  ip.c_id = agenda.c_id AND
1896
                  ip.tool = '".TOOL_CALENDAR_EVENT."'
1897
                )
1898
                WHERE
1899
                    ref = $eventId AND
1900
                    ip.visibility = '1' AND
1901
                    ip.c_id = $courseId AND
1902
                    $sessionCondition
1903
                ";
1904
1905
        $result = Database::query($sql);
1906
        $users = [];
1907
        $groups = [];
1908
        $everyone = false;
1909
1910
        while ($row = Database::fetch_array($result, 'ASSOC')) {
1911
            if (!empty($row['to_group_id'])) {
1912
                $groups[] = $row['to_group_id'];
1913
            }
1914
            if (!empty($row['to_user_id'])) {
1915
                $users[] = $row['to_user_id'];
1916
            }
1917
1918
            if (empty($groups) && empty($users)) {
1919
                if ($row['to_group_id'] == 0) {
1920
                    $everyone = true;
1921
                }
1922
            }
1923
        }
1924
1925
        return [
1926
            'everyone' => $everyone,
1927
            'users' => $users,
1928
            'groups' => $groups,
1929
        ];
1930
    }
1931
1932
    /**
1933
     * @param int    $start
1934
     * @param int    $end
1935
     * @param int    $sessionId
1936
     * @param int    $userId
1937
     * @param string $color
1938
     *
1939
     * @return array
1940
     */
1941
    public function getSessionEvents(
1942
        $start,
1943
        $end,
1944
        $sessionId = 0,
1945
        $userId = 0,
1946
        $color = ''
1947
    ) {
1948
        $courses = SessionManager::get_course_list_by_session_id($sessionId);
1949
1950
        if (!empty($courses)) {
1951
            foreach ($courses as $course) {
1952
                $this->getCourseEvents(
1953
                    $start,
1954
                    $end,
1955
                    $course,
1956
                    0,
1957
                    $sessionId,
1958
                    0,
1959
                    $color
1960
                );
1961
            }
1962
        }
1963
    }
1964
1965
    /**
1966
     * @param int    $start
1967
     * @param int    $end
1968
     * @param array  $courseInfo
1969
     * @param int    $groupId
1970
     * @param int    $sessionId
1971
     * @param int    $user_id
1972
     * @param string $color
1973
     *
1974
     * @return array
1975
     */
1976
    public function getCourseEvents(
1977
        $start,
1978
        $end,
1979
        $courseInfo,
1980
        $groupId = 0,
1981
        $sessionId = 0,
1982
        $user_id = 0,
1983
        $color = ''
1984
    ) {
1985
        $start = isset($start) && !empty($start) ? api_get_utc_datetime(intval($start)) : null;
1986
        $end = isset($end) && !empty($end) ? api_get_utc_datetime(intval($end)) : null;
1987
1988
        if (empty($courseInfo)) {
1989
            return [];
1990
        }
1991
        $courseId = $courseInfo['real_id'];
1992
1993
        if (empty($courseId)) {
1994
            return [];
1995
        }
1996
1997
        $sessionId = (int) $sessionId;
1998
        $user_id = (int) $user_id;
1999
2000
        $groupList = GroupManager::get_group_list(
2001
            null,
2002
            $courseInfo,
2003
            null,
2004
            $sessionId
2005
        );
2006
2007
        $groupNameList = [];
2008
        if (!empty($groupList)) {
2009
            foreach ($groupList as $group) {
2010
                $groupNameList[$group['iid']] = $group['name'];
2011
            }
2012
        }
2013
2014
        if (api_is_platform_admin() || api_is_allowed_to_edit()) {
2015
            $isAllowToEdit = true;
2016
        } else {
2017
            $isAllowToEdit = CourseManager::is_course_teacher(
2018
                api_get_user_id(),
2019
                $courseInfo['code']
2020
            );
2021
        }
2022
2023
        $isAllowToEditByHrm = false;
2024
        if (!empty($sessionId)) {
2025
            $allowDhrToEdit = api_get_configuration_value('allow_agenda_edit_for_hrm');
2026
            if ($allowDhrToEdit) {
2027
                $isHrm = SessionManager::isUserSubscribedAsHRM($sessionId, api_get_user_id());
2028
                if ($isHrm) {
2029
                    $isAllowToEdit = $isAllowToEditByHrm = true;
2030
                }
2031
            }
2032
        }
2033
2034
        $groupMemberships = [];
2035
        if (!empty($groupId)) {
2036
            $groupMemberships = [$groupId];
2037
        } else {
2038
            if ($isAllowToEdit) {
2039
                if (!empty($groupList)) {
2040
                    // c_item_property.to_group_id field was migrated to use
2041
                    // c_group_info.iid
2042
                    $groupMemberships = array_column($groupList, 'iid');
2043
                }
2044
            } else {
2045
                // get only related groups from user
2046
                $groupMemberships = GroupManager::get_group_ids(
2047
                    $courseId,
2048
                    api_get_user_id()
2049
                );
2050
            }
2051
        }
2052
2053
        $tlb_course_agenda = Database::get_course_table(TABLE_AGENDA);
2054
        $tbl_property = Database::get_course_table(TABLE_ITEM_PROPERTY);
2055
2056
        $shareEventsInSessions = 1 == api_get_course_setting('agenda_share_events_in_sessions', $courseInfo);
2057
2058
        $agendaSessionCondition = str_replace(
2059
            ' AND ',
2060
            '',
2061
            api_get_session_condition($sessionId, true, $shareEventsInSessions, 'agenda.session_id')
2062
        );
2063
        $ipSessionCondition = api_get_session_condition($sessionId, true, $shareEventsInSessions, 'ip.session_id');
2064
2065
        $sessionCondition = "($agendaSessionCondition $ipSessionCondition)";
2066
2067
        if ($isAllowToEdit) {
2068
            // No group filter was asked
2069
            if (empty($groupId)) {
2070
                if (empty($user_id)) {
2071
                    // Show all events not added in group
2072
                    $userCondition = ' (ip.to_group_id IS NULL OR ip.to_group_id = 0) ';
2073
                    // admin see only his stuff
2074
                    if ($this->type === 'personal') {
2075
                        $userCondition = " (ip.to_user_id = ".api_get_user_id()." AND (ip.to_group_id IS NULL OR ip.to_group_id = 0) ) ";
2076
                        $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) ) ";
2077
                    }
2078
2079
                    if (!empty($groupMemberships)) {
2080
                        // Show events sent to selected groups
2081
                        $userCondition .= " OR (ip.to_user_id = 0 OR ip.to_user_id is NULL) AND (ip.to_group_id IN (".implode(", ", $groupMemberships).")) ";
2082
                    }
2083
                } else {
2084
                    // Show events of requested user in no group
2085
                    $userCondition = " (ip.to_user_id = $user_id AND (ip.to_group_id IS NULL OR ip.to_group_id = 0)) ";
2086
                    // Show events sent to selected groups
2087
                    if (!empty($groupMemberships)) {
2088
                        $userCondition .= " OR (ip.to_user_id = $user_id) AND (ip.to_group_id IN (".implode(", ", $groupMemberships).")) ";
2089
                    }
2090
                }
2091
            } else {
2092
                // Show only selected groups (depending of user status)
2093
                $userCondition = " (ip.to_user_id = 0 OR ip.to_user_id is NULL) AND (ip.to_group_id IN (".implode(", ", $groupMemberships).")) ";
2094
2095
                if (!empty($groupMemberships)) {
2096
                    // Show send to $user_id in selected groups
2097
                    $userCondition .= " OR (ip.to_user_id = $user_id) AND (ip.to_group_id IN (".implode(", ", $groupMemberships).")) ";
2098
                }
2099
            }
2100
        } else {
2101
            // No group filter was asked
2102
            if (empty($groupId)) {
2103
                // Show events sent to everyone and no group
2104
                $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) ';
2105
2106
                // Show events sent to selected groups
2107
                if (!empty($groupMemberships)) {
2108
                    $userCondition .= " OR (ip.to_user_id = 0 OR ip.to_user_id is NULL) AND (ip.to_group_id IN (".implode(", ", $groupMemberships)."))) ";
2109
                } else {
2110
                    $userCondition .= " ) ";
2111
                }
2112
                $userCondition .= " OR (ip.to_user_id = ".api_get_user_id()." AND (ip.to_group_id IS NULL OR ip.to_group_id = 0)) ";
2113
            } else {
2114
                if (!empty($groupMemberships)) {
2115
                    // Show send to everyone - and only selected groups
2116
                    $userCondition = " (ip.to_user_id = 0 OR ip.to_user_id is NULL) AND (ip.to_group_id IN (".implode(", ", $groupMemberships).")) ";
2117
                }
2118
            }
2119
2120
            // Show sent to only me and no group
2121
            if (!empty($groupMemberships)) {
2122
                $userCondition .= " OR (ip.to_user_id = ".api_get_user_id().") AND (ip.to_group_id IN (".implode(", ", $groupMemberships).")) ";
2123
            } else {
2124
                // Show sent to only me and selected groups
2125
            }
2126
        }
2127
2128
        if (api_is_allowed_to_edit()) {
2129
            $visibilityCondition = " (ip.visibility IN ('1', '0'))  ";
2130
        } else {
2131
            $visibilityCondition = " (ip.visibility = '1') ";
2132
        }
2133
2134
        $sql = "SELECT DISTINCT
2135
                    agenda.*,
2136
                    ip.visibility,
2137
                    ip.to_group_id,
2138
                    ip.insert_user_id,
2139
                    ip.ref,
2140
                    to_user_id
2141
                FROM $tlb_course_agenda agenda
2142
                INNER JOIN $tbl_property ip
2143
                ON (
2144
                    agenda.id = ip.ref AND
2145
                    agenda.c_id = ip.c_id AND
2146
                    ip.tool = '".TOOL_CALENDAR_EVENT."'
2147
                )
2148
                WHERE
2149
                    $sessionCondition AND
2150
                    ($userCondition) AND
2151
                    $visibilityCondition AND
2152
                    agenda.c_id = $courseId
2153
        ";
2154
        $dateCondition = '';
2155
        if (!empty($start) && !empty($end)) {
2156
            $dateCondition .= "AND (
2157
                 agenda.start_date BETWEEN '".$start."' AND '".$end."' OR
2158
                 agenda.end_date BETWEEN '".$start."' AND '".$end."' OR
2159
                 (
2160
                     agenda.start_date IS NOT NULL AND agenda.end_date IS NOT NULL AND
2161
                     YEAR(agenda.start_date) = YEAR(agenda.end_date) AND
2162
                     MONTH('$start') BETWEEN MONTH(agenda.start_date) AND MONTH(agenda.end_date)
2163
                 )
2164
            )";
2165
        }
2166
2167
        $sql .= $dateCondition;
2168
        $result = Database::query($sql);
2169
2170
        $coachCanEdit = false;
2171
        if (!empty($sessionId)) {
2172
            $coachCanEdit = api_is_coach($sessionId, $courseId) || api_is_platform_admin();
2173
        }
2174
2175
        if (Database::num_rows($result)) {
2176
            $eventsAdded = array_column($this->events, 'unique_id');
2177
            while ($row = Database::fetch_array($result, 'ASSOC')) {
2178
                $event = [];
2179
                $event['id'] = 'course_'.$row['id'];
2180
                $event['unique_id'] = $row['iid'];
2181
                // To avoid doubles
2182
                if (in_array($event['unique_id'], $eventsAdded)) {
2183
                    continue;
2184
                }
2185
2186
                $eventsAdded[] = $event['unique_id'];
2187
                $eventId = $row['ref'];
2188
                $items = $this->getUsersAndGroupSubscribedToEvent(
2189
                    $eventId,
2190
                    $courseId,
2191
                    $this->sessionId
2192
                );
2193
                $group_to_array = $items['groups'];
2194
                $user_to_array = $items['users'];
2195
                $attachmentList = $this->getAttachmentList(
2196
                    $row['id'],
2197
                    $courseInfo
2198
                );
2199
                $event['attachment'] = '';
2200
                if (!empty($attachmentList)) {
2201
                    foreach ($attachmentList as $attachment) {
2202
                        $has_attachment = Display::return_icon(
2203
                            'attachment.gif',
2204
                            get_lang('Attachment')
2205
                        );
2206
                        $user_filename = $attachment['filename'];
2207
                        $url = api_get_path(WEB_CODE_PATH).'calendar/download.php?file='.$attachment['path'].'&course_id='.$courseId.'&'.api_get_cidreq();
2208
                        $event['attachment'] .= $has_attachment.
2209
                            Display::url(
2210
                                $user_filename,
2211
                                $url
2212
                            ).'<br />';
2213
                    }
2214
                }
2215
2216
                $event['title'] = $row['title'];
2217
                $event['className'] = 'course';
2218
                $event['allDay'] = 'false';
2219
                $event['course_id'] = $courseId;
2220
                $event['borderColor'] = $event['backgroundColor'] = $this->event_course_color;
2221
2222
                $sessionInfo = [];
2223
                if (isset($row['session_id']) && !empty($row['session_id'])) {
2224
                    $sessionInfo = api_get_session_info($sessionId);
2225
                    $event['borderColor'] = $event['backgroundColor'] = $this->event_session_color;
2226
                }
2227
2228
                $event['session_name'] = isset($sessionInfo['name']) ? $sessionInfo['name'] : '';
2229
                $event['course_name'] = isset($courseInfo['title']) ? $courseInfo['title'] : '';
2230
2231
                if (isset($row['to_group_id']) && !empty($row['to_group_id'])) {
2232
                    $event['borderColor'] = $event['backgroundColor'] = $this->event_group_color;
2233
                }
2234
2235
                if (!empty($color)) {
2236
                    $event['borderColor'] = $event['backgroundColor'] = $color;
2237
                }
2238
2239
                if (isset($row['color']) && !empty($row['color'])) {
2240
                    $event['borderColor'] = $event['backgroundColor'] = $row['color'];
2241
                }
2242
2243
                $event['editable'] = false;
2244
                if ($this->getIsAllowedToEdit() && $this->type == 'course') {
2245
                    $event['editable'] = true;
2246
                    if (!empty($sessionId)) {
2247
                        if ($coachCanEdit == false) {
2248
                            $event['editable'] = false;
2249
                        }
2250
                        if ($isAllowToEditByHrm) {
2251
                            $event['editable'] = true;
2252
                        }
2253
                        if ($sessionId != $row['session_id']) {
2254
                            $event['editable'] = false;
2255
                        }
2256
                    }
2257
                    // if user is author then he can edit the item
2258
                    if (api_get_user_id() == $row['insert_user_id']) {
2259
                        $event['editable'] = true;
2260
                    }
2261
                }
2262
2263
                if (!empty($row['start_date'])) {
2264
                    $event['start'] = $this->formatEventDate($row['start_date']);
2265
                    $event['start_date_localtime'] = api_get_local_time($row['start_date']);
2266
                }
2267
                if (!empty($row['end_date'])) {
2268
                    $event['end'] = $this->formatEventDate($row['end_date']);
2269
                    $event['end_date_localtime'] = api_get_local_time($row['end_date']);
2270
                }
2271
2272
                $event['sent_to'] = '';
2273
                $event['type'] = 'course';
2274
                if ($row['session_id'] != 0) {
2275
                    $event['type'] = 'session';
2276
                }
2277
2278
                // Event Sent to a group?
2279
                if (isset($row['to_group_id']) && !empty($row['to_group_id'])) {
2280
                    $sent_to = [];
2281
                    if (!empty($group_to_array)) {
2282
                        foreach ($group_to_array as $group_item) {
2283
                            $sent_to[] = $groupNameList[$group_item];
2284
                        }
2285
                    }
2286
                    $sent_to = implode('@@', $sent_to);
2287
                    $sent_to = str_replace(
2288
                        '@@',
2289
                        '</div><div class="label_tag notice">',
2290
                        $sent_to
2291
                    );
2292
                    $event['sent_to'] = '<div class="label_tag notice">'.$sent_to.'</div>';
2293
                    $event['type'] = 'group';
2294
                }
2295
2296
                // Event sent to a user?
2297
                if (isset($row['to_user_id'])) {
2298
                    $sent_to = [];
2299
                    if (!empty($user_to_array)) {
2300
                        foreach ($user_to_array as $item) {
2301
                            $user_info = api_get_user_info($item);
2302
                            // Add username as tooltip for $event['sent_to'] - ref #4226
2303
                            $username = api_htmlentities(
2304
                                sprintf(
2305
                                    get_lang('LoginX'),
2306
                                    $user_info['username']
2307
                                ),
2308
                                ENT_QUOTES
2309
                            );
2310
                            $sent_to[] = "<span title='".$username."'>".$user_info['complete_name']."</span>";
2311
                        }
2312
                    }
2313
                    $sent_to = implode('@@', $sent_to);
2314
                    $sent_to = str_replace(
2315
                        '@@',
2316
                        '</div><div class="label_tag notice">',
2317
                        $sent_to
2318
                    );
2319
                    $event['sent_to'] = '<div class="label_tag notice">'.$sent_to.'</div>';
2320
                }
2321
2322
                //Event sent to everyone!
2323
                if (empty($event['sent_to'])) {
2324
                    $event['sent_to'] = '<div class="label_tag notice">'.get_lang('Everyone').'</div>';
2325
                }
2326
2327
                $event['description'] = Security::remove_XSS($row['content']);
2328
                $event['visibility'] = $row['visibility'];
2329
                $event['real_id'] = $row['id'];
2330
                $event['allDay'] = isset($row['all_day']) && $row['all_day'] == 1 ? $row['all_day'] : 0;
2331
                $event['parent_event_id'] = $row['parent_event_id'];
2332
                $event['has_children'] = $this->hasChildren($row['id'], $courseId) ? 1 : 0;
2333
                $event['comment'] = Security::remove_XSS($row['comment']);
2334
                $this->events[] = $event;
2335
            }
2336
        }
2337
2338
        return $this->events;
2339
    }
2340
2341
    /**
2342
     * @param int $start tms
2343
     * @param int $end   tms
2344
     *
2345
     * @return array
2346
     */
2347
    public function getPlatformEvents($start, $end)
2348
    {
2349
        $start = isset($start) && !empty($start) ? api_get_utc_datetime(intval($start)) : null;
2350
        $end = isset($end) && !empty($end) ? api_get_utc_datetime(intval($end)) : null;
2351
        $dateCondition = '';
2352
2353
        if (!empty($start) && !empty($end)) {
2354
            $dateCondition .= "AND (
2355
                 start_date BETWEEN '".$start."' AND '".$end."' OR
2356
                 end_date BETWEEN '".$start."' AND '".$end."' OR
2357
                 (
2358
                     start_date IS NOT NULL AND end_date IS NOT NULL AND
2359
                     YEAR(start_date) = YEAR(end_date) AND
2360
                     MONTH('$start') BETWEEN MONTH(start_date) AND MONTH(end_date)
2361
                 )
2362
            )";
2363
        }
2364
2365
        $access_url_id = api_get_current_access_url_id();
2366
2367
        $sql = "SELECT *
2368
                FROM ".$this->tbl_global_agenda."
2369
                WHERE access_url_id = $access_url_id
2370
                $dateCondition";
2371
        $result = Database::query($sql);
2372
        $my_events = [];
2373
        if (Database::num_rows($result)) {
2374
            while ($row = Database::fetch_array($result, 'ASSOC')) {
2375
                $event = [];
2376
                $event['id'] = 'platform_'.$row['id'];
2377
                $event['title'] = $row['title'];
2378
                $event['className'] = 'platform';
2379
                $event['allDay'] = 'false';
2380
                $event['borderColor'] = $event['backgroundColor'] = $this->event_platform_color;
2381
                $event['editable'] = false;
2382
                $event['type'] = 'admin';
2383
2384
                if (api_is_platform_admin() && $this->type === 'admin') {
2385
                    $event['editable'] = true;
2386
                }
2387
2388
                if (!empty($row['start_date'])) {
2389
                    $event['start'] = $this->formatEventDate($row['start_date']);
2390
                    $event['start_date_localtime'] = api_get_local_time($row['start_date']);
2391
                }
2392
2393
                if (!empty($row['end_date'])) {
2394
                    $event['end'] = $this->formatEventDate($row['end_date']);
2395
                    $event['end_date_localtime'] = api_get_local_time($row['end_date']);
2396
                }
2397
                $event['allDay'] = isset($row['all_day']) && $row['all_day'] == 1 ? $row['all_day'] : 0;
2398
                $event['parent_event_id'] = 0;
2399
                $event['has_children'] = 0;
2400
                $event['description'] = $row['content'];
2401
2402
                if (api_get_configuration_value('allow_carrers_in_global_agenda')) {
2403
                    $event['career'] = null;
2404
                    $event['promotion'] = null;
2405
2406
                    if (!empty($row['career_id'])) {
2407
                        $careerInfo = (new Career())->get($row['career_id']);
2408
2409
                        unset($careerInfo['status'], $careerInfo['created_at'], $careerInfo['updated_at']);
2410
2411
                        $event['career'] = $careerInfo;
2412
                    }
2413
2414
                    if (!empty($row['promotion_id'])) {
2415
                        $promotionInfo = (new Promotion())->get($row['promotion_id']);
2416
2417
                        unset(
2418
                            $promotionInfo['career_id'],
2419
                            $promotionInfo['status'],
2420
                            $promotionInfo['created_at'],
2421
                            $promotionInfo['updated_at']
2422
                        );
2423
2424
                        $event['promotion'] = $promotionInfo;
2425
                    }
2426
                }
2427
2428
                $my_events[] = $event;
2429
                $this->events[] = $event;
2430
            }
2431
        }
2432
2433
        return $my_events;
2434
    }
2435
2436
    /**
2437
     * @param FormValidator $form
2438
     * @param array         $groupList
2439
     * @param array         $userList
2440
     * @param array         $sendTo               array('users' => [1, 2], 'groups' => [3, 4])
2441
     * @param array         $attributes
2442
     * @param bool          $addOnlyItemsInSendTo
2443
     * @param bool          $required
2444
     */
2445
    public function setSendToSelect(
2446
        $form,
2447
        $groupList = [],
2448
        $userList = [],
2449
        $sendTo = [],
2450
        $attributes = [],
2451
        $addOnlyItemsInSendTo = false,
2452
        $required = false
2453
    ) {
2454
        $params = [
2455
            'id' => 'users_to_send_id',
2456
            'data-placeholder' => get_lang('Select'),
2457
            'multiple' => 'multiple',
2458
            'class' => 'multiple-select',
2459
        ];
2460
2461
        if (!empty($attributes)) {
2462
            $params = array_merge($params, $attributes);
2463
            if (empty($params['multiple'])) {
2464
                unset($params['multiple']);
2465
            }
2466
        }
2467
2468
        $sendToGroups = isset($sendTo['groups']) ? $sendTo['groups'] : [];
2469
        $sendToUsers = isset($sendTo['users']) ? $sendTo['users'] : [];
2470
2471
        /** @var HTML_QuickForm_select $select */
2472
        $select = $form->addSelect(
2473
            'users_to_send',
2474
            get_lang('To'),
2475
            null,
2476
            $params
2477
        );
2478
2479
        if ($required) {
2480
            $form->setRequired($select);
2481
        }
2482
2483
        $selectedEveryoneOptions = [];
2484
        if (isset($sendTo['everyone']) && $sendTo['everyone']) {
2485
            $selectedEveryoneOptions = ['selected'];
2486
            $sendToUsers = [];
2487
        }
2488
2489
        $select->addOption(
2490
            get_lang('Everyone'),
2491
            'everyone',
2492
            $selectedEveryoneOptions
2493
        );
2494
2495
        $options = [];
2496
        if (is_array($groupList)) {
2497
            foreach ($groupList as $group) {
2498
                $count_users = isset($group['count_users']) ? $group['count_users'] : $group['userNb'];
2499
                $count_users = " &ndash; $count_users ".get_lang('Users');
2500
                $option = [
2501
                    'text' => $group['name'].$count_users,
2502
                    'value' => "GROUP:".$group['id'],
2503
                ];
2504
                $selected = in_array(
2505
                    $group['id'],
2506
                    $sendToGroups
2507
                ) ? true : false;
2508
                if ($selected) {
2509
                    $option['selected'] = 'selected';
2510
                }
2511
2512
                if ($addOnlyItemsInSendTo) {
2513
                    if ($selected) {
2514
                        $options[] = $option;
2515
                    }
2516
                } else {
2517
                    $options[] = $option;
2518
                }
2519
            }
2520
            $select->addOptGroup($options, get_lang('Groups'));
2521
        }
2522
2523
        // adding the individual users to the select form
2524
        if (is_array($userList)) {
2525
            $options = [];
2526
            foreach ($userList as $user) {
2527
                if ($user['status'] == ANONYMOUS) {
2528
                    continue;
2529
                }
2530
                $option = [
2531
                    'text' => api_get_person_name(
2532
                            $user['firstname'],
2533
                            $user['lastname']
2534
                        ).' ('.$user['username'].')',
2535
                    'value' => "USER:".$user['user_id'],
2536
                ];
2537
2538
                $selected = in_array(
2539
                    $user['user_id'],
2540
                    $sendToUsers
2541
                ) ? true : false;
2542
2543
                if ($selected) {
2544
                    $option['selected'] = 'selected';
2545
                }
2546
2547
                if ($addOnlyItemsInSendTo) {
2548
                    if ($selected) {
2549
                        $options[] = $option;
2550
                    }
2551
                } else {
2552
                    $options[] = $option;
2553
                }
2554
            }
2555
2556
            $select->addOptGroup($options, get_lang('Users'));
2557
        }
2558
    }
2559
2560
    /**
2561
     * Separates the users and groups array
2562
     * users have a value USER:XXX (with XXX the user id
2563
     * groups have a value GROUP:YYY (with YYY the group id)
2564
     * use the 'everyone' key.
2565
     *
2566
     * @author Julio Montoya based in separate_users_groups in agenda.inc.php
2567
     *
2568
     * @param array $to
2569
     *
2570
     * @return array
2571
     */
2572
    public function parseSendToArray($to)
2573
    {
2574
        $groupList = [];
2575
        $userList = [];
2576
        $sendTo = null;
2577
2578
        $sendTo['everyone'] = false;
2579
        if (is_array($to) && count($to) > 0) {
2580
            foreach ($to as $item) {
2581
                if ($item == 'everyone') {
2582
                    $sendTo['everyone'] = true;
2583
                } else {
2584
                    list($type, $id) = explode(':', $item);
2585
                    switch ($type) {
2586
                        case 'GROUP':
2587
                            $groupList[] = $id;
2588
                            break;
2589
                        case 'USER':
2590
                            $userList[] = $id;
2591
                            break;
2592
                    }
2593
                }
2594
            }
2595
            $sendTo['groups'] = $groupList;
2596
            $sendTo['users'] = $userList;
2597
        }
2598
2599
        return $sendTo;
2600
    }
2601
2602
    /**
2603
     * @param int    $eventId
2604
     * @param string $type
2605
     *
2606
     * @return array<int, AgendaReminder>
2607
     */
2608
    public function getEventReminders($eventId, $type = null): array
2609
    {
2610
        $em = Database::getManager();
2611
        $remindersRepo = $em->getRepository('ChamiloCoreBundle:AgendaReminder');
2612
2613
        return $remindersRepo->findBy(
2614
            [
2615
                'eventId' => $eventId,
2616
                'type' => $type ?: $this->type,
2617
            ]
2618
        );
2619
    }
2620
2621
    public function parseEventReminders(array $eventReminders): array
2622
    {
2623
        return array_map(
2624
            function (AgendaReminder $reminder) {
2625
                $interval = $reminder->getDateInterval();
2626
2627
                $reminderInfo = [
2628
                    'id' => $reminder->getId(),
2629
                    'type' => $reminder->getType(),
2630
                    'sent' => $reminder->isSent(),
2631
                    'date_interval' => [$interval->format('%a'), 'd'],
2632
                ];
2633
2634
                if ($interval->i) {
2635
                    $reminderInfo['date_interval'] = [$interval->i, 'i'];
2636
                } elseif ($interval->h) {
2637
                    $reminderInfo['date_interval'] = [$interval->h, 'h'];
2638
                } elseif ($interval->d) {
2639
                    $reminderInfo['date_interval'] = [$interval->d, 'd'];
2640
                }
2641
2642
                return $reminderInfo;
2643
            },
2644
            $eventReminders
2645
        );
2646
    }
2647
2648
    /**
2649
     * @param array $params
2650
     *
2651
     * @return FormValidator
2652
     */
2653
    public function getForm($params = [])
2654
    {
2655
        $action = isset($params['action']) ? Security::remove_XSS($params['action']) : null;
2656
        $id = isset($params['id']) ? (int) $params['id'] : 0;
2657
2658
        $url = api_get_self().'?action='.$action.'&id='.$id.'&type='.$this->type;
2659
        if ($this->type == 'course') {
2660
            $url = api_get_self().'?'.api_get_cidreq().'&action='.$action.'&id='.$id.'&type='.$this->type;
2661
        }
2662
2663
        $form = new FormValidator(
2664
            'add_event',
2665
            'post',
2666
            $url,
2667
            null,
2668
            ['enctype' => 'multipart/form-data']
2669
        );
2670
2671
        $idAttach = isset($params['id_attach']) ? (int) $params['id_attach'] : null;
2672
        $groupId = api_get_group_id();
2673
        $form_Title = get_lang('AddCalendarItem');
2674
        if (!empty($id)) {
2675
            $form_Title = get_lang('ModifyCalendarItem');
2676
        }
2677
2678
        $form->addHeader($form_Title);
2679
        $form->addElement('hidden', 'id', $id);
2680
        $form->addElement('hidden', 'action', $action);
2681
        $form->addElement('hidden', 'id_attach', $idAttach);
2682
2683
        $isSubEventEdition = false;
2684
        $isParentFromSerie = false;
2685
        $showAttachmentForm = true;
2686
2687
        if ($this->type == 'course') {
2688
            // Edition mode.
2689
            if (!empty($id)) {
2690
                $showAttachmentForm = false;
2691
                if (isset($params['parent_event_id']) && !empty($params['parent_event_id'])) {
2692
                    $isSubEventEdition = true;
2693
                }
2694
                if (!empty($params['repeat_info'])) {
2695
                    $isParentFromSerie = true;
2696
                }
2697
            }
2698
        }
2699
2700
        if ($isSubEventEdition) {
2701
            $form->addElement(
2702
                'label',
2703
                null,
2704
                Display::return_message(
2705
                    get_lang('EditingThisEventWillRemoveItFromTheSerie'),
2706
                    'warning'
2707
                )
2708
            );
2709
        }
2710
2711
        $form->addElement('text', 'title', get_lang('ItemTitle'));
2712
2713
        if (isset($groupId) && !empty($groupId)) {
2714
            $form->addElement(
2715
                'hidden',
2716
                'users_to_send[]',
2717
                "GROUP:$groupId"
2718
            );
2719
            $form->addElement('hidden', 'to', 'true');
2720
        } else {
2721
            $sendTo = isset($params['send_to']) ? $params['send_to'] : ['everyone' => true];
2722
            if ($this->type == 'course') {
2723
                $this->showToForm($form, $sendTo, [], false, true);
2724
            }
2725
        }
2726
2727
        $form->addDateRangePicker(
2728
            'date_range',
2729
            get_lang('DateRange'),
2730
            false,
2731
            ['id' => 'date_range']
2732
        );
2733
        $form->addElement('checkbox', 'all_day', null, get_lang('AllDay'));
2734
2735
        if ($this->type == 'course') {
2736
            $repeat = $form->addElement(
2737
                'checkbox',
2738
                'repeat',
2739
                null,
2740
                get_lang('RepeatEvent'),
2741
                ['onclick' => 'return plus_repeated_event();']
2742
            );
2743
            $form->addElement(
2744
                'html',
2745
                '<div id="options2" style="display:none">'
2746
            );
2747
            $form->addElement(
2748
                'select',
2749
                'repeat_type',
2750
                get_lang('RepeatType'),
2751
                self::getRepeatTypes()
2752
            );
2753
            $form->addElement(
2754
                'date_picker',
2755
                'repeat_end_day',
2756
                get_lang('RepeatEnd'),
2757
                ['id' => 'repeat_end_date_form']
2758
            );
2759
2760
            if ($isSubEventEdition || $isParentFromSerie) {
2761
                $repeatInfo = $params['repeat_info'];
2762
                if ($isSubEventEdition) {
2763
                    $parentEvent = $params['parent_info'];
2764
                    $repeatInfo = $parentEvent['repeat_info'];
2765
                }
2766
                $params['repeat'] = 1;
2767
                $params['repeat_type'] = $repeatInfo['cal_type'];
2768
                $params['repeat_end_day'] = substr(
2769
                    api_get_local_time($repeatInfo['cal_end']),
2770
                    0,
2771
                    10
2772
                );
2773
2774
                $form->freeze(['repeat_type', 'repeat_end_day']);
2775
                $repeat->_attributes['disabled'] = 'disabled';
2776
            }
2777
            $form->addElement('html', '</div>');
2778
        }
2779
2780
        if (!empty($id)) {
2781
            if (empty($params['end_date'])) {
2782
                $params['date_range'] = $params['end_date'];
2783
            }
2784
2785
            $params['date_range'] =
2786
                substr(api_get_local_time($params['start_date']), 0, 16).' / '.
2787
                substr(api_get_local_time($params['end_date']), 0, 16);
2788
        }
2789
2790
        $toolbar = 'Agenda';
2791
        if (!api_is_allowed_to_edit(null, true)) {
2792
            $toolbar = 'AgendaStudent';
2793
        }
2794
2795
        $form->addElement(
2796
            'html_editor',
2797
            'content',
2798
            get_lang('Description'),
2799
            null,
2800
            [
2801
                'ToolbarSet' => $toolbar,
2802
                'Width' => '100%',
2803
                'Height' => '200',
2804
            ]
2805
        );
2806
2807
        if ($this->type == 'course') {
2808
            $form->addElement('textarea', 'comment', get_lang('Comment'));
2809
            $form->addLabel(
2810
                get_lang('FilesAttachment'),
2811
                '<div id="filepaths" class="file-upload-event">
2812
2813
                        <div id="filepath_1">
2814
                            <input type="file" name="attach_1"/>
2815
2816
                            <label>'.get_lang('Description').'</label>
2817
                            <input class="form-control" type="text" name="legend[]" />
2818
                        </div>
2819
2820
                    </div>'
2821
            );
2822
2823
            $form->addLabel(
2824
                '',
2825
                '<span id="link-more-attach">
2826
                    <a href="javascript://" onclick="return add_image_form()">'.
2827
                get_lang('AddOneMoreFile').'</a>
2828
                 </span>&nbsp;('.sprintf(
2829
                    get_lang('MaximunFileSizeX'),
2830
                    format_file_size(
2831
                        api_get_setting('message_max_upload_filesize')
2832
                    )
2833
                ).')'
2834
            );
2835
2836
            if (isset($params['attachment']) && !empty($params['attachment'])) {
2837
                $attachmentList = $params['attachment'];
2838
                foreach ($attachmentList as $attachment) {
2839
                    $params['file_comment'] = $attachment['comment'];
2840
                    if (!empty($attachment['path'])) {
2841
                        $form->addElement(
2842
                            'checkbox',
2843
                            'delete_attachment['.$attachment['id'].']',
2844
                            null,
2845
                            get_lang(
2846
                                'DeleteAttachment'
2847
                            ).': '.$attachment['filename']
2848
                        );
2849
                    }
2850
                }
2851
            }
2852
2853
            $form->addElement(
2854
                'textarea',
2855
                'file_comment',
2856
                get_lang('FileComment')
2857
            );
2858
        }
2859
2860
        if (empty($id) && 'course' === $this->type) {
2861
            $form->addElement(
2862
                'checkbox',
2863
                'add_announcement',
2864
                null,
2865
                get_lang('AddAnnouncement').'&nbsp('.get_lang('SendMail').')'
2866
            );
2867
        }
2868
2869
        $agendaCollectiveInvitations = api_get_configuration_value('agenda_collective_invitations');
2870
2871
        if ($agendaCollectiveInvitations && 'personal' === $this->type) {
2872
            $em = Database::getManager();
2873
2874
            $invitees = [];
2875
            $isCollective = false;
2876
2877
            if ($id) {
2878
                $event = $em->find('ChamiloCoreBundle:PersonalAgenda', $id);
2879
                $eventInvitation = $event->getInvitation();
2880
2881
                if ($eventInvitation) {
2882
                    foreach ($eventInvitation->getInvitees() as $invitee) {
2883
                        $inviteeUser = $invitee->getUser();
2884
2885
                        $invitees[$inviteeUser->getId()] = $inviteeUser->getCompleteNameWithUsername();
2886
                    }
2887
                }
2888
2889
                $isCollective = $event->isCollective();
2890
            }
2891
2892
            $form->addSelectAjax(
2893
                'invitees',
2894
                get_lang('Invitees'),
2895
                $invitees,
2896
                [
2897
                    'multiple' => 'multiple',
2898
                    'url' => api_get_path(WEB_AJAX_PATH).'message.ajax.php?a=find_users',
2899
                ]
2900
            );
2901
            $form->addCheckBox('collective', '', get_lang('IsItEditableByTheInvitees'));
2902
2903
            $params['invitees'] = array_keys($invitees);
2904
            $params['collective'] = $isCollective;
2905
        }
2906
2907
        if (api_get_configuration_value('agenda_reminders')) {
2908
            $form->addHtml('<hr><div id="notification_list">');
2909
2910
            if ($id) {
2911
                $this->addFieldsForRemindersToForm($id, $form);
2912
            }
2913
2914
            $form->addHtml('</div>');
2915
            $form->addButton('add_notification', get_lang('AddNotification'), 'bell-o')->setType('button');
2916
            $form->addHtml('<hr>');
2917
        }
2918
2919
        if (api_get_configuration_value('allow_carrers_in_global_agenda') && 'admin' === $this->type) {
2920
            Career::addCareerFieldsToForm($form);
2921
            $form->addHtml('<hr>');
2922
        }
2923
2924
        if ($id) {
2925
            $form->addButtonUpdate(get_lang('ModifyEvent'));
2926
        } else {
2927
            $form->addButtonSave(get_lang('AgendaAdd'));
2928
        }
2929
2930
        $form->setDefaults($params);
2931
        $form->addRule(
2932
            'date_range',
2933
            get_lang('ThisFieldIsRequired'),
2934
            'required'
2935
        );
2936
        $form->addRule('title', get_lang('ThisFieldIsRequired'), 'required');
2937
2938
        return $form;
2939
    }
2940
2941
    public function addFieldsForRemindersToForm(int $eventId, FormValidator $form)
2942
    {
2943
        $remindersList = $this->parseEventReminders(
2944
            $this->getEventReminders($eventId)
2945
        );
2946
2947
        foreach ($remindersList as $reminderInfo) {
2948
            $form->addHtml('<div class="form-group">');
2949
            $form
2950
                ->addNumeric('notification_count[]', '', ['step' => 1, 'min' => 0])
2951
                ->setValue($reminderInfo['date_interval'][0])
2952
            ;
2953
            $form
2954
                ->addSelect(
2955
                'notification_period[]',
2956
                '',
2957
                    [
2958
                        'i' => get_lang('Minutes'),
2959
                        'h' => get_lang('Hours'),
2960
                        'd' => get_lang('Days'),
2961
                    ]
2962
                )
2963
                ->setValue($reminderInfo['date_interval'][1])
2964
            ;
2965
            $form->addHtml('<div class="col-sm-2"><p class="form-control-static">'.get_lang('Before').'</p></div>');
2966
            $form->addHtml(
2967
                '<div class="text-right col-sm-2">'
2968
                .'<button class="btn btn-default delete-notification" type="button" aria-label="'.get_lang('Delete').'"><em class="fa fa-times"></em></button>'
2969
                .'</div>'
2970
            );
2971
            $form->addHtml('</div>');
2972
        }
2973
2974
        $renderer = $form->defaultRenderer();
2975
        $renderer->setElementTemplate(
2976
            '<div class="col-sm-offset-2 col-sm-3">{element}</div>',
2977
            'notification_count[]'
2978
        );
2979
        $renderer->setElementTemplate(
2980
            '<div class="col-sm-3">{element}</div>',
2981
            'notification_period[]'
2982
        );
2983
    }
2984
2985
    /**
2986
     * @param FormValidator $form
2987
     * @param array         $sendTo               array('everyone' => false, 'users' => [1, 2], 'groups' => [3, 4])
2988
     * @param array         $attributes
2989
     * @param bool          $addOnlyItemsInSendTo
2990
     * @param bool          $required
2991
     *
2992
     * @return bool
2993
     */
2994
    public function showToForm(
2995
        $form,
2996
        $sendTo = [],
2997
        $attributes = [],
2998
        $addOnlyItemsInSendTo = false,
2999
        $required = false
3000
    ) {
3001
        if ($this->type != 'course') {
3002
            return false;
3003
        }
3004
3005
        $order = 'lastname';
3006
        if (api_is_western_name_order()) {
3007
            $order = 'firstname';
3008
        }
3009
3010
        $userList = CourseManager::get_user_list_from_course_code(
3011
            api_get_course_id(),
3012
            $this->sessionId,
3013
            null,
3014
            $order
3015
        );
3016
3017
        $groupList = CourseManager::get_group_list_of_course(
3018
            api_get_course_id(),
3019
            $this->sessionId
3020
        );
3021
3022
        $this->setSendToSelect(
3023
            $form,
3024
            $groupList,
3025
            $userList,
3026
            $sendTo,
3027
            $attributes,
3028
            $addOnlyItemsInSendTo,
3029
            $required
3030
        );
3031
3032
        return true;
3033
    }
3034
3035
    /**
3036
     * @param int   $id
3037
     * @param int   $visibility 0= invisible, 1 visible
3038
     * @param array $courseInfo
3039
     * @param int   $userId
3040
     */
3041
    public static function changeVisibility(
3042
        $id,
3043
        $visibility,
3044
        $courseInfo,
3045
        $userId = null
3046
    ) {
3047
        $id = intval($id);
3048
        if (empty($userId)) {
3049
            $userId = api_get_user_id();
3050
        } else {
3051
            $userId = intval($userId);
3052
        }
3053
3054
        if ($visibility == 0) {
3055
            api_item_property_update(
3056
                $courseInfo,
3057
                TOOL_CALENDAR_EVENT,
3058
                $id,
3059
                'invisible',
3060
                $userId
3061
            );
3062
        } else {
3063
            api_item_property_update(
3064
                $courseInfo,
3065
                TOOL_CALENDAR_EVENT,
3066
                $id,
3067
                'visible',
3068
                $userId
3069
            );
3070
        }
3071
    }
3072
3073
    /**
3074
     * Get repeat types.
3075
     *
3076
     * @return array
3077
     */
3078
    public static function getRepeatTypes()
3079
    {
3080
        return [
3081
            'daily' => get_lang('RepeatDaily'),
3082
            'weekly' => get_lang('RepeatWeekly'),
3083
            'monthlyByDate' => get_lang('RepeatMonthlyByDate'),
3084
            //monthlyByDay"> get_lang('RepeatMonthlyByDay');
3085
            //monthlyByDayR' => get_lang('RepeatMonthlyByDayR'),
3086
            'yearly' => get_lang('RepeatYearly'),
3087
        ];
3088
    }
3089
3090
    /**
3091
     * Show a list with all the attachments according to the post's id.
3092
     *
3093
     * @param int   $eventId
3094
     * @param array $courseInfo
3095
     *
3096
     * @return array with the post info
3097
     */
3098
    public function getAttachmentList($eventId, $courseInfo)
3099
    {
3100
        $tableAttachment = Database::get_course_table(TABLE_AGENDA_ATTACHMENT);
3101
        $courseId = (int) $courseInfo['real_id'];
3102
        $eventId = (int) $eventId;
3103
3104
        $sql = "SELECT id, path, filename, comment
3105
                FROM $tableAttachment
3106
                WHERE
3107
                    c_id = $courseId AND
3108
                    agenda_id = $eventId";
3109
        $result = Database::query($sql);
3110
        $list = [];
3111
        if (Database::num_rows($result) != 0) {
3112
            $list = Database::store_result($result, 'ASSOC');
3113
        }
3114
3115
        return $list;
3116
    }
3117
3118
    /**
3119
     * Show a list with all the attachments according to the post's id.
3120
     *
3121
     * @param int   $attachmentId
3122
     * @param int   $eventId
3123
     * @param array $courseInfo
3124
     *
3125
     * @return array with the post info
3126
     */
3127
    public function getAttachment($attachmentId, $eventId, $courseInfo)
3128
    {
3129
        if (empty($courseInfo) || empty($attachmentId) || empty($eventId)) {
3130
            return [];
3131
        }
3132
3133
        $tableAttachment = Database::get_course_table(TABLE_AGENDA_ATTACHMENT);
3134
        $courseId = (int) $courseInfo['real_id'];
3135
        $eventId = (int) $eventId;
3136
        $attachmentId = (int) $attachmentId;
3137
3138
        $row = [];
3139
        $sql = "SELECT id, path, filename, comment
3140
                FROM $tableAttachment
3141
                WHERE
3142
                    c_id = $courseId AND
3143
                    agenda_id = $eventId AND
3144
                    id = $attachmentId
3145
                ";
3146
        $result = Database::query($sql);
3147
        if (Database::num_rows($result) != 0) {
3148
            $row = Database::fetch_array($result, 'ASSOC');
3149
        }
3150
3151
        return $row;
3152
    }
3153
3154
    /**
3155
     * Add an attachment file into agenda.
3156
     *
3157
     * @param int    $eventId
3158
     * @param array  $fileUserUpload ($_FILES['user_upload'])
3159
     * @param string $comment        about file
3160
     * @param array  $courseInfo
3161
     *
3162
     * @return string
3163
     */
3164
    public function addAttachment(
3165
        $eventId,
3166
        $fileUserUpload,
3167
        $comment,
3168
        $courseInfo
3169
    ) {
3170
        $agenda_table_attachment = Database::get_course_table(TABLE_AGENDA_ATTACHMENT);
3171
        $eventId = (int) $eventId;
3172
3173
        // Storing the attachments
3174
        $upload_ok = false;
3175
        if (!empty($fileUserUpload['name'])) {
3176
            $upload_ok = process_uploaded_file($fileUserUpload);
3177
        }
3178
3179
        if (!empty($upload_ok)) {
3180
            $courseDir = $courseInfo['directory'].'/upload/calendar';
3181
            $sys_course_path = api_get_path(SYS_COURSE_PATH);
3182
            $uploadDir = $sys_course_path.$courseDir;
3183
3184
            // Try to add an extension to the file if it hasn't one
3185
            $new_file_name = add_ext_on_mime(
3186
                stripslashes($fileUserUpload['name']),
3187
                $fileUserUpload['type']
3188
            );
3189
3190
            // user's file name
3191
            $file_name = $fileUserUpload['name'];
3192
3193
            if (!filter_extension($new_file_name)) {
3194
                return Display::return_message(
3195
                    get_lang('UplUnableToSaveFileFilteredExtension'),
3196
                    'error'
3197
                );
3198
            } else {
3199
                $new_file_name = uniqid('');
3200
                $new_path = $uploadDir.'/'.$new_file_name;
3201
                $result = @move_uploaded_file(
3202
                    $fileUserUpload['tmp_name'],
3203
                    $new_path
3204
                );
3205
                $courseId = api_get_course_int_id();
3206
                $size = intval($fileUserUpload['size']);
3207
                // Storing the attachments if any
3208
                if ($result) {
3209
                    $params = [
3210
                        'c_id' => $courseId,
3211
                        'filename' => $file_name,
3212
                        'comment' => $comment,
3213
                        'path' => $new_file_name,
3214
                        'agenda_id' => $eventId,
3215
                        'size' => $size,
3216
                    ];
3217
                    $id = Database::insert($agenda_table_attachment, $params);
3218
                    if ($id) {
3219
                        $sql = "UPDATE $agenda_table_attachment
3220
                                SET id = iid WHERE iid = $id";
3221
                        Database::query($sql);
3222
3223
                        api_item_property_update(
3224
                            $courseInfo,
3225
                            'calendar_event_attachment',
3226
                            $id,
3227
                            'AgendaAttachmentAdded',
3228
                            api_get_user_id()
3229
                        );
3230
                    }
3231
                }
3232
            }
3233
        }
3234
    }
3235
3236
    /**
3237
     * @param int    $attachmentId
3238
     * @param int    $eventId
3239
     * @param array  $fileUserUpload
3240
     * @param string $comment
3241
     * @param array  $courseInfo
3242
     */
3243
    public function updateAttachment(
3244
        $attachmentId,
3245
        $eventId,
3246
        $fileUserUpload,
3247
        $comment,
3248
        $courseInfo
3249
    ) {
3250
        $attachment = $this->getAttachment(
3251
            $attachmentId,
3252
            $eventId,
3253
            $courseInfo
3254
        );
3255
        if (!empty($attachment)) {
3256
            $this->deleteAttachmentFile($attachmentId, $courseInfo);
3257
        }
3258
        $this->addAttachment($eventId, $fileUserUpload, $comment, $courseInfo);
3259
    }
3260
3261
    /**
3262
     * This function delete a attachment file by id.
3263
     *
3264
     * @param int   $attachmentId
3265
     * @param array $courseInfo
3266
     *
3267
     * @return string
3268
     */
3269
    public function deleteAttachmentFile($attachmentId, $courseInfo)
3270
    {
3271
        $table = Database::get_course_table(TABLE_AGENDA_ATTACHMENT);
3272
        $attachmentId = (int) $attachmentId;
3273
        $courseId = $courseInfo['real_id'];
3274
3275
        if (empty($courseId) || empty($attachmentId)) {
3276
            return false;
3277
        }
3278
3279
        $sql = "DELETE FROM $table
3280
                WHERE c_id = $courseId AND id = ".$attachmentId;
3281
        $result = Database::query($sql);
3282
3283
        // update item_property
3284
        api_item_property_update(
3285
            $courseInfo,
3286
            'calendar_event_attachment',
3287
            $attachmentId,
3288
            'AgendaAttachmentDeleted',
3289
            api_get_user_id()
3290
        );
3291
3292
        if (!empty($result)) {
3293
            return Display::return_message(
3294
                get_lang("AttachmentFileDeleteSuccess"),
3295
                'confirmation'
3296
            );
3297
        }
3298
    }
3299
3300
    /**
3301
     * @param int $eventId
3302
     *
3303
     * @return array
3304
     */
3305
    public function getAllRepeatEvents($eventId)
3306
    {
3307
        $events = [];
3308
        $eventId = (int) $eventId;
3309
3310
        switch ($this->type) {
3311
            case 'personal':
3312
                break;
3313
            case 'course':
3314
                if (!empty($this->course['real_id'])) {
3315
                    $sql = "SELECT * FROM ".$this->tbl_course_agenda."
3316
                            WHERE
3317
                                c_id = ".$this->course['real_id']." AND
3318
                                parent_event_id = ".$eventId;
3319
                    $result = Database::query($sql);
3320
                    if (Database::num_rows($result)) {
3321
                        while ($row = Database::fetch_array($result, 'ASSOC')) {
3322
                            $events[] = $row;
3323
                        }
3324
                    }
3325
                }
3326
                break;
3327
        }
3328
3329
        return $events;
3330
    }
3331
3332
    /**
3333
     * @param int $eventId
3334
     * @param int $courseId
3335
     *
3336
     * @return bool
3337
     */
3338
    public function hasChildren($eventId, $courseId)
3339
    {
3340
        $eventId = (int) $eventId;
3341
        $courseId = (int) $courseId;
3342
3343
        $sql = "SELECT count(DISTINCT(id)) as count
3344
                FROM ".$this->tbl_course_agenda."
3345
                WHERE
3346
                    c_id = $courseId AND
3347
                    parent_event_id = $eventId";
3348
        $result = Database::query($sql);
3349
        if (Database::num_rows($result)) {
3350
            $row = Database::fetch_array($result, 'ASSOC');
3351
3352
            return $row['count'] > 0;
3353
        }
3354
3355
        return false;
3356
    }
3357
3358
    /**
3359
     * @param int    $filter
3360
     * @param string $view
3361
     *
3362
     * @return string
3363
     */
3364
    public function displayActions($view, $filter = 0)
3365
    {
3366
        $groupInfo = GroupManager::get_group_properties(api_get_group_id());
3367
        $groupIid = isset($groupInfo['iid']) ? $groupInfo['iid'] : 0;
3368
3369
        $codePath = api_get_path(WEB_CODE_PATH);
3370
3371
        $currentUserId = api_get_user_id();
3372
        $cidReq = api_get_cidreq();
3373
3374
        $actionsLeft = '';
3375
        $actionsLeft .= Display::url(
3376
            Display::return_icon('calendar.png', get_lang('Calendar'), [], ICON_SIZE_MEDIUM),
3377
            $codePath."calendar/agenda_js.php?type={$this->type}&$cidReq"
3378
        );
3379
        $actionsLeft .= Display::url(
3380
            Display::return_icon('week.png', get_lang('AgendaList'), [], ICON_SIZE_MEDIUM),
3381
            $codePath."calendar/agenda_list.php?type={$this->type}&$cidReq"
3382
        );
3383
3384
        $form = '';
3385
        if (api_is_allowed_to_edit(false, true) ||
3386
            ('personal' === $this->type && !api_is_anonymous() && 'true' === api_get_setting('allow_personal_agenda')) ||
3387
            (
3388
                '1' === api_get_course_setting('allow_user_edit_agenda') && !api_is_anonymous() &&
3389
                api_is_allowed_to_session_edit(false, true))
3390
            || (
3391
                GroupManager::user_has_access($currentUserId, $groupIid, GroupManager::GROUP_TOOL_CALENDAR)
3392
                && GroupManager::is_tutor_of_group($currentUserId, $groupInfo)
3393
            )
3394
        ) {
3395
            $actionsLeft .= Display::url(
3396
                Display::return_icon('new_event.png', get_lang('AgendaAdd'), [], ICON_SIZE_MEDIUM),
3397
                $codePath."calendar/agenda.php?action=add&type={$this->type}&$cidReq"
3398
            );
3399
3400
            $actionsLeft .= Display::url(
3401
                Display::return_icon('import_calendar.png', get_lang('ICalFileImport'), [], ICON_SIZE_MEDIUM),
3402
                $codePath."calendar/agenda.php?action=importical&type={$this->type}&$cidReq"
3403
            );
3404
3405
            if ($this->type === 'course') {
3406
                if (!isset($_GET['action'])) {
3407
                    $form = new FormValidator(
3408
                        'form-search',
3409
                        'post',
3410
                        '',
3411
                        '',
3412
                        [],
3413
                        FormValidator::LAYOUT_INLINE
3414
                    );
3415
                    $attributes = [
3416
                        'multiple' => false,
3417
                        'id' => 'select_form_id_search',
3418
                    ];
3419
                    $selectedValues = $this->parseAgendaFilter($filter);
3420
                    $this->showToForm($form, $selectedValues, $attributes);
3421
                    $form = $form->returnForm();
3422
                }
3423
            }
3424
        }
3425
3426
        if ($this->type === 'personal' && !api_is_anonymous()) {
3427
            $actionsLeft .= Display::url(
3428
                Display::return_icon('1day.png', get_lang('SessionsPlanCalendar'), [], ICON_SIZE_MEDIUM),
3429
                $codePath.'calendar/planification.php'
3430
            );
3431
3432
            if (api_is_student_boss() || api_is_platform_admin()) {
3433
                $actionsLeft .= Display::url(
3434
                    Display::return_icon('calendar-user.png', get_lang('MyStudentsSchedule'), [], ICON_SIZE_MEDIUM),
3435
                    $codePath.'mySpace/calendar_plan.php'
3436
                );
3437
            }
3438
        }
3439
3440
        if (api_is_platform_admin() ||
3441
            api_is_teacher() ||
3442
            api_is_student_boss() ||
3443
            api_is_drh() ||
3444
            api_is_session_admin() ||
3445
            api_is_coach()
3446
        ) {
3447
            if ($this->type == 'personal') {
3448
                $form = null;
3449
                if (!isset($_GET['action'])) {
3450
                    $form = new FormValidator(
3451
                        'form-search',
3452
                        'get',
3453
                        api_get_self().'?type=personal&',
3454
                        '',
3455
                        [],
3456
                        FormValidator::LAYOUT_INLINE
3457
                    );
3458
3459
                    $sessions = [];
3460
3461
                    if (api_is_drh()) {
3462
                        $sessionList = SessionManager::get_sessions_followed_by_drh($currentUserId);
3463
                        if (!empty($sessionList)) {
3464
                            foreach ($sessionList as $sessionItem) {
3465
                                $sessions[$sessionItem['id']] = strip_tags($sessionItem['name']);
3466
                            }
3467
                        }
3468
                    } else {
3469
                        $sessions = SessionManager::get_sessions_by_user($currentUserId);
3470
                        $sessions = array_column($sessions, 'session_name', 'session_id');
3471
                    }
3472
3473
                    $form->addHidden('type', 'personal');
3474
                    $sessions = ['0' => get_lang('SelectAnOption')] + $sessions;
3475
3476
                    $form->addSelect(
3477
                        'session_id',
3478
                        get_lang('Session'),
3479
                        $sessions,
3480
                        ['id' => 'session_id', 'onchange' => 'submit();']
3481
                    );
3482
3483
                    $form->addButton('reset', get_lang('Reset'), 'eraser');
3484
                    $form = $form->returnForm();
3485
                }
3486
            }
3487
        }
3488
3489
        $actionsRight = '';
3490
        if ($view == 'calendar') {
3491
            $actionsRight .= $form;
3492
        }
3493
3494
        $toolbar = Display::toolbarAction(
3495
            'toolbar-agenda',
3496
            [$actionsLeft, $actionsRight]
3497
        );
3498
3499
        return $toolbar;
3500
    }
3501
3502
    /**
3503
     * @return FormValidator
3504
     */
3505
    public function getImportCalendarForm()
3506
    {
3507
        $form = new FormValidator(
3508
            'frm_import_ical',
3509
            'post',
3510
            api_get_self().'?action=importical&type='.$this->type,
3511
            ['enctype' => 'multipart/form-data']
3512
        );
3513
        $form->addHeader(get_lang('ICalFileImport'));
3514
        $form->addElement('file', 'ical_import', get_lang('ICalFileImport'));
3515
        $form->addRule(
3516
            'ical_import',
3517
            get_lang('ThisFieldIsRequired'),
3518
            'required'
3519
        );
3520
        $form->addButtonImport(get_lang('Import'), 'ical_submit');
3521
3522
        return $form;
3523
    }
3524
3525
    /**
3526
     * @param array $courseInfo
3527
     * @param $file
3528
     *
3529
     * @return false|string
3530
     */
3531
    public function importEventFile($courseInfo, $file)
3532
    {
3533
        $charset = api_get_system_encoding();
3534
        $filepath = api_get_path(SYS_ARCHIVE_PATH).$file['name'];
3535
        $messages = [];
3536
3537
        if (!@move_uploaded_file($file['tmp_name'], $filepath)) {
3538
            error_log(
3539
                'Problem moving uploaded file: '.$file['error'].' in '.__FILE__.' line '.__LINE__
3540
            );
3541
3542
            return false;
3543
        }
3544
3545
        $data = file_get_contents($filepath);
3546
3547
        $trans = [
3548
            'DAILY' => 'daily',
3549
            'WEEKLY' => 'weekly',
3550
            'MONTHLY' => 'monthlyByDate',
3551
            'YEARLY' => 'yearly',
3552
        ];
3553
        $sentTo = ['everyone' => true];
3554
        $calendar = Sabre\VObject\Reader::read($data);
3555
        $currentTimeZone = api_get_timezone();
3556
        if (!empty($calendar->VEVENT)) {
3557
            /** @var Sabre\VObject\Component\VEvent $event */
3558
            foreach ($calendar->VEVENT as $event) {
3559
                $tempDate = $event->DTSTART->getValue();
3560
                if ('Z' == substr($tempDate, -1) && 'UTC' != date('e', strtotime($tempDate))) {
3561
                    $event->DTSTART->setValue(gmdate('Ymd\THis\Z', strtotime($tempDate)));
3562
                }
3563
                $tempDate = $event->DTEND->getValue();
3564
                if ('Z' == substr($tempDate, -1) && 'UTC' != date('e', strtotime($tempDate))) {
3565
                    $event->DTEND->setValue(gmdate('Ymd\THis\Z', strtotime($tempDate)));
3566
                }
3567
                $start = $event->DTSTART->getDateTime();
3568
                $end = $event->DTEND->getDateTime();
3569
                //Sabre\VObject\DateTimeParser::parseDateTime(string $dt, \Sabre\VObject\DateTimeZone $tz)
3570
3571
                $startDateTime = api_get_local_time(
3572
                    $start->format('Y-m-d H:i:s'),
3573
                    $currentTimeZone,
3574
                    $start->format('e')
3575
                );
3576
                $endDateTime = api_get_local_time(
3577
                    $end->format('Y-m-d H:i'),
3578
                    $currentTimeZone,
3579
                    $end->format('e')
3580
                );
3581
                $title = api_convert_encoding(
3582
                    (string) $event->summary,
3583
                    $charset,
3584
                    'UTF-8'
3585
                );
3586
                $description = api_convert_encoding(
3587
                    (string) $event->description,
3588
                    $charset,
3589
                    'UTF-8'
3590
                );
3591
3592
                $id = $this->addEvent(
3593
                    $startDateTime,
3594
                    $endDateTime,
3595
                    'false',
3596
                    $title,
3597
                    $description,
3598
                    $sentTo
3599
                );
3600
3601
                $messages[] = " $title - ".$startDateTime." - ".$endDateTime;
3602
3603
                //$attendee = (string)$event->attendee;
3604
                /** @var Sabre\VObject\Property\ICalendar\Recur $repeat */
3605
                $repeat = $event->RRULE;
3606
                if ($id && !empty($repeat)) {
3607
                    $repeat = $repeat->getParts();
3608
                    $freq = $trans[$repeat['FREQ']];
3609
3610
                    if (isset($repeat['UNTIL']) && !empty($repeat['UNTIL'])) {
3611
                        // Check if datetime or just date (strlen == 8)
3612
                        if (strlen($repeat['UNTIL']) == 8) {
3613
                            // Fix the datetime format to avoid exception in the next step
3614
                            $repeat['UNTIL'] .= 'T000000';
3615
                        }
3616
                        $until = Sabre\VObject\DateTimeParser::parseDateTime(
3617
                            $repeat['UNTIL'],
3618
                            new DateTimeZone($currentTimeZone)
3619
                        );
3620
                        $until = $until->format('Y-m-d H:i:s');
3621
                        $this->addRepeatedItem(
3622
                            $id,
3623
                            $freq,
3624
                            $until,
3625
                            $sentTo
3626
                        );
3627
                    }
3628
3629
                    if (!empty($repeat['COUNT'])) {
3630
                        /*$count = $repeat['COUNT'];
3631
                        $interval = $repeat['INTERVAL'];
3632
                        $endDate = null;
3633
                        switch($freq) {
3634
                            case 'daily':
3635
                                $start = api_strtotime($startDateTime);
3636
                                $date = new DateTime($startDateTime);
3637
                                $days = $count * $interval;
3638
                                var_dump($days);
3639
                                $date->add(new DateInterval("P".$days."D"));
3640
                                $endDate = $date->format('Y-m-d H:i');
3641
                                //$endDate = $count *
3642
                                for ($i = 0; $i < $count; $i++) {
3643
                                    $days = 86400 * 7
3644
                                }
3645
                            }
3646
                        }*/
3647
                        //$res = agenda_add_repeat_item($courseInfo, $id, $freq, $count, $attendee);
3648
                        /*$this->addRepeatedItem(
3649
                            $id,
3650
                            $freq,
3651
                            $endDate,
3652
                            $sentTo
3653
                        );*/
3654
                    }
3655
                }
3656
            }
3657
        }
3658
3659
        if (!empty($messages)) {
3660
            $messages = implode('<br /> ', $messages);
3661
        } else {
3662
            $messages = get_lang('NoAgendaItems');
3663
        }
3664
3665
        return $messages;
3666
    }
3667
3668
    /**
3669
     * Parse filter turns USER:12 to ['users' => [12])] or G:1 ['groups' => [1]].
3670
     *
3671
     * @param int $filter
3672
     *
3673
     * @return array
3674
     */
3675
    public function parseAgendaFilter($filter)
3676
    {
3677
        $everyone = false;
3678
        $groupId = null;
3679
        $userId = null;
3680
3681
        if ($filter == 'everyone') {
3682
            $everyone = true;
3683
        } else {
3684
            if (substr($filter, 0, 1) == 'G') {
3685
                $groupId = str_replace('GROUP:', '', $filter);
3686
            } else {
3687
                $userId = str_replace('USER:', '', $filter);
3688
            }
3689
        }
3690
        if (empty($userId) && empty($groupId)) {
3691
            $everyone = true;
3692
        }
3693
3694
        return [
3695
            'everyone' => $everyone,
3696
            'users' => [$userId],
3697
            'groups' => [$groupId],
3698
        ];
3699
    }
3700
3701
    /**
3702
     *    This function retrieves all the agenda items of all the courses the user is subscribed to.
3703
     */
3704
    public static function get_myagendaitems(
3705
        $user_id,
3706
        $courses_dbs,
3707
        $month,
3708
        $year
3709
    ) {
3710
        $user_id = intval($user_id);
3711
3712
        $items = [];
3713
        $my_list = [];
3714
3715
        // get agenda-items for every course
3716
        foreach ($courses_dbs as $key => $array_course_info) {
3717
            //databases of the courses
3718
            $TABLEAGENDA = Database::get_course_table(TABLE_AGENDA);
3719
            $TABLE_ITEMPROPERTY = Database::get_course_table(
3720
                TABLE_ITEM_PROPERTY
3721
            );
3722
3723
            $group_memberships = GroupManager::get_group_ids(
3724
                $array_course_info['real_id'],
3725
                $user_id
3726
            );
3727
            $course_user_status = CourseManager::getUserInCourseStatus(
3728
                $user_id,
3729
                $array_course_info['real_id']
3730
            );
3731
            // if the user is administrator of that course we show all the agenda items
3732
            if ($course_user_status == '1') {
3733
                //echo "course admin";
3734
                $sqlquery = "SELECT DISTINCT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref
3735
							FROM ".$TABLEAGENDA." agenda,
3736
								 ".$TABLE_ITEMPROPERTY." ip
3737
							WHERE agenda.id = ip.ref
3738
							AND MONTH(agenda.start_date)='".$month."'
3739
							AND YEAR(agenda.start_date)='".$year."'
3740
							AND ip.tool='".TOOL_CALENDAR_EVENT."'
3741
							AND ip.visibility='1'
3742
							GROUP BY agenda.id
3743
							ORDER BY start_date ";
3744
            } else {
3745
                // if the user is not an administrator of that course
3746
                if (is_array($group_memberships) && count(
3747
                        $group_memberships
3748
                    ) > 0
3749
                ) {
3750
                    $sqlquery = "SELECT	agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref
3751
								FROM ".$TABLEAGENDA." agenda,
3752
									".$TABLE_ITEMPROPERTY." ip
3753
								WHERE agenda.id = ip.ref
3754
								AND MONTH(agenda.start_date)='".$month."'
3755
								AND YEAR(agenda.start_date)='".$year."'
3756
								AND ip.tool='".TOOL_CALENDAR_EVENT."'
3757
								AND	( ip.to_user_id='".$user_id."' OR (ip.to_group_id IS NULL OR ip.to_group_id IN (0, ".implode(
3758
                            ", ",
3759
                            $group_memberships
3760
                        ).")) )
3761
								AND ip.visibility='1'
3762
								ORDER BY start_date ";
3763
                } else {
3764
                    $sqlquery = "SELECT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref
3765
								FROM ".$TABLEAGENDA." agenda,
3766
									".$TABLE_ITEMPROPERTY." ip
3767
								WHERE agenda.id = ip.ref
3768
								AND MONTH(agenda.start_date)='".$month."'
3769
								AND YEAR(agenda.start_date)='".$year."'
3770
								AND ip.tool='".TOOL_CALENDAR_EVENT."'
3771
								AND ( ip.to_user_id='".$user_id."' OR ip.to_group_id='0' OR ip.to_group_id IS NULL)
3772
								AND ip.visibility='1'
3773
								ORDER BY start_date ";
3774
                }
3775
            }
3776
            $result = Database::query($sqlquery);
3777
3778
            while ($item = Database::fetch_array($result, 'ASSOC')) {
3779
                $agendaday = -1;
3780
                if (!empty($item['start_date'])) {
3781
                    $item['start_date'] = api_get_local_time(
3782
                        $item['start_date']
3783
                    );
3784
                    $item['start_date_tms'] = api_strtotime(
3785
                        $item['start_date']
3786
                    );
3787
                    $agendaday = date("j", $item['start_date_tms']);
3788
                }
3789
                if (!empty($item['end_date'])) {
3790
                    $item['end_date'] = api_get_local_time($item['end_date']);
3791
                }
3792
3793
                $url = api_get_path(
3794
                        WEB_CODE_PATH
3795
                    )."calendar/agenda.php?cidReq=".urlencode(
3796
                        $array_course_info["code"]
3797
                    )."&day=$agendaday&month=$month&year=$year#$agendaday";
3798
3799
                $item['url'] = $url;
3800
                $item['course_name'] = $array_course_info['title'];
3801
                $item['calendar_type'] = 'course';
3802
                $item['course_id'] = $array_course_info['course_id'];
3803
3804
                $my_list[$agendaday][] = $item;
3805
            }
3806
        }
3807
3808
        // sorting by hour for every day
3809
        $agendaitems = [];
3810
        foreach ($items as $agendaday => $tmpitems) {
3811
            if (!isset($agendaitems[$agendaday])) {
3812
                $agendaitems[$agendaday] = '';
3813
            }
3814
            sort($tmpitems);
3815
            foreach ($tmpitems as $val) {
3816
                $agendaitems[$agendaday] .= $val;
3817
            }
3818
        }
3819
3820
        return $my_list;
3821
    }
3822
3823
    /**
3824
     * This function retrieves one personal agenda item returns it.
3825
     *
3826
     * @param    array    The array containing existing events. We add to this array.
3827
     * @param    int        Day
3828
     * @param    int        Month
3829
     * @param    int        Year (4 digits)
3830
     * @param    int        Week number
3831
     * @param    string    Type of view (month_view, week_view, day_view)
3832
     *
3833
     * @return array The results of the database query, or null if not found
3834
     */
3835
    public static function get_global_agenda_items(
3836
        $agendaitems,
3837
        $day,
3838
        $month,
3839
        $year,
3840
        $week,
3841
        $type
3842
    ) {
3843
        $tbl_global_agenda = Database::get_main_table(
3844
            TABLE_MAIN_SYSTEM_CALENDAR
3845
        );
3846
        $month = intval($month);
3847
        $year = intval($year);
3848
        $week = intval($week);
3849
        $day = intval($day);
3850
        // 1. creating the SQL statement for getting the personal agenda items in MONTH view
3851
3852
        $current_access_url_id = api_get_current_access_url_id();
3853
3854
        if ($type == "month_view" || $type == "") {
3855
            // We are in month view
3856
            $sql = "SELECT * FROM ".$tbl_global_agenda."
3857
                    WHERE
3858
                        MONTH(start_date) = ".$month." AND
3859
                        YEAR(start_date) = ".$year."  AND
3860
                        access_url_id = $current_access_url_id
3861
                    ORDER BY start_date ASC";
3862
        }
3863
        // 2. creating the SQL statement for getting the personal agenda items in WEEK view
3864
        if ($type == "week_view") { // we are in week view
3865
            $start_end_day_of_week = self::calculate_start_end_of_week(
3866
                $week,
3867
                $year
3868
            );
3869
            $start_day = $start_end_day_of_week['start']['day'];
3870
            $start_month = $start_end_day_of_week['start']['month'];
3871
            $start_year = $start_end_day_of_week['start']['year'];
3872
            $end_day = $start_end_day_of_week['end']['day'];
3873
            $end_month = $start_end_day_of_week['end']['month'];
3874
            $end_year = $start_end_day_of_week['end']['year'];
3875
            // in sql statements you have to use year-month-day for date calculations
3876
            $start_filter = $start_year."-".$start_month."-".$start_day." 00:00:00";
3877
            $start_filter = api_get_utc_datetime($start_filter);
3878
3879
            $end_filter = $end_year."-".$end_month."-".$end_day." 23:59:59";
3880
            $end_filter = api_get_utc_datetime($end_filter);
3881
            $sql = " SELECT * FROM ".$tbl_global_agenda." WHERE start_date>='".$start_filter."' AND start_date<='".$end_filter."' AND  access_url_id = $current_access_url_id ";
3882
        }
3883
        // 3. creating the SQL statement for getting the personal agenda items in DAY view
3884
        if ($type == "day_view") { // we are in day view
3885
            // we could use mysql date() function but this is only available from 4.1 and higher
3886
            $start_filter = $year."-".$month."-".$day." 00:00:00";
3887
            $start_filter = api_get_utc_datetime($start_filter);
3888
3889
            $end_filter = $year."-".$month."-".$day." 23:59:59";
3890
            $end_filter = api_get_utc_datetime($end_filter);
3891
            $sql = " SELECT * FROM ".$tbl_global_agenda." WHERE start_date>='".$start_filter."' AND start_date<='".$end_filter."'  AND  access_url_id = $current_access_url_id";
3892
        }
3893
3894
        $result = Database::query($sql);
3895
3896
        while ($item = Database::fetch_array($result)) {
3897
            if (!empty($item['start_date'])) {
3898
                $item['start_date'] = api_get_local_time($item['start_date']);
3899
                $item['start_date_tms'] = api_strtotime($item['start_date']);
3900
            }
3901
            if (!empty($item['end_date'])) {
3902
                $item['end_date'] = api_get_local_time($item['end_date']);
3903
            }
3904
3905
            // we break the date field in the database into a date and a time part
3906
            $agenda_db_date = explode(" ", $item['start_date']);
3907
            $date = $agenda_db_date[0];
3908
            $time = $agenda_db_date[1];
3909
            // we divide the date part into a day, a month and a year
3910
            $agendadate = explode("-", $date);
3911
            $year = intval($agendadate[0]);
3912
            $month = intval($agendadate[1]);
3913
            $day = intval($agendadate[2]);
3914
            // we divide the time part into hour, minutes, seconds
3915
            $agendatime = explode(":", $time);
3916
            $hour = $agendatime[0];
3917
            $minute = $agendatime[1];
3918
            $second = $agendatime[2];
3919
3920
            if ($type == 'month_view') {
3921
                $item['calendar_type'] = 'global';
3922
                $agendaitems[$day][] = $item;
3923
                continue;
3924
            }
3925
3926
            $start_time = api_format_date(
3927
                $item['start_date'],
3928
                TIME_NO_SEC_FORMAT
3929
            );
3930
            $end_time = '';
3931
            if (!empty($item['end_date'])) {
3932
                $end_time = ' - '.api_format_date(
3933
                        $item['end_date'],
3934
                        DATE_TIME_FORMAT_LONG
3935
                    );
3936
            }
3937
3938
            // if the student has specified a course we a add a link to that course
3939
            if ($item['course'] != "") {
3940
                $url = api_get_path(
3941
                        WEB_CODE_PATH
3942
                    )."admin/agenda.php?cidReq=".urlencode(
3943
                        $item['course']
3944
                    )."&day=$day&month=$month&year=$year#$day"; // RH  //Patrick Cool: to highlight the relevant agenda item
3945
                $course_link = "<a href=\"$url\" title=\"".$item['course']."\">".$item['course']."</a>";
3946
            } else {
3947
                $course_link = "";
3948
            }
3949
            // Creating the array that will be returned. If we have week or month view we have an array with the date as the key
3950
            // if we have a day_view we use a half hour as index => key 33 = 16h30
3951
            if ($type !== "day_view") {
3952
                // This is the array construction for the WEEK or MONTH view
3953
                //Display the Agenda global in the tab agenda (administrator)
3954
                $agendaitems[$day] .= "<i>$start_time $end_time</i>&nbsp;-&nbsp;";
3955
                $agendaitems[$day] .= "<b>".get_lang('GlobalEvent')."</b>";
3956
                $agendaitems[$day] .= "<div>".$item['title']."</div><br>";
3957
            } else {
3958
                // this is the array construction for the DAY view
3959
                $halfhour = 2 * $agendatime['0'];
3960
                if ($agendatime['1'] >= '30') {
3961
                    $halfhour = $halfhour + 1;
3962
                }
3963
                if (!is_array($agendaitems[$halfhour])) {
3964
                    $content = $agendaitems[$halfhour];
3965
                }
3966
                $agendaitems[$halfhour] = $content."<div><i>$hour:$minute</i> <b>".get_lang(
3967
                        'GlobalEvent'
3968
                    ).":  </b>".$item['title']."</div>";
3969
            }
3970
        }
3971
3972
        return $agendaitems;
3973
    }
3974
3975
    /**
3976
     * This function retrieves all the personal agenda items and add them to the agenda items found by the other
3977
     * functions.
3978
     */
3979
    public static function get_personal_agenda_items(
3980
        $user_id,
3981
        $agendaitems,
3982
        $day,
3983
        $month,
3984
        $year,
3985
        $week,
3986
        $type
3987
    ) {
3988
        $tbl_personal_agenda = Database::get_main_table(TABLE_PERSONAL_AGENDA);
3989
        $user_id = intval($user_id);
3990
3991
        // 1. creating the SQL statement for getting the personal agenda items in MONTH view
3992
        if ($type === "month_view" || $type === "") {
3993
            // we are in month view
3994
            $sql = "SELECT * FROM $tbl_personal_agenda
3995
                    WHERE
3996
                        user='".$user_id."' AND
3997
                        MONTH(date)='".$month."' AND
3998
                        YEAR(date) = '".$year."'
3999
                     ORDER BY date ASC";
4000
        }
4001
4002
        // 2. creating the SQL statement for getting the personal agenda items in WEEK view
4003
        // we are in week view
4004
        if ($type == "week_view") {
4005
            $start_end_day_of_week = self::calculate_start_end_of_week(
4006
                $week,
4007
                $year
4008
            );
4009
            $start_day = $start_end_day_of_week['start']['day'];
4010
            $start_month = $start_end_day_of_week['start']['month'];
4011
            $start_year = $start_end_day_of_week['start']['year'];
4012
            $end_day = $start_end_day_of_week['end']['day'];
4013
            $end_month = $start_end_day_of_week['end']['month'];
4014
            $end_year = $start_end_day_of_week['end']['year'];
4015
            // in sql statements you have to use year-month-day for date calculations
4016
            $start_filter = $start_year."-".$start_month."-".$start_day." 00:00:00";
4017
            $start_filter = api_get_utc_datetime($start_filter);
4018
            $end_filter = $end_year."-".$end_month."-".$end_day." 23:59:59";
4019
            $end_filter = api_get_utc_datetime($end_filter);
4020
            $sql = " SELECT * FROM ".$tbl_personal_agenda." WHERE user='".$user_id."' AND date>='".$start_filter."' AND date<='".$end_filter."'";
4021
        }
4022
        // 3. creating the SQL statement for getting the personal agenda items in DAY view
4023
        if ($type == "day_view") {
4024
            // we are in day view
4025
            // we could use mysql date() function but this is only available from 4.1 and higher
4026
            $start_filter = $year."-".$month."-".$day." 00:00:00";
4027
            $start_filter = api_get_utc_datetime($start_filter);
4028
            $end_filter = $year."-".$month."-".$day." 23:59:59";
4029
            $end_filter = api_get_utc_datetime($end_filter);
4030
            $sql = " SELECT * FROM ".$tbl_personal_agenda." WHERE user='".$user_id."' AND date>='".$start_filter."' AND date<='".$end_filter."'";
4031
        }
4032
4033
        $result = Database::query($sql);
4034
        while ($item = Database::fetch_array($result, 'ASSOC')) {
4035
            $time_minute = api_convert_and_format_date(
4036
                $item['date'],
4037
                TIME_NO_SEC_FORMAT
4038
            );
4039
            $item['date'] = api_get_local_time($item['date']);
4040
            $item['start_date_tms'] = api_strtotime($item['date']);
4041
            $item['content'] = $item['text'];
4042
4043
            // we break the date field in the database into a date and a time part
4044
            $agenda_db_date = explode(" ", $item['date']);
4045
            $date = $agenda_db_date[0];
4046
            $time = $agenda_db_date[1];
4047
            // we divide the date part into a day, a month and a year
4048
            $agendadate = explode("-", $item['date']);
4049
            $year = intval($agendadate[0]);
4050
            $month = intval($agendadate[1]);
4051
            $day = intval($agendadate[2]);
4052
            // we divide the time part into hour, minutes, seconds
4053
            $agendatime = explode(":", $time);
4054
4055
            $hour = $agendatime[0];
4056
            $minute = $agendatime[1];
4057
            $second = $agendatime[2];
4058
4059
            if ($type == 'month_view') {
4060
                $item['calendar_type'] = 'personal';
4061
                $item['start_date'] = $item['date'];
4062
                $agendaitems[$day][] = $item;
4063
                continue;
4064
            }
4065
4066
            // if the student has specified a course we a add a link to that course
4067
            if ($item['course'] != "") {
4068
                $url = api_get_path(
4069
                        WEB_CODE_PATH
4070
                    )."calendar/agenda.php?cidReq=".urlencode(
4071
                        $item['course']
4072
                    )."&day=$day&month=$month&year=$year#$day"; // RH  //Patrick Cool: to highlight the relevant agenda item
4073
                $course_link = "<a href=\"$url\" title=\"".$item['course']."\">".$item['course']."</a>";
4074
            } else {
4075
                $course_link = "";
4076
            }
4077
            // Creating the array that will be returned. If we have week or month view we have an array with the date as the key
4078
            // if we have a day_view we use a half hour as index => key 33 = 16h30
4079
            if ($type !== "day_view") {
4080
                // This is the array construction for the WEEK or MONTH view
4081
4082
                //Display events in agenda
4083
                $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 />";
4084
            } else {
4085
                // this is the array construction for the DAY view
4086
                $halfhour = 2 * $agendatime['0'];
4087
                if ($agendatime['1'] >= '30') {
4088
                    $halfhour = $halfhour + 1;
4089
                }
4090
4091
                //Display events by list
4092
                $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>";
4093
            }
4094
        }
4095
4096
        return $agendaitems;
4097
    }
4098
4099
    /**
4100
     * Show the monthcalender of the given month.
4101
     *
4102
     * @param    array    Agendaitems
4103
     * @param    int    Month number
4104
     * @param    int    Year number
4105
     * @param    array    Array of strings containing long week day names (deprecated, you can send an empty array
4106
     *                          instead)
4107
     * @param    string    The month name
4108
     */
4109
    public static function display_mymonthcalendar(
4110
        $user_id,
4111
        $agendaitems,
4112
        $month,
4113
        $year,
4114
        $weekdaynames,
4115
        $monthName,
4116
        $show_content = true
4117
    ) {
4118
        global $DaysShort, $course_path;
4119
        //Handle leap year
4120
        $numberofdays = [
4121
            0,
4122
            31,
4123
            28,
4124
            31,
4125
            30,
4126
            31,
4127
            30,
4128
            31,
4129
            31,
4130
            30,
4131
            31,
4132
            30,
4133
            31,
4134
        ];
4135
        if (($year % 400 == 0) or ($year % 4 == 0 and $year % 100 != 0)) {
4136
            $numberofdays[2] = 29;
4137
        }
4138
        //Get the first day of the month
4139
        $dayone = getdate(mktime(0, 0, 0, $month, 1, $year));
4140
        //Start the week on monday
4141
        $startdayofweek = $dayone['wday'] != 0 ? ($dayone['wday'] - 1) : 6;
4142
        $g_cc = (isset($_GET['courseCode']) ? $_GET['courseCode'] : '');
4143
4144
        $next_month = ($month == 1 ? 12 : $month - 1);
4145
        $prev_month = ($month == 12 ? 1 : $month + 1);
4146
4147
        $next_year = ($month == 1 ? $year - 1 : $year);
4148
        $prev_year = ($month == 12 ? $year + 1 : $year);
4149
4150
        if ($show_content) {
4151
            $back_url = Display::url(
4152
                get_lang('Previous'),
4153
                api_get_self()."?coursePath=".urlencode(
4154
                    $course_path
4155
                )."&courseCode=".Security::remove_XSS(
4156
                    $g_cc
4157
                )."&action=view&view=month&month=".$next_month."&year=".$next_year
4158
            );
4159
            $next_url = Display::url(
4160
                get_lang('Next'),
4161
                api_get_self()."?coursePath=".urlencode(
4162
                    $course_path
4163
                )."&courseCode=".Security::remove_XSS(
4164
                    $g_cc
4165
                )."&action=view&view=month&month=".$prev_month."&year=".$prev_year
4166
            );
4167
        } else {
4168
            $back_url = Display::url(
4169
                get_lang('Previous'),
4170
                '',
4171
                [
4172
                    'onclick' => "load_calendar('".$user_id."','".$next_month."', '".$next_year."'); ",
4173
                    'class' => 'btn ui-button ui-widget ui-state-default',
4174
                ]
4175
            );
4176
            $next_url = Display::url(
4177
                get_lang('Next'),
4178
                '',
4179
                [
4180
                    'onclick' => "load_calendar('".$user_id."','".$prev_month."', '".$prev_year."'); ",
4181
                    'class' => 'pull-right btn ui-button ui-widget ui-state-default',
4182
                ]
4183
            );
4184
        }
4185
        $html = '';
4186
        $html .= '<div class="actions">';
4187
        $html .= '<div class="row">';
4188
        $html .= '<div class="col-md-4">'.$back_url.'</div>';
4189
        $html .= '<div class="col-md-4"><p class="agenda-title text-center">'.$monthName." ".$year.'</p></div>';
4190
        $html .= '<div class="col-md-4">'.$next_url.'</div>';
4191
        $html .= '</div>';
4192
        $html .= '</div>';
4193
        $html .= '<table id="agenda_list2" class="table table-bordered">';
4194
        $html .= '<tr>';
4195
        for ($ii = 1; $ii < 8; $ii++) {
4196
            $html .= '<td class="weekdays">'.$DaysShort[$ii % 7].'</td>';
4197
        }
4198
        $html .= '</tr>';
4199
4200
        $curday = -1;
4201
        $today = getdate();
4202
        while ($curday <= $numberofdays[$month]) {
4203
            $html .= "<tr>";
4204
            for ($ii = 0; $ii < 7; $ii++) {
4205
                if (($curday == -1) && ($ii == $startdayofweek)) {
4206
                    $curday = 1;
4207
                }
4208
                if (($curday > 0) && ($curday <= $numberofdays[$month])) {
4209
                    $bgcolor = $class = 'class="days_week"';
4210
                    $dayheader = Display::div(
4211
                        $curday,
4212
                        ['class' => 'agenda_day']
4213
                    );
4214
                    if (($curday == $today['mday']) && ($year == $today['year']) && ($month == $today['mon'])) {
4215
                        $class = "class=\"days_today\" style=\"width:10%;\"";
4216
                    }
4217
4218
                    $html .= "<td ".$class.">".$dayheader;
4219
4220
                    if (!empty($agendaitems[$curday])) {
4221
                        $items = $agendaitems[$curday];
4222
                        $items = msort($items, 'start_date_tms');
4223
4224
                        foreach ($items as $value) {
4225
                            $value['title'] = Security::remove_XSS(
4226
                                $value['title']
4227
                            );
4228
                            $start_time = api_format_date(
4229
                                $value['start_date'],
4230
                                TIME_NO_SEC_FORMAT
4231
                            );
4232
                            $end_time = '';
4233
4234
                            if (!empty($value['end_date'])) {
4235
                                $end_time = '-&nbsp;<i>'.api_format_date(
4236
                                        $value['end_date'],
4237
                                        DATE_TIME_FORMAT_LONG
4238
                                    ).'</i>';
4239
                            }
4240
                            $complete_time = '<i>'.api_format_date(
4241
                                    $value['start_date'],
4242
                                    DATE_TIME_FORMAT_LONG
4243
                                ).'</i>&nbsp;'.$end_time;
4244
                            $time = '<i>'.$start_time.'</i>';
4245
4246
                            switch ($value['calendar_type']) {
4247
                                case 'personal':
4248
                                    $bg_color = '#D0E7F4';
4249
                                    $icon = Display::return_icon(
4250
                                        'user.png',
4251
                                        get_lang('MyAgenda'),
4252
                                        [],
4253
                                        ICON_SIZE_SMALL
4254
                                    );
4255
                                    break;
4256
                                case 'global':
4257
                                    $bg_color = '#FFBC89';
4258
                                    $icon = Display::return_icon(
4259
                                        'view_remove.png',
4260
                                        get_lang('GlobalEvent'),
4261
                                        [],
4262
                                        ICON_SIZE_SMALL
4263
                                    );
4264
                                    break;
4265
                                case 'course':
4266
                                    $bg_color = '#CAFFAA';
4267
                                    $icon_name = 'course.png';
4268
                                    if (!empty($value['session_id'])) {
4269
                                        $icon_name = 'session.png';
4270
                                    }
4271
                                    if ($show_content) {
4272
                                        $icon = Display::url(
4273
                                            Display::return_icon(
4274
                                                $icon_name,
4275
                                                $value['course_name'].' '.get_lang(
4276
                                                    'Course'
4277
                                                ),
4278
                                                [],
4279
                                                ICON_SIZE_SMALL
4280
                                            ),
4281
                                            $value['url']
4282
                                        );
4283
                                    } else {
4284
                                        $icon = Display::return_icon(
4285
                                            $icon_name,
4286
                                            $value['course_name'].' '.get_lang(
4287
                                                'Course'
4288
                                            ),
4289
                                            [],
4290
                                            ICON_SIZE_SMALL
4291
                                        );
4292
                                    }
4293
                                    break;
4294
                                default:
4295
                                    break;
4296
                            }
4297
4298
                            $result = '<div class="rounded_div_agenda" style="background-color:'.$bg_color.';">';
4299
4300
                            if ($show_content) {
4301
                                //Setting a personal event to green
4302
                                $icon = Display::div(
4303
                                    $icon,
4304
                                    ['style' => 'float:right']
4305
                                );
4306
4307
                                $link = $value['calendar_type'].'_'.$value['id'].'_'.$value['course_id'].'_'.$value['session_id'];
4308
4309
                                //Link to bubble
4310
                                $url = Display::url(
4311
                                    cut($value['title'], 40),
4312
                                    '#',
4313
                                    ['id' => $link, 'class' => 'opener']
4314
                                );
4315
                                $result .= $time.' '.$icon.' '.Display::div(
4316
                                        $url
4317
                                    );
4318
4319
                                //Hidden content
4320
                                $content = Display::div(
4321
                                    $icon.Display::tag(
4322
                                        'h2',
4323
                                        $value['course_name']
4324
                                    ).'<hr />'.Display::tag(
4325
                                        'h3',
4326
                                        $value['title']
4327
                                    ).$complete_time.'<hr />'.Security::remove_XSS(
4328
                                        $value['content']
4329
                                    )
4330
                                );
4331
4332
                                //Main div
4333
                                $result .= Display::div(
4334
                                    $content,
4335
                                    [
4336
                                        'id' => 'main_'.$link,
4337
                                        'class' => 'dialog',
4338
                                        'style' => 'display:none',
4339
                                    ]
4340
                                );
4341
                                $result .= '</div>';
4342
                                $html .= $result;
4343
                            } else {
4344
                                $html .= $result .= $icon.'</div>';
4345
                            }
4346
                        }
4347
                    }
4348
                    $html .= "</td>";
4349
                    $curday++;
4350
                } else {
4351
                    $html .= "<td></td>";
4352
                }
4353
            }
4354
            $html .= "</tr>";
4355
        }
4356
        $html .= "</table>";
4357
        echo $html;
4358
    }
4359
4360
    /**
4361
     * Get personal agenda items between two dates (=all events from all registered courses).
4362
     *
4363
     * @param int $user_id user ID of the user
4364
     * @param    string    Optional start date in datetime format (if no start date is given, uses today)
4365
     * @param    string    Optional end date in datetime format (if no date is given, uses one year from now)
4366
     *
4367
     * @return array array of events ordered by start date, in
4368
     *               [0]('datestart','dateend','title'),[1]('datestart','dateend','title','link','coursetitle') format,
4369
     *               where datestart and dateend are in yyyyMMddhhmmss format
4370
     *
4371
     * @deprecated use agenda events
4372
     */
4373
    public static function get_personal_agenda_items_between_dates(
4374
        $user_id,
4375
        $date_start = '',
4376
        $date_end = ''
4377
    ) {
4378
        $items = [];
4379
        if ($user_id != strval(intval($user_id))) {
4380
            return $items;
4381
        }
4382
        if (empty($date_start)) {
4383
            $date_start = date('Y-m-d H:i:s');
4384
        }
4385
        if (empty($date_end)) {
4386
            $date_end = date(
4387
                'Y-m-d H:i:s',
4388
                mktime(0, 0, 0, date("m"), date("d"), date("Y") + 1)
4389
            );
4390
        }
4391
        $expr = '/\d{4}-\d{2}-\d{2}\ \d{2}:\d{2}:\d{2}/';
4392
        if (!preg_match($expr, $date_start)) {
4393
            return $items;
4394
        }
4395
        if (!preg_match($expr, $date_end)) {
4396
            return $items;
4397
        }
4398
4399
        // get agenda-items for every course
4400
        $courses = api_get_user_courses($user_id, false);
4401
        foreach ($courses as $id => $course) {
4402
            $c = api_get_course_info_by_id($course['real_id']);
4403
            //databases of the courses
4404
            $t_a = Database::get_course_table(TABLE_AGENDA, $course['db']);
4405
            $t_ip = Database::get_course_table(
4406
                TABLE_ITEM_PROPERTY,
4407
                $course['db']
4408
            );
4409
            // get the groups to which the user belong
4410
            $group_memberships = GroupManager:: get_group_ids(
4411
                $course['db'],
4412
                $user_id
4413
            );
4414
            // if the user is administrator of that course we show all the agenda items
4415
            if ($course['status'] == '1') {
4416
                //echo "course admin";
4417
                $sqlquery = "SELECT ".
4418
                    " DISTINCT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref ".
4419
                    " FROM ".$t_a." agenda, ".
4420
                    $t_ip." ip ".
4421
                    " WHERE agenda.id = ip.ref ".
4422
                    " AND agenda.start_date>='$date_start' ".
4423
                    " AND agenda.end_date<='$date_end' ".
4424
                    " AND ip.tool='".TOOL_CALENDAR_EVENT."' ".
4425
                    " AND ip.visibility='1' ".
4426
                    " GROUP BY agenda.id ".
4427
                    " ORDER BY start_date ";
4428
            } else {
4429
                // if the user is not an administrator of that course, then...
4430
                if (is_array($group_memberships) && count(
4431
                        $group_memberships
4432
                    ) > 0
4433
                ) {
4434
                    $sqlquery = "SELECT ".
4435
                        "DISTINCT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref ".
4436
                        " FROM ".$t_a." agenda, ".
4437
                        $t_ip." ip ".
4438
                        " WHERE agenda.id = ip.ref ".
4439
                        " AND agenda.start_date>='$date_start' ".
4440
                        " AND agenda.end_date<='$date_end' ".
4441
                        " AND ip.tool='".TOOL_CALENDAR_EVENT."' ".
4442
                        " AND	( ip.to_user_id='".$user_id."' OR (ip.to_group_id IS NULL OR ip.to_group_id IN (0, ".implode(
4443
                            ", ",
4444
                            $group_memberships
4445
                        ).")) ) ".
4446
                        " AND ip.visibility='1' ".
4447
                        " ORDER BY start_date ";
4448
                } else {
4449
                    $sqlquery = "SELECT ".
4450
                        "DISTINCT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref ".
4451
                        " FROM ".$t_a." agenda, ".
4452
                        $t_ip." ip ".
4453
                        " WHERE agenda.id = ip.ref ".
4454
                        " AND agenda.start_date>='$date_start' ".
4455
                        " AND agenda.end_date<='$date_end' ".
4456
                        " AND ip.tool='".TOOL_CALENDAR_EVENT."' ".
4457
                        " AND ( ip.to_user_id='".$user_id."' OR ip.to_group_id='0' OR ip.to_group_id IS NULL) ".
4458
                        " AND ip.visibility='1' ".
4459
                        " ORDER BY start_date ";
4460
                }
4461
            }
4462
4463
            $result = Database::query($sqlquery);
4464
            while ($item = Database::fetch_array($result)) {
4465
                $agendaday = date("j", strtotime($item['start_date']));
4466
                $month = date("n", strtotime($item['start_date']));
4467
                $year = date("Y", strtotime($item['start_date']));
4468
                $URL = api_get_path(
4469
                        WEB_PATH
4470
                    )."main/calendar/agenda.php?cidReq=".urlencode(
4471
                        $course["code"]
4472
                    )."&day=$agendaday&month=$month&year=$year#$agendaday";
4473
                list($year, $month, $day, $hour, $min, $sec) = explode(
4474
                    '[-: ]',
4475
                    $item['start_date']
4476
                );
4477
                $start_date = $year.$month.$day.$hour.$min;
4478
                list($year, $month, $day, $hour, $min, $sec) = explode(
4479
                    '[-: ]',
4480
                    $item['end_date']
4481
                );
4482
                $end_date = $year.$month.$day.$hour.$min;
4483
4484
                $items[] = [
4485
                    'datestart' => $start_date,
4486
                    'dateend' => $end_date,
4487
                    'title' => $item['title'],
4488
                    'link' => $URL,
4489
                    'coursetitle' => $c['name'],
4490
                ];
4491
            }
4492
        }
4493
4494
        return $items;
4495
    }
4496
4497
    /**
4498
     * This function calculates the startdate of the week (monday)
4499
     * and the enddate of the week (sunday)
4500
     * and returns it as an array.
4501
     */
4502
    public static function calculate_start_end_of_week($week_number, $year)
4503
    {
4504
        // determine the start and end date
4505
        // step 1: we calculate a timestamp for a day in this week
4506
        $random_day_in_week = mktime(
4507
                0,
4508
                0,
4509
                0,
4510
                1,
4511
                1,
4512
                $year
4513
            ) + ($week_number) * (7 * 24 * 60 * 60); // we calculate a random day in this week
4514
        // step 2: we which day this is (0=sunday, 1=monday, ...)
4515
        $number_day_in_week = date('w', $random_day_in_week);
4516
        // step 3: we calculate the timestamp of the monday of the week we are in
4517
        $start_timestamp = $random_day_in_week - (($number_day_in_week - 1) * 24 * 60 * 60);
4518
        // step 4: we calculate the timestamp of the sunday of the week we are in
4519
        $end_timestamp = $random_day_in_week + ((7 - $number_day_in_week + 1) * 24 * 60 * 60) - 3600;
4520
        // step 5: calculating the start_day, end_day, start_month, end_month, start_year, end_year
4521
        $start_day = date('j', $start_timestamp);
4522
        $start_month = date('n', $start_timestamp);
4523
        $start_year = date('Y', $start_timestamp);
4524
        $end_day = date('j', $end_timestamp);
4525
        $end_month = date('n', $end_timestamp);
4526
        $end_year = date('Y', $end_timestamp);
4527
        $start_end_array['start']['day'] = $start_day;
4528
        $start_end_array['start']['month'] = $start_month;
4529
        $start_end_array['start']['year'] = $start_year;
4530
        $start_end_array['end']['day'] = $end_day;
4531
        $start_end_array['end']['month'] = $end_month;
4532
        $start_end_array['end']['year'] = $end_year;
4533
4534
        return $start_end_array;
4535
    }
4536
4537
    /**
4538
     * @return bool
4539
     */
4540
    public function getIsAllowedToEdit()
4541
    {
4542
        return $this->isAllowedToEdit;
4543
    }
4544
4545
    /**
4546
     * @param bool $isAllowedToEdit
4547
     */
4548
    public function setIsAllowedToEdit($isAllowedToEdit)
4549
    {
4550
        $this->isAllowedToEdit = $isAllowedToEdit;
4551
    }
4552
4553
    /**
4554
     * Format needed for the Fullcalendar js lib.
4555
     *
4556
     * @param string $utcTime
4557
     *
4558
     * @return bool|string
4559
     */
4560
    public function formatEventDate($utcTime)
4561
    {
4562
        $utcTimeZone = new DateTimeZone('UTC');
4563
        $platformTimeZone = new DateTimeZone(api_get_timezone());
4564
4565
        $eventDate = new DateTime($utcTime, $utcTimeZone);
4566
        $eventDate->setTimezone($platformTimeZone);
4567
4568
        return $eventDate->format(DateTime::ISO8601);
4569
    }
4570
4571
    /**
4572
     * @throws \Doctrine\ORM\OptimisticLockException
4573
     * @throws \Doctrine\ORM\ORMException
4574
     * @throws \Doctrine\ORM\TransactionRequiredException
4575
     */
4576
    public static function saveCollectiveProperties(array $inviteeUserList, bool $isCollective, int $eventId)
4577
    {
4578
        $em = Database::getManager();
4579
4580
        $event = $em->find('ChamiloCoreBundle:PersonalAgenda', $eventId);
4581
4582
        $invitation = new AgendaEventInvitation();
4583
        $invitation->setCreator(api_get_user_entity(api_get_user_id()));
4584
4585
        $event
4586
            ->setCollective($isCollective)
4587
            ->setInvitation($invitation)
4588
        ;
4589
4590
        $em->persist($event);
4591
4592
        foreach ($inviteeUserList as $inviteeId) {
4593
            $invitee = new AgendaEventInvitee();
4594
            $invitee
4595
                ->setUser(api_get_user_entity($inviteeId))
4596
                ->setInvitation($invitation)
4597
            ;
4598
4599
            $em->persist($invitee);
4600
        }
4601
4602
        $em->flush();
4603
    }
4604
4605
    public static function getJsForReminders(string $cssSelectorBtnAdd): string
4606
    {
4607
        return '
4608
            var template = \'<div class="form-group">\' +
4609
                \'<div class="col-sm-offset-2 col-sm-3">\' +
4610
                \'<input min="0" step="1" id="notification_count[]" type="number" class=" form-control" name="notification_count[]">\' +
4611
                \'</div>\' +
4612
                \'<div class="col-sm-3">\' +
4613
                \'<select class="form-control" name="notification_period[]" id="form_notification_period[]">\' +
4614
                \'<option value="i">'.get_lang('Minutes').'</option>\' +
4615
                \'<option value="h">'.get_lang('Hours').'</option>\' +
4616
                \'<option value="d">'.get_lang('Days').'</option>\' +
4617
                \'</select>\' +
4618
                \'</div>\' +
4619
                \'<div class="col-sm-2"><p class="form-control-static">'.get_lang('Before').'</p></div>\' +
4620
                \'<div class="text-right col-sm-2">\' +
4621
                \'<button class="btn btn-default delete-notification" type="button" aria-label="'.get_lang('Delete').'"><em class="fa fa-times"></em></button>\' +
4622
                \'</div>\' +
4623
                \'</div>\';
4624
4625
            $("'.$cssSelectorBtnAdd.'").on("click", function (e) {
4626
                e.preventDefault();
4627
4628
                $(template).appendTo("#notification_list");
4629
                $("#notification_list select").selectpicker("refresh");
4630
            });
4631
4632
            $("#notification_list").on("click", ".delete-notification", function (e) {
4633
                e.preventDefault();
4634
4635
                $(this).parents(".form-group").remove();
4636
            });';
4637
    }
4638
4639
    private function editReminders(int $eventId, array $reminderList = [])
4640
    {
4641
        if (false === api_get_configuration_value('agenda_reminders')) {
4642
            return;
4643
        }
4644
4645
        $eventReminders = $this->parseEventReminders(
4646
            $this->getEventReminders($eventId)
4647
        );
4648
        $eventIntervalList = array_column($eventReminders, 'date_interval');
4649
4650
        foreach ($eventIntervalList as $eventIntervalInfo) {
4651
            if (!in_array($eventIntervalInfo, $reminderList)) {
4652
                $this->removeReminders($eventId, $eventIntervalInfo[0], $eventIntervalInfo[1]);
4653
            }
4654
        }
4655
4656
        foreach ($reminderList as $reminderInfo) {
4657
            if (!in_array($reminderInfo, $eventIntervalList)) {
4658
                $this->addReminder($eventId, $reminderInfo[0], $reminderInfo[1]);
4659
            }
4660
        }
4661
    }
4662
4663
    private static function isUserInvitedInEvent(int $id, int $userId): bool
4664
    {
4665
        $user = api_get_user_entity($userId);
4666
4667
        $event = Database::getManager()
4668
            ->getRepository('ChamiloCoreBundle:PersonalAgenda')
4669
            ->findOneByIdAndInvitee($id, $user)
4670
        ;
4671
4672
        return null !== $event;
4673
    }
4674
4675
    private function loadEventsAsInvitee(User $user, ?DateTime $startDate, ?DateTime $endDate)
4676
    {
4677
        $em = Database::getManager();
4678
        $eventRepo = $em->getRepository('ChamiloCoreBundle:PersonalAgenda');
4679
        $events = $eventRepo->getEventsForInvitee($user, $startDate, $endDate);
4680
4681
        foreach ($events as $event) {
4682
            $eventInfo = [];
4683
            $eventInfo['id'] = 'personal_'.$event->getId();
4684
            $eventInfo['title'] = $event->getTitle();
4685
            $eventInfo['className'] = 'personal';
4686
            $eventInfo['borderColor'] = $eventInfo['backgroundColor'] = $this->event_personal_color;
4687
            $eventInfo['editable'] = $event->isCollective();
4688
            $eventInfo['sent_to'] = get_lang('Me');
4689
            $eventInfo['type'] = 'personal';
4690
4691
            if ($event->getDate()) {
4692
                $eventInfo['start'] = $this->formatEventDate($event->getDate()->format('Y-m-d H:i:s'));
4693
                $eventInfo['start_date_localtime'] = api_get_local_time($event->getDate());
4694
            }
4695
4696
            if ($event->getEnddate()) {
4697
                $eventInfo['end'] = $this->formatEventDate($event->getEnddate()->format('Y-m-d H:i:s'));
4698
                $eventInfo['end_date_localtime'] = api_get_local_time($event->getEnddate());
4699
            }
4700
4701
            $eventInfo['description'] = $event->getText();
4702
            $eventInfo['allDay'] = $event->getAllDay();
4703
            $eventInfo['parent_event_id'] = 0;
4704
            $eventInfo['has_children'] = 0;
4705
            $eventInfo['collective'] = $event->isCollective();
4706
            $eventInfo['invitees'] = [];
4707
4708
            $invitation = $event->getInvitation();
4709
4710
            if ($invitation) {
4711
                foreach ($invitation->getInvitees() as $invitee) {
4712
                    $inviteeUser = $invitee->getUser();
4713
4714
                    $eventInfo['invitees'][] = [
4715
                        'id' => $inviteeUser->getId(),
4716
                        'name' => $inviteeUser->getCompleteNameWithUsername(),
4717
                    ];
4718
                }
4719
            }
4720
4721
            $this->events[] = $eventInfo;
4722
        }
4723
    }
4724
4725
    private function loadSessionsAsEvents(int $start, int $end)
4726
    {
4727
        if (false === api_get_configuration_value('personal_calendar_show_sessions_occupation')) {
4728
            return;
4729
        }
4730
4731
        $start = api_get_utc_datetime($start, false, true);
4732
        $end = api_get_utc_datetime($end, false, true);
4733
        $userInfo = api_get_user_info();
4734
        $sessionList = SessionManager::getSessionsFollowedByUser($userInfo['id'], $userInfo['status']);
4735
4736
        foreach ($sessionList as $sessionInfo) {
4737
            if (!empty($sessionInfo['duration'])) {
4738
                $courseAccess = CourseManager::getFirstCourseAccessPerSessionAndUser(
4739
                    $sessionInfo['session_id'],
4740
                    $userInfo['id']
4741
                );
4742
4743
                if (empty($courseAccess)) {
4744
                    continue;
4745
                }
4746
4747
                $firstAccessDate = new DateTime($courseAccess['login_course_date'], new DateTimeZone('UTC'));
4748
                $lastAccessDate = clone $firstAccessDate;
4749
                $lastAccessDate->modify('+'.$sessionInfo['duration'].' days');
4750
4751
                if ($firstAccessDate->format('Y-m-d H:i:s') > $start
4752
                    && $lastAccessDate->format('Y-m-d H:i:s') < $end
4753
                ) {
4754
                    continue;
4755
                }
4756
4757
                $courseList = SessionManager::get_course_list_by_session_id($sessionInfo['id']);
4758
                $firstCourse = current($courseList);
4759
4760
                $this->events[] = [
4761
                    'id' => 'session_'.$sessionInfo['id'],
4762
                    'session_id' => $sessionInfo['id'],
4763
                    'title' => $sessionInfo['name'],
4764
                    'description' => $sessionInfo['show_description'] ? $sessionInfo['description'] : '',
4765
                    'className' => 'personal',
4766
                    'borderColor' => $this->event_personal_color,
4767
                    'backgroundColor' => $this->event_personal_color,
4768
                    'editable' => false,
4769
                    'sent_to' => get_lang('Me'),
4770
                    'type' => 'session',
4771
                    'start' => $firstAccessDate->format(DateTime::ISO8601),
4772
                    'start_date_localtime' => api_get_local_time($firstAccessDate),
4773
                    'end' => $lastAccessDate->format(DateTime::ISO8601),
4774
                    'end_date_localtime' => api_get_local_time($lastAccessDate),
4775
                    'allDay' => 0,
4776
                    'parent_event_id' => 0,
4777
                    'has_children' => 0,
4778
                    'course_url' => api_get_course_url($firstCourse['code'], $sessionInfo['id']),
4779
                ];
4780
4781
                continue;
4782
            }
4783
4784
            if ($sessionInfo['display_start_date'] < $start
4785
                && $sessionInfo['display_end_date'] > $end
4786
            ) {
4787
                continue;
4788
            }
4789
4790
            $courseList = SessionManager::get_course_list_by_session_id($sessionInfo['id']);
4791
            $firstCourse = current($courseList);
4792
4793
            $this->events[] = [
4794
                'id' => 'session_'.$sessionInfo['id'],
4795
                'session_id' => $sessionInfo['id'],
4796
                'title' => $sessionInfo['name'],
4797
                'description' => $sessionInfo['show_description'] ? $sessionInfo['description'] : '',
4798
                'className' => 'personal',
4799
                'borderColor' => $this->event_personal_color,
4800
                'backgroundColor' => $this->event_personal_color,
4801
                'editable' => false,
4802
                'sent_to' => get_lang('Me'),
4803
                'type' => 'session_subscription',
4804
                'start' => $sessionInfo['display_start_date'],
4805
                'start_date_localtime' => $sessionInfo['display_start_date']
4806
                    ? $this->formatEventDate($sessionInfo['display_start_date'])
4807
                    : '',
4808
                'end' => $sessionInfo['display_end_date'],
4809
                'end_date_localtime' => $sessionInfo['display_end_date']
4810
                    ? $this->formatEventDate($sessionInfo['display_end_date'])
4811
                    : '',
4812
                'allDay' => 0,
4813
                'parent_event_id' => 0,
4814
                'has_children' => 0,
4815
                'course_url' => api_get_course_url($firstCourse['code'], $sessionInfo['id']),
4816
            ];
4817
        }
4818
    }
4819
}
4820