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

Agenda::getTypes()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

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