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

Agenda::set_course()   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 1
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_careers_in_global_agenda')) {
452
                        $attributes['career_id'] = $careerId;
453
                        $attributes['promotion_id'] = $promotionId;
454
                    }
455
456
                    $id = Database::insert(
457
                        $this->tbl_global_agenda,
458
                        $attributes
459
                    );
460
                }
461
                break;
462
        }
463
464
        if (api_get_configuration_value('agenda_reminders')) {
465
            foreach ($reminders as $reminder) {
466
                $this->addReminder($id, $reminder[0], $reminder[1]);
467
            }
468
        }
469
470
        return $id;
471
    }
472
473
    /**
474
     * @throws Exception
475
     */
476
    public function addReminder($eventId, $count, $period)
477
    {
478
        switch ($period) {
479
            case 'i':
480
                $dateInterval = DateInterval::createFromDateString("$count minutes");
481
                break;
482
            case 'h':
483
                $dateInterval = DateInterval::createFromDateString("$count hours");
484
                break;
485
            case 'd':
486
                $dateInterval = DateInterval::createFromDateString("$count days");
487
                break;
488
            default:
489
                return null;
490
        }
491
492
        $agendaReminder = new AgendaReminder();
493
        $agendaReminder
494
            ->setType($this->type)
495
            ->setEventId($eventId)
496
            ->setDateInterval($dateInterval)
497
        ;
498
499
        $em = Database::getManager();
500
        $em->persist($agendaReminder);
501
        $em->flush();
502
    }
503
504
    public function removeReminders(int $eventId, int $count, string $period)
505
    {
506
        switch ($period) {
507
            case 'i':
508
                $dateInterval = DateInterval::createFromDateString("$count minutes");
509
                break;
510
            case 'h':
511
                $dateInterval = DateInterval::createFromDateString("$count hours");
512
                break;
513
            case 'd':
514
                $dateInterval = DateInterval::createFromDateString("$count days");
515
                break;
516
            default:
517
                return null;
518
        }
519
520
        Database::getManager()
521
            ->createQuery(
522
                'DELETE FROM ChamiloCoreBundle:AgendaReminder ar
523
                WHERE ar.eventId = :eventId AND ar.type = :type AND ar.dateInterval = :dateInterval'
524
            )
525
            ->setParameters(
526
                [
527
                    'eventId' => $eventId,
528
                    'type' => $this->type,
529
                    'dateInterval' => $dateInterval,
530
                ]
531
            )
532
            ->execute();
533
    }
534
535
    public function getReminder(int $eventId, int $count, string $period)
536
    {
537
        switch ($period) {
538
            case 'i':
539
                $dateInterval = DateInterval::createFromDateString("$count minutes");
540
                break;
541
            case 'h':
542
                $dateInterval = DateInterval::createFromDateString("$count hours");
543
                break;
544
            case 'd':
545
                $dateInterval = DateInterval::createFromDateString("$count days");
546
                break;
547
            default:
548
                return null;
549
        }
550
551
        $em = Database::getManager();
552
        $remindersRepo = $em->getRepository('ChamiloCoreBundle:AgendaReminder');
553
554
        return $remindersRepo->findOneBy(
555
            [
556
                'type' => $this->type,
557
                'dateInterval' => $dateInterval,
558
                'eventId' => $eventId,
559
            ]
560
        );
561
    }
562
563
    /**
564
     * @param int $eventId
565
     * @param int $courseId
566
     *
567
     * @return array
568
     */
569
    public function getRepeatedInfoByEvent($eventId, $courseId)
570
    {
571
        $repeatTable = Database::get_course_table(TABLE_AGENDA_REPEAT);
572
        $eventId = (int) $eventId;
573
        $courseId = (int) $courseId;
574
        $sql = "SELECT * FROM $repeatTable
575
                WHERE c_id = $courseId AND cal_id = $eventId";
576
        $res = Database::query($sql);
577
        $repeatInfo = [];
578
        if (Database::num_rows($res) > 0) {
579
            $repeatInfo = Database::fetch_array($res, 'ASSOC');
580
        }
581
582
        return $repeatInfo;
583
    }
584
585
    /**
586
     * @param string $type
587
     * @param string $startEvent      in UTC
588
     * @param string $endEvent        in UTC
589
     * @param string $repeatUntilDate in UTC
590
     *
591
     * @throws Exception
592
     *
593
     * @return array with local times
594
     */
595
    public function generateDatesByType($type, $startEvent, $endEvent, $repeatUntilDate)
596
    {
597
        $continue = true;
598
        $repeatUntilDate = new DateTime($repeatUntilDate, new DateTimeZone('UTC'));
599
        $loopMax = 365;
600
        $counter = 0;
601
        $list = [];
602
603
        switch ($type) {
604
            case 'daily':
605
                $interval = 'P1D';
606
                break;
607
            case 'weekly':
608
                $interval = 'P1W';
609
                break;
610
            case 'monthlyByDate':
611
                $interval = 'P1M';
612
                break;
613
            case 'monthlyByDay':
614
                // not yet implemented
615
                break;
616
            case 'monthlyByDayR':
617
                // not yet implemented
618
                break;
619
            case 'yearly':
620
                $interval = 'P1Y';
621
                break;
622
        }
623
624
        if (empty($interval)) {
625
            return [];
626
        }
627
        $timeZone = api_get_timezone();
628
629
        while ($continue) {
630
            $startDate = new DateTime($startEvent, new DateTimeZone('UTC'));
631
            $endDate = new DateTime($endEvent, new DateTimeZone('UTC'));
632
633
            $startDate->add(new DateInterval($interval));
634
            $endDate->add(new DateInterval($interval));
635
636
            $newStartDate = $startDate->format('Y-m-d H:i:s');
637
            $newEndDate = $endDate->format('Y-m-d H:i:s');
638
639
            $startEvent = $newStartDate;
640
            $endEvent = $newEndDate;
641
642
            if ($endDate > $repeatUntilDate) {
643
                break;
644
            }
645
646
            // @todo remove comment code
647
            // The code below was not adpating to saving light time but was doubling the difference with UTC time.
648
            // Might be necessary to adapt to update saving light time difference.
649
            /*            $startDateInLocal = new DateTime($newStartDate, new DateTimeZone($timeZone));
650
                        if ($startDateInLocal->format('I') == 0) {
651
                            // Is saving time? Then fix UTC time to add time
652
                            $seconds = $startDateInLocal->getOffset();
653
                            $startDate->add(new DateInterval("PT".$seconds."S"));
654
                            //$startDateFixed = $startDate->format('Y-m-d H:i:s');
655
                            //$startDateInLocalFixed = new DateTime($startDateFixed, new DateTimeZone($timeZone));
656
                            //$newStartDate = $startDateInLocalFixed->format('Y-m-d H:i:s');
657
                            //$newStartDate = $startDate->setTimezone(new DateTimeZone($timeZone))->format('Y-m-d H:i:s');
658
                        }
659
660
                        $endDateInLocal = new DateTime($newEndDate, new DateTimeZone($timeZone));
661
                        if ($endDateInLocal->format('I') == 0) {
662
                            // Is saving time? Then fix UTC time to add time
663
                            $seconds = $endDateInLocal->getOffset();
664
                            $endDate->add(new DateInterval("PT".$seconds."S"));
665
                            //$endDateFixed = $endDate->format('Y-m-d H:i:s');
666
                            //$endDateInLocalFixed = new DateTime($endDateFixed, new DateTimeZone($timeZone));
667
                            //$newEndDate = $endDateInLocalFixed->format('Y-m-d H:i:s');
668
                    }
669
            */
670
            $newStartDate = $startDate->setTimezone(new DateTimeZone($timeZone))->format('Y-m-d H:i:s');
671
            $newEndDate = $endDate->setTimezone(new DateTimeZone($timeZone))->format('Y-m-d H:i:s');
672
            $list[] = ['start' => $newStartDate, 'end' => $newEndDate];
673
            $counter++;
674
675
            // just in case stop if more than $loopMax
676
            if ($counter > $loopMax) {
677
                break;
678
            }
679
        }
680
681
        return $list;
682
    }
683
684
    /**
685
     * @param int    $eventId
686
     * @param string $type
687
     * @param string $end     in UTC
688
     * @param array  $sentTo
689
     *
690
     * @return bool
691
     */
692
    public function addRepeatedItem($eventId, $type, $end, $sentTo = [])
693
    {
694
        $t_agenda = Database::get_course_table(TABLE_AGENDA);
695
        $t_agenda_r = Database::get_course_table(TABLE_AGENDA_REPEAT);
696
697
        if (empty($this->course)) {
698
            return false;
699
        }
700
701
        $courseId = $this->course['real_id'];
702
        $eventId = (int) $eventId;
703
704
        $sql = "SELECT title, content, start_date, end_date, all_day
705
                FROM $t_agenda
706
                WHERE c_id = $courseId AND id = $eventId";
707
        $res = Database::query($sql);
708
709
        if (Database::num_rows($res) !== 1) {
710
            return false;
711
        }
712
713
        $typeList = [
714
            'daily',
715
            'weekly',
716
            'monthlyByDate',
717
            'monthlyByDay',
718
            'monthlyByDayR',
719
            'yearly',
720
        ];
721
722
        if (!in_array($type, $typeList)) {
723
            return false;
724
        }
725
726
        $now = time();
727
728
        // The event has to repeat *in the future*. We don't allow repeated
729
        // events in the past.
730
        $endTimeStamp = api_strtotime($end, 'UTC');
731
732
        if ($endTimeStamp < $now) {
733
            return false;
734
        }
735
736
        $row = Database::fetch_array($res);
737
738
        $title = $row['title'];
739
        $content = $row['content'];
740
        $allDay = $row['all_day'];
741
742
        $type = Database::escape_string($type);
743
        $end = Database::escape_string($end);
744
745
        $sql = "INSERT INTO $t_agenda_r (c_id, cal_id, cal_type, cal_end)
746
                VALUES ($courseId, '$eventId', '$type', '$endTimeStamp')";
747
        Database::query($sql);
748
749
        $generatedDates = $this->generateDatesByType($type, $row['start_date'], $row['end_date'], $end);
750
751
        if (empty($generatedDates)) {
752
            return false;
753
        }
754
755
        foreach ($generatedDates as $dateInfo) {
756
//            $start = api_get_local_time($dateInfo['start']);
757
//            $end = api_get_local_time($dateInfo['end']);
758
            // On line 529 in function generateDatesByType there is a @todo remove comment code
759
            // just before the part updating the date in local time so keep both synchronised
760
            $start = $dateInfo['start'];
761
            $end = $dateInfo['end'];
762
763
            $this->addEvent(
764
                $start,
765
                $end,
766
                $allDay,
767
                $title,
768
                $content,
769
                $sentTo,
770
                false,
771
                $eventId
772
            );
773
        }
774
775
        return true;
776
    }
777
778
    /**
779
     * @param int   $item_id
780
     * @param array $sentTo
781
     *
782
     * @return int
783
     */
784
    public function storeAgendaEventAsAnnouncement($item_id, $sentTo = [])
785
    {
786
        $table_agenda = Database::get_course_table(TABLE_AGENDA);
787
        $courseId = api_get_course_int_id();
788
789
        // Check params
790
        if (empty($item_id) || $item_id != strval(intval($item_id))) {
791
            return -1;
792
        }
793
794
        // Get the agenda item.
795
        $item_id = intval($item_id);
796
        $sql = "SELECT * FROM $table_agenda
797
                WHERE c_id = $courseId AND id = ".$item_id;
798
        $res = Database::query($sql);
799
800
        if (Database::num_rows($res) > 0) {
801
            $row = Database::fetch_array($res, 'ASSOC');
802
803
            // Sending announcement
804
            if (!empty($sentTo)) {
805
                $id = AnnouncementManager::add_announcement(
806
                    api_get_course_info(),
807
                    api_get_session_id(),
808
                    $row['title'],
809
                    $row['content'],
810
                    $sentTo,
811
                    null,
812
                    null,
813
                    $row['end_date']
814
                );
815
816
                AnnouncementManager::sendEmail(
817
                    api_get_course_info(),
818
                    api_get_session_id(),
819
                    $id
820
                );
821
822
                return $id;
823
            }
824
        }
825
826
        return -1;
827
    }
828
829
    /**
830
     * Edits an event.
831
     *
832
     * @param int    $id
833
     * @param string $start                 datetime format: 2012-06-14 09:00:00
834
     * @param string $end                   datetime format: 2012-06-14 09:00:00
835
     * @param int    $allDay                is all day 'true' or 'false'
836
     * @param string $title
837
     * @param string $content
838
     * @param array  $usersToSend
839
     * @param array  $attachmentArray
840
     * @param array  $attachmentCommentList
841
     * @param string $comment
842
     * @param string $color
843
     * @param bool   $addAnnouncement
844
     * @param bool   $updateContent
845
     * @param int    $authorId
846
     *
847
     * @return bool
848
     */
849
    public function editEvent(
850
        $id,
851
        $start,
852
        $end,
853
        $allDay,
854
        $title,
855
        $content,
856
        $usersToSend = [],
857
        $attachmentArray = [],
858
        $attachmentCommentList = [],
859
        $comment = null,
860
        $color = '',
861
        $addAnnouncement = false,
862
        $updateContent = true,
863
        $authorId = 0,
864
        array $inviteesList = [],
865
        bool $isCollective = false,
866
        array $remindersList = [],
867
        int $careerId = 0,
868
        int $promotionId = 0
869
    ) {
870
        $id = (int) $id;
871
        $start = api_get_utc_datetime($start);
872
        $end = api_get_utc_datetime($end);
873
        $allDay = isset($allDay) && $allDay == 'true' ? 1 : 0;
874
        $currentUserId = api_get_user_id();
875
        $authorId = empty($authorId) ? $currentUserId : (int) $authorId;
876
877
        switch ($this->type) {
878
            case 'personal':
879
                $eventInfo = $this->get_event($id);
880
                if ($eventInfo['user'] != $currentUserId
881
                    && (
882
                        api_get_configuration_value('agenda_collective_invitations')
883
                            && !self::isUserInvitedInEvent($id, $currentUserId)
884
                    )
885
                ) {
886
                    break;
887
                }
888
                $attributes = [
889
                    'title' => $title,
890
                    'date' => $start,
891
                    'enddate' => $end,
892
                    'all_day' => $allDay,
893
                ];
894
895
                if ($updateContent) {
896
                    $attributes['text'] = $content;
897
                }
898
899
                if (!empty($color)) {
900
                    $attributes['color'] = $color;
901
                }
902
903
                Database::update(
904
                    $this->tbl_personal_agenda,
905
                    $attributes,
906
                    ['id = ?' => $id]
907
                );
908
909
                if (api_get_configuration_value('agenda_collective_invitations')) {
910
                    Agenda::saveCollectiveProperties($inviteesList, $isCollective, $id);
911
                }
912
                break;
913
            case 'course':
914
                $eventInfo = $this->get_event($id);
915
916
                if (empty($eventInfo)) {
917
                    return false;
918
                }
919
920
                $groupId = api_get_group_id();
921
                $groupIid = 0;
922
                $groupInfo = [];
923
                if ($groupId) {
924
                    $groupInfo = GroupManager::get_group_properties($groupId);
925
                    if ($groupInfo) {
926
                        $groupIid = $groupInfo['iid'];
927
                    }
928
                }
929
930
                $courseId = $this->course['real_id'];
931
932
                if (empty($courseId)) {
933
                    return false;
934
                }
935
936
                if (!$this->getIsAllowedToEdit()) {
937
                    return false;
938
                }
939
940
                $attributes = [
941
                    'title' => $title,
942
                    'start_date' => $start,
943
                    'end_date' => $end,
944
                    'all_day' => $allDay,
945
                    'comment' => $comment,
946
                ];
947
948
                if ($updateContent) {
949
                    $attributes['content'] = $content;
950
                }
951
952
                if (!empty($color)) {
953
                    $attributes['color'] = $color;
954
                }
955
956
                Database::update(
957
                    $this->tbl_course_agenda,
958
                    $attributes,
959
                    [
960
                        'id = ? AND c_id = ? AND session_id = ? ' => [
961
                            $id,
962
                            $courseId,
963
                            $this->sessionId,
964
                        ],
965
                    ]
966
                );
967
968
                if (!empty($usersToSend)) {
969
                    $sendTo = $this->parseSendToArray($usersToSend);
970
971
                    $usersToDelete = array_diff(
972
                        $eventInfo['send_to']['users'],
973
                        $sendTo['users']
974
                    );
975
                    $usersToAdd = array_diff(
976
                        $sendTo['users'],
977
                        $eventInfo['send_to']['users']
978
                    );
979
980
                    $groupsToDelete = array_diff(
981
                        $eventInfo['send_to']['groups'],
982
                        $sendTo['groups']
983
                    );
984
                    $groupToAdd = array_diff(
985
                        $sendTo['groups'],
986
                        $eventInfo['send_to']['groups']
987
                    );
988
989
                    if ($sendTo['everyone']) {
990
                        // Delete all from group
991
                        if (isset($eventInfo['send_to']['groups']) &&
992
                            !empty($eventInfo['send_to']['groups'])
993
                        ) {
994
                            foreach ($eventInfo['send_to']['groups'] as $group) {
995
                                $groupIidItem = 0;
996
                                if ($group) {
997
                                    $groupInfoItem = GroupManager::get_group_properties(
998
                                        $group
999
                                    );
1000
                                    if ($groupInfoItem) {
1001
                                        $groupIidItem = $groupInfoItem['iid'];
1002
                                    }
1003
                                }
1004
1005
                                api_item_property_delete(
1006
                                    $this->course,
1007
                                    TOOL_CALENDAR_EVENT,
1008
                                    $id,
1009
                                    0,
1010
                                    $groupIidItem,
1011
                                    $this->sessionId
1012
                                );
1013
                            }
1014
                        }
1015
1016
                        // Storing the selected users.
1017
                        if (isset($eventInfo['send_to']['users']) &&
1018
                            !empty($eventInfo['send_to']['users'])
1019
                        ) {
1020
                            foreach ($eventInfo['send_to']['users'] as $userId) {
1021
                                api_item_property_delete(
1022
                                    $this->course,
1023
                                    TOOL_CALENDAR_EVENT,
1024
                                    $id,
1025
                                    $userId,
1026
                                    $groupIid,
1027
                                    $this->sessionId
1028
                                );
1029
                            }
1030
                        }
1031
1032
                        // Add to everyone only.
1033
                        api_item_property_update(
1034
                            $this->course,
1035
                            TOOL_CALENDAR_EVENT,
1036
                            $id,
1037
                            'visible',
1038
                            $authorId,
1039
                            $groupInfo,
1040
                            null,
1041
                            $start,
1042
                            $end,
1043
                            $this->sessionId
1044
                        );
1045
                    } else {
1046
                        // Delete "everyone".
1047
                        api_item_property_delete(
1048
                            $this->course,
1049
                            TOOL_CALENDAR_EVENT,
1050
                            $id,
1051
                            0,
1052
                            0,
1053
                            $this->sessionId
1054
                        );
1055
1056
                        // Add groups
1057
                        if (!empty($groupToAdd)) {
1058
                            foreach ($groupToAdd as $group) {
1059
                                $groupInfoItem = [];
1060
                                if ($group) {
1061
                                    $groupInfoItem = GroupManager::get_group_properties(
1062
                                        $group
1063
                                    );
1064
                                }
1065
1066
                                api_item_property_update(
1067
                                    $this->course,
1068
                                    TOOL_CALENDAR_EVENT,
1069
                                    $id,
1070
                                    'visible',
1071
                                    $authorId,
1072
                                    $groupInfoItem,
1073
                                    0,
1074
                                    $start,
1075
                                    $end,
1076
                                    $this->sessionId
1077
                                );
1078
                            }
1079
                        }
1080
1081
                        // Delete groups.
1082
                        if (!empty($groupsToDelete)) {
1083
                            foreach ($groupsToDelete as $group) {
1084
                                $groupIidItem = 0;
1085
                                $groupInfoItem = [];
1086
                                if ($group) {
1087
                                    $groupInfoItem = GroupManager::get_group_properties(
1088
                                        $group
1089
                                    );
1090
                                    if ($groupInfoItem) {
1091
                                        $groupIidItem = $groupInfoItem['iid'];
1092
                                    }
1093
                                }
1094
1095
                                api_item_property_delete(
1096
                                    $this->course,
1097
                                    TOOL_CALENDAR_EVENT,
1098
                                    $id,
1099
                                    0,
1100
                                    $groupIidItem,
1101
                                    $this->sessionId
1102
                                );
1103
                            }
1104
                        }
1105
1106
                        // Add users.
1107
                        if (!empty($usersToAdd)) {
1108
                            foreach ($usersToAdd as $userId) {
1109
                                api_item_property_update(
1110
                                    $this->course,
1111
                                    TOOL_CALENDAR_EVENT,
1112
                                    $id,
1113
                                    'visible',
1114
                                    $authorId,
1115
                                    $groupInfo,
1116
                                    $userId,
1117
                                    $start,
1118
                                    $end,
1119
                                    $this->sessionId
1120
                                );
1121
                            }
1122
                        }
1123
1124
                        // Delete users.
1125
                        if (!empty($usersToDelete)) {
1126
                            foreach ($usersToDelete as $userId) {
1127
                                api_item_property_delete(
1128
                                    $this->course,
1129
                                    TOOL_CALENDAR_EVENT,
1130
                                    $id,
1131
                                    $userId,
1132
                                    $groupInfo,
1133
                                    $this->sessionId
1134
                                );
1135
                            }
1136
                        }
1137
                    }
1138
                }
1139
1140
                // Add announcement.
1141
                if (isset($addAnnouncement) && !empty($addAnnouncement)) {
1142
                    $this->storeAgendaEventAsAnnouncement(
1143
                        $id,
1144
                        $usersToSend
1145
                    );
1146
                }
1147
1148
                // Add attachment.
1149
                if (isset($attachmentArray) && !empty($attachmentArray)) {
1150
                    $counter = 0;
1151
                    foreach ($attachmentArray as $attachmentItem) {
1152
                        if (empty($attachmentItems['id'])) {
1153
                            continue;
1154
                        }
1155
1156
                        $this->updateAttachment(
1157
                            $attachmentItem['id'],
1158
                            $id,
1159
                            $attachmentItem,
1160
                            $attachmentCommentList[$counter],
1161
                            $this->course
1162
                        );
1163
                        $counter++;
1164
                    }
1165
                }
1166
                break;
1167
            case 'admin':
1168
            case 'platform':
1169
                if (api_is_platform_admin()) {
1170
                    $attributes = [
1171
                        'title' => $title,
1172
                        'start_date' => $start,
1173
                        'end_date' => $end,
1174
                        'all_day' => $allDay,
1175
                    ];
1176
1177
                    if (api_get_configuration_value('allow_careers_in_global_agenda')) {
1178
                        $attributes['career_id'] = $careerId;
1179
                        $attributes['promotion_id'] = $promotionId;
1180
                    }
1181
1182
                    if ($updateContent) {
1183
                        $attributes['content'] = $content;
1184
                    }
1185
                    Database::update(
1186
                        $this->tbl_global_agenda,
1187
                        $attributes,
1188
                        ['id = ?' => $id]
1189
                    );
1190
                }
1191
                break;
1192
        }
1193
1194
        $this->editReminders($id, $remindersList);
1195
1196
        return true;
1197
    }
1198
1199
    /**
1200
     * @param int  $id
1201
     * @param bool $deleteAllItemsFromSerie
1202
     *
1203
     * @throws \Doctrine\ORM\ORMException
1204
     * @throws \Doctrine\ORM\OptimisticLockException
1205
     */
1206
    public function deleteEvent($id, $deleteAllItemsFromSerie = false)
1207
    {
1208
        $em = Database::getManager();
1209
1210
        switch ($this->type) {
1211
            case 'personal':
1212
                $eventInfo = $this->get_event($id);
1213
                if ($eventInfo['user'] == api_get_user_id()) {
1214
                    Database::delete(
1215
                        $this->tbl_personal_agenda,
1216
                        ['id = ?' => $id]
1217
                    );
1218
                } elseif (api_get_configuration_value('agenda_collective_invitations')) {
1219
                    $currentUser = api_get_user_entity(api_get_user_id());
1220
1221
                    $eventRepo = $em->getRepository('ChamiloCoreBundle:PersonalAgenda');
1222
                    $event = $eventRepo->findOneByIdAndInvitee($id, $currentUser);
1223
                    $invitation = $event ? $event->getInvitation() : null;
1224
1225
                    if ($invitation) {
1226
                        $invitation->removeInviteeUser($currentUser);
1227
1228
                        $em->persist($invitation);
1229
                        $em->flush();
1230
                    }
1231
                }
1232
                break;
1233
            case 'course':
1234
                $courseId = api_get_course_int_id();
1235
                $isAllowToEdit = $this->getIsAllowedToEdit();
1236
1237
                if (!empty($courseId) && $isAllowToEdit) {
1238
                    $eventInfo = $this->get_event($id);
1239
                    if ($deleteAllItemsFromSerie) {
1240
                        /* This is one of the children.
1241
                           Getting siblings and delete 'Em all + the father! */
1242
                        if (isset($eventInfo['parent_event_id']) && !empty($eventInfo['parent_event_id'])) {
1243
                            // Removing items.
1244
                            $events = $this->getAllRepeatEvents($eventInfo['parent_event_id']);
1245
                            if (!empty($events)) {
1246
                                foreach ($events as $event) {
1247
                                    $this->deleteEvent($event['id']);
1248
                                }
1249
                            }
1250
                            // Removing parent.
1251
                            $this->deleteEvent($eventInfo['parent_event_id']);
1252
                        } else {
1253
                            // This is the father looking for the children.
1254
                            $events = $this->getAllRepeatEvents($id);
1255
                            if (!empty($events)) {
1256
                                foreach ($events as $event) {
1257
                                    $this->deleteEvent($event['id']);
1258
                                }
1259
                            }
1260
                        }
1261
                    }
1262
1263
                    // Removing from events.
1264
                    Database::delete(
1265
                        $this->tbl_course_agenda,
1266
                        ['id = ? AND c_id = ?' => [$id, $courseId]]
1267
                    );
1268
1269
                    api_item_property_update(
1270
                        $this->course,
1271
                        TOOL_CALENDAR_EVENT,
1272
                        $id,
1273
                        'delete',
1274
                        api_get_user_id()
1275
                    );
1276
1277
                    // Removing from series.
1278
                    Database::delete(
1279
                        $this->table_repeat,
1280
                        [
1281
                            'cal_id = ? AND c_id = ?' => [
1282
                                $id,
1283
                                $courseId,
1284
                            ],
1285
                        ]
1286
                    );
1287
1288
                    if (isset($eventInfo['attachment']) && !empty($eventInfo['attachment'])) {
1289
                        foreach ($eventInfo['attachment'] as $attachment) {
1290
                            self::deleteAttachmentFile(
1291
                                $attachment['id'],
1292
                                $this->course
1293
                            );
1294
                        }
1295
                    }
1296
                }
1297
                break;
1298
            case 'admin':
1299
                if (api_is_platform_admin()) {
1300
                    Database::delete(
1301
                        $this->tbl_global_agenda,
1302
                        ['id = ?' => $id]
1303
                    );
1304
                }
1305
                break;
1306
        }
1307
    }
1308
1309
    /**
1310
     * Get agenda events.
1311
     *
1312
     * @param int    $start
1313
     * @param int    $end
1314
     * @param int    $courseId
1315
     * @param int    $groupId
1316
     * @param int    $user_id
1317
     * @param string $format
1318
     *
1319
     * @return array|string
1320
     */
1321
    public function getEvents(
1322
        $start,
1323
        $end,
1324
        $courseId = null,
1325
        $groupId = null,
1326
        $user_id = 0,
1327
        $format = 'json'
1328
    ) {
1329
        switch ($this->type) {
1330
            case 'admin':
1331
                $this->getPlatformEvents($start, $end);
1332
                break;
1333
            case 'course':
1334
                $courseInfo = api_get_course_info_by_id($courseId);
1335
1336
                // Session coach can see all events inside a session.
1337
                if (api_is_coach()) {
1338
                    // Own course
1339
                    $this->getCourseEvents(
1340
                        $start,
1341
                        $end,
1342
                        $courseInfo,
1343
                        $groupId,
1344
                        $this->sessionId,
1345
                        $user_id
1346
                    );
1347
1348
                    // Others
1349
                    $this->getSessionEvents(
1350
                        $start,
1351
                        $end,
1352
                        $this->sessionId,
1353
                        $user_id,
1354
                        $this->eventOtherSessionColor
1355
                    );
1356
                } else {
1357
                    $this->getCourseEvents(
1358
                        $start,
1359
                        $end,
1360
                        $courseInfo,
1361
                        $groupId,
1362
                        $this->sessionId,
1363
                        $user_id
1364
                    );
1365
                }
1366
                break;
1367
            case 'personal':
1368
            default:
1369
                $sessionFilterActive = false;
1370
                if (!empty($this->sessionId)) {
1371
                    $sessionFilterActive = true;
1372
                }
1373
1374
                if ($sessionFilterActive == false) {
1375
                    // Getting personal events
1376
                    $this->getPersonalEvents($start, $end);
1377
1378
                    // Getting platform/admin events
1379
                    $this->getPlatformEvents($start, $end);
1380
                }
1381
1382
                $ignoreVisibility = api_get_configuration_value('personal_agenda_show_all_session_events');
1383
1384
                $session_list = [];
1385
                // Getting course events
1386
                $my_course_list = [];
1387
                if (!api_is_anonymous()) {
1388
                    $session_list = SessionManager::get_sessions_by_user(
1389
                        api_get_user_id(),
1390
                        $ignoreVisibility
1391
                    );
1392
                    $my_course_list = CourseManager::get_courses_list_by_user_id(
1393
                        api_get_user_id(),
1394
                        false
1395
                    );
1396
                }
1397
1398
                if (api_is_drh()) {
1399
                    if (api_drh_can_access_all_session_content()) {
1400
                        $session_list = [];
1401
                        $sessionList = SessionManager::get_sessions_followed_by_drh(
1402
                            api_get_user_id(),
1403
                            null,
1404
                            null,
1405
                            null,
1406
                            true,
1407
                            false
1408
                        );
1409
1410
                        if (!empty($sessionList)) {
1411
                            foreach ($sessionList as $sessionItem) {
1412
                                $sessionId = $sessionItem['id'];
1413
                                $courses = SessionManager::get_course_list_by_session_id($sessionId);
1414
                                $sessionInfo = [
1415
                                    'session_id' => $sessionId,
1416
                                    'courses' => $courses,
1417
                                ];
1418
                                $session_list[] = $sessionInfo;
1419
                            }
1420
                        }
1421
                    }
1422
                }
1423
1424
                if (!empty($session_list)) {
1425
                    foreach ($session_list as $session_item) {
1426
                        if ($sessionFilterActive) {
1427
                            if ($this->sessionId != $session_item['session_id']) {
1428
                                continue;
1429
                            }
1430
                        }
1431
1432
                        $my_courses = $session_item['courses'];
1433
                        $my_session_id = $session_item['session_id'];
1434
1435
                        if (!empty($my_courses)) {
1436
                            foreach ($my_courses as $course_item) {
1437
                                $courseInfo = api_get_course_info_by_id(
1438
                                    $course_item['real_id']
1439
                                );
1440
                                $this->getCourseEvents(
1441
                                    $start,
1442
                                    $end,
1443
                                    $courseInfo,
1444
                                    0,
1445
                                    $my_session_id
1446
                                );
1447
                            }
1448
                        }
1449
                    }
1450
                }
1451
1452
                if (!empty($my_course_list) && $sessionFilterActive == false) {
1453
                    foreach ($my_course_list as $courseInfoItem) {
1454
                        $courseInfo = api_get_course_info_by_id(
1455
                            $courseInfoItem['real_id']
1456
                        );
1457
                        if (isset($courseId) && !empty($courseId)) {
1458
                            if ($courseInfo['real_id'] == $courseId) {
1459
                                $this->getCourseEvents(
1460
                                    $start,
1461
                                    $end,
1462
                                    $courseInfo,
1463
                                    0,
1464
                                    0,
1465
                                    $user_id
1466
                                );
1467
                            }
1468
                        } else {
1469
                            $this->getCourseEvents(
1470
                                $start,
1471
                                $end,
1472
                                $courseInfo,
1473
                                0,
1474
                                0,
1475
                                $user_id
1476
                            );
1477
                        }
1478
                    }
1479
                }
1480
1481
                if ($start && $end) {
1482
                    $this->loadSessionsAsEvents($start, $end);
1483
                }
1484
1485
                break;
1486
        }
1487
1488
        if (api_get_configuration_value('agenda_reminders')) {
1489
            $this->events = array_map(
1490
                function (array $eventInfo) {
1491
                    $id = str_replace(['personal_', 'course_', 'session_'], '', $eventInfo['id']);
1492
1493
                    $eventInfo['reminders'] = $this->parseEventReminders(
1494
                        $this->getEventReminders(
1495
                            $id,
1496
                            'session' === $eventInfo['type'] ? 'course' : $eventInfo['type']
1497
                        )
1498
                    );
1499
1500
                    return $eventInfo;
1501
                },
1502
                $this->events
1503
            );
1504
        }
1505
1506
        $this->cleanEvents();
1507
1508
        switch ($format) {
1509
            case 'json':
1510
                if (empty($this->events)) {
1511
                    return '[]';
1512
                }
1513
1514
                return json_encode($this->events);
1515
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

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

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

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

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