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

Agenda::addEvent()   F

Complexity

Conditions 22
Paths 612

Size

Total Lines 211
Code Lines 145

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 22
eloc 145
nc 612
nop 12
dl 0
loc 211
rs 0.4311
c 0
b 0
f 0

How to fix   Long Method    Complexity    Many Parameters   

Long Method

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

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

Commonly applied refactorings include:

Many Parameters

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

There are several approaches to avoid long parameter lists:

1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
/**
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
        $userInfo = api_get_user_info();
4152
        $sessionList = SessionManager::getSessionsFollowedByUser($userInfo['id'], $userInfo['status']);
4153
4154
        foreach ($sessionList as $sessionInfo) {
4155
            if (!empty($sessionInfo['duration'])) {
4156
                $courseAccess = CourseManager::getFirstCourseAccessPerSessionAndUser(
4157
                    $sessionInfo['session_id'],
4158
                    $userInfo['id']
4159
                );
4160
4161
                if (empty($courseAccess)) {
4162
                    continue;
4163
                }
4164
4165
                $firstAccessDate = new DateTime($courseAccess['login_course_date'], new DateTimeZone('UTC'));
4166
                $lastAccessDate = clone $firstAccessDate;
4167
                $lastAccessDate->modify('+'.$sessionInfo['duration'].' days');
4168
4169
                if ($firstAccessDate->format('Y-m-d H:i:s') > $start
4170
                    && $lastAccessDate->format('Y-m-d H:i:s') < $end
4171
                ) {
4172
                    continue;
4173
                }
4174
4175
                $courseList = SessionManager::get_course_list_by_session_id($sessionInfo['id']);
4176
                $firstCourse = current($courseList);
4177
4178
                $this->events[] = [
4179
                    'id' => 'session_'.$sessionInfo['id'],
4180
                    'session_id' => $sessionInfo['id'],
4181
                    'title' => $sessionInfo['name'],
4182
                    'description' => $sessionInfo['show_description'] ? $sessionInfo['description'] : '',
4183
                    'className' => 'personal',
4184
                    'borderColor' => $this->event_personal_color,
4185
                    'backgroundColor' => $this->event_personal_color,
4186
                    'editable' => false,
4187
                    'sent_to' => get_lang('Me'),
4188
                    'type' => 'session',
4189
                    'start' => $firstAccessDate->format(DateTime::ISO8601),
4190
                    'start_date_localtime' => api_get_local_time($firstAccessDate),
4191
                    'end' => $lastAccessDate->format(DateTime::ISO8601),
4192
                    'end_date_localtime' => api_get_local_time($lastAccessDate),
4193
                    'allDay' => 0,
4194
                    'parent_event_id' => 0,
4195
                    'has_children' => 0,
4196
                    'course_url' => api_get_course_url($firstCourse['code'], $sessionInfo['id']),
4197
                ];
4198
4199
                continue;
4200
            }
4201
4202
            if ($sessionInfo['display_start_date'] < $start
4203
                && $sessionInfo['display_end_date'] > $end
4204
            ) {
4205
                continue;
4206
            }
4207
4208
            $courseList = SessionManager::get_course_list_by_session_id($sessionInfo['id']);
4209
            $firstCourse = current($courseList);
4210
4211
            $this->events[] = [
4212
                'id' => 'session_'.$sessionInfo['id'],
4213
                'session_id' => $sessionInfo['id'],
4214
                'title' => $sessionInfo['name'],
4215
                'description' => $sessionInfo['show_description'] ? $sessionInfo['description'] : '',
4216
                'className' => 'personal',
4217
                'borderColor' => $this->event_personal_color,
4218
                'backgroundColor' => $this->event_personal_color,
4219
                'editable' => false,
4220
                'sent_to' => get_lang('Me'),
4221
                'type' => 'session',
4222
                'start' => $sessionInfo['display_start_date'],
4223
                'start_date_localtime' => $sessionInfo['display_start_date']
4224
                    ? $this->formatEventDate($sessionInfo['display_start_date'])
4225
                    : '',
4226
                'end' => $sessionInfo['display_end_date'],
4227
                'end_date_localtime' => $sessionInfo['display_end_date']
4228
                    ? $this->formatEventDate($sessionInfo['display_end_date'])
4229
                    : '',
4230
                'allDay' => 0,
4231
                'parent_event_id' => 0,
4232
                'has_children' => 0,
4233
                'course_url' => api_get_course_url($firstCourse['code'], $sessionInfo['id']),
4234
            ];
4235
        }
4236
    }
4237
}
4238