Passed
Pull Request — 1.11.x (#4093)
by Angel Fernando Quiroz
10:12
created

Agenda::loadSessionsAsEvents()   C

Complexity

Conditions 13

Size

Total Lines 91
Code Lines 69

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
cc 13
eloc 69
c 2
b 1
f 0
nop 2
dl 0
loc 91
rs 5.9696

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

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