Passed
Pull Request — 1.11.x (#4093)
by Angel Fernando Quiroz
11:44
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
    private function loadSessionsAsEvents(int $start, int $end)
1347
    {
1348
        if (false === api_get_configuration_value('personal_calendar_show_sessions_occupation')) {
1349
            return;
1350
        }
1351
1352
        $userInfo = api_get_user_info();
1353
        $sessionList = SessionManager::getSessionsFollowedByUser($userInfo['id'], $userInfo['status']);
1354
1355
        foreach ($sessionList as $sessionInfo) {
1356
            if (!empty($sessionInfo['duration'])) {
1357
                $courseAccess = CourseManager::getFirstCourseAccessPerSessionAndUser(
1358
                    $sessionInfo['session_id'],
1359
                    $userInfo['id']
1360
                );
1361
1362
                if (empty($courseAccess)) {
1363
                    continue;
1364
                }
1365
1366
                $firstAccessDate = new DateTime($courseAccess['login_course_date'], new DateTimeZone('UTC'));
1367
                $lastAccessDate = clone $firstAccessDate;
1368
                $lastAccessDate->modify('+'.$sessionInfo['duration'].' days');
1369
1370
                if ($firstAccessDate->format('Y-m-d H:i:s') > $start
1371
                    && $lastAccessDate->format('Y-m-d H:i:s') < $end
1372
                ) {
1373
                    continue;
1374
                }
1375
1376
                $this->events[] = [
1377
                    'id' => 'session_' . $sessionInfo['id'],
1378
                    'title' => $sessionInfo['name'],
1379
                    'description' => $sessionInfo['show_description'] ? $sessionInfo['description'] : '',
1380
                    'className' => 'personal',
1381
                    'borderColor' => $this->event_personal_color,
1382
                    'backgroundColor' => $this->event_personal_color,
1383
                    'editable' => false,
1384
                    'sent_to' => get_lang('Me'),
1385
                    'type' => 'personal',
1386
                    'start' => $firstAccessDate->format(DateTime::ISO8601),
1387
                    'start_date_localtime' => api_get_local_time($firstAccessDate),
1388
                    'end' => $lastAccessDate->format(DateTime::ISO8601),
1389
                    'end_date_localtime' => api_get_local_time($lastAccessDate),
1390
                    'allDay' => 0,
1391
                    'parent_event_id' => 0,
1392
                    'has_children' => 0,
1393
                ];
1394
1395
                continue;
1396
            }
1397
1398
            if ($sessionInfo['display_start_date'] < $start
1399
                && $sessionInfo['display_end_date'] > $end
1400
            ) {
1401
                continue;
1402
            }
1403
1404
            $this->events[] = [
1405
                'id' => 'session_' . $sessionInfo['id'],
1406
                'title' => $sessionInfo['name'],
1407
                'description' => $sessionInfo['show_description'] ? $sessionInfo['description'] : '',
1408
                'className' => 'personal',
1409
                'borderColor' => $this->event_personal_color,
1410
                'backgroundColor' => $this->event_personal_color,
1411
                'editable' => false,
1412
                'sent_to' => get_lang('Me'),
1413
                'type' => 'personal',
1414
                'start' => $sessionInfo['display_start_date'],
1415
                'start_date_localtime' => $sessionInfo['display_start_date']
1416
                    ? $this->formatEventDate($sessionInfo['display_start_date'])
1417
                    : '',
1418
                'end' => $sessionInfo['display_end_date'],
1419
                'end_date_localtime' => $sessionInfo['display_end_date']
1420
                    ? $this->formatEventDate($sessionInfo['display_end_date'])
1421
                    : '',
1422
                'allDay' => 0,
1423
                'parent_event_id' => 0,
1424
                'has_children' => 0,
1425
            ];
1426
        }
1427
    }
1428
1429
    /**
1430
     * Clean events.
1431
     *
1432
     * @return bool
1433
     */
1434
    public function cleanEvents()
1435
    {
1436
        if (empty($this->events)) {
1437
            return false;
1438
        }
1439
1440
        foreach ($this->events as &$event) {
1441
            $event['description'] = Security::remove_XSS($event['description']);
1442
            $event['title'] = Security::remove_XSS($event['title']);
1443
        }
1444
1445
        return true;
1446
    }
1447
1448
    /**
1449
     * @param int $id
1450
     * @param int $minute_delta
1451
     *
1452
     * @return int
1453
     */
1454
    public function resizeEvent($id, $minute_delta)
1455
    {
1456
        $id = (int) $id;
1457
        $delta = (int) $minute_delta;
1458
        $event = $this->get_event($id);
1459
        if (!empty($event)) {
1460
            switch ($this->type) {
1461
                case 'personal':
1462
                    $sql = "UPDATE $this->tbl_personal_agenda SET
1463
                            enddate = DATE_ADD(enddate, INTERVAL $delta MINUTE)
1464
							WHERE id = ".$id;
1465
                    Database::query($sql);
1466
                    break;
1467
                case 'course':
1468
                    $sql = "UPDATE $this->tbl_course_agenda SET
1469
                            end_date = DATE_ADD(end_date, INTERVAL $delta MINUTE)
1470
							WHERE
1471
							    c_id = ".$this->course['real_id']." AND
1472
							    id = ".$id;
1473
                    Database::query($sql);
1474
                    break;
1475
                case 'admin':
1476
                    $sql = "UPDATE $this->tbl_global_agenda SET
1477
                            end_date = DATE_ADD(end_date, INTERVAL $delta MINUTE)
1478
							WHERE id = ".$id;
1479
                    Database::query($sql);
1480
                    break;
1481
            }
1482
        }
1483
1484
        return 1;
1485
    }
1486
1487
    /**
1488
     * @param int $id
1489
     * @param int $minute_delta minutes
1490
     * @param int $allDay
1491
     *
1492
     * @return int
1493
     */
1494
    public function move_event($id, $minute_delta, $allDay)
1495
    {
1496
        $id = (int) $id;
1497
        $event = $this->get_event($id);
1498
1499
        if (empty($event)) {
1500
            return false;
1501
        }
1502
1503
        // we convert the hour delta into minutes and add the minute delta
1504
        $delta = (int) $minute_delta;
1505
        $allDay = (int) $allDay;
1506
1507
        if (!empty($event)) {
1508
            switch ($this->type) {
1509
                case 'personal':
1510
                    $sql = "UPDATE $this->tbl_personal_agenda SET
1511
                            all_day = $allDay, date = DATE_ADD(date, INTERVAL $delta MINUTE),
1512
                            enddate = DATE_ADD(enddate, INTERVAL $delta MINUTE)
1513
							WHERE id=".$id;
1514
                    Database::query($sql);
1515
                    break;
1516
                case 'course':
1517
                    $sql = "UPDATE $this->tbl_course_agenda SET
1518
                            all_day = $allDay,
1519
                            start_date = DATE_ADD(start_date, INTERVAL $delta MINUTE),
1520
                            end_date = DATE_ADD(end_date, INTERVAL $delta MINUTE)
1521
							WHERE
1522
							    c_id = ".$this->course['real_id']." AND
1523
							    id=".$id;
1524
                    Database::query($sql);
1525
                    break;
1526
                case 'admin':
1527
                    $sql = "UPDATE $this->tbl_global_agenda SET
1528
                            all_day = $allDay,
1529
                            start_date = DATE_ADD(start_date,INTERVAL $delta MINUTE),
1530
                            end_date = DATE_ADD(end_date, INTERVAL $delta MINUTE)
1531
							WHERE id=".$id;
1532
                    Database::query($sql);
1533
                    break;
1534
            }
1535
        }
1536
1537
        return 1;
1538
    }
1539
1540
    /**
1541
     * Gets a single event.
1542
     *
1543
     * @param int $id event id
1544
     *
1545
     * @return array
1546
     */
1547
    public function get_event($id)
1548
    {
1549
        // make sure events of the personal agenda can only be seen by the user himself
1550
        $id = (int) $id;
1551
        $event = null;
1552
        switch ($this->type) {
1553
            case 'personal':
1554
                $sql = "SELECT * FROM ".$this->tbl_personal_agenda."
1555
                        WHERE id = $id AND user = ".api_get_user_id();
1556
                $result = Database::query($sql);
1557
                if (Database::num_rows($result)) {
1558
                    $event = Database::fetch_array($result, 'ASSOC');
1559
                    $event['description'] = $event['text'];
1560
                    $event['content'] = $event['text'];
1561
                    $event['start_date'] = $event['date'];
1562
                    $event['end_date'] = $event['enddate'];
1563
                }
1564
                break;
1565
            case 'course':
1566
                if (!empty($this->course['real_id'])) {
1567
                    $sql = "SELECT * FROM ".$this->tbl_course_agenda."
1568
                            WHERE c_id = ".$this->course['real_id']." AND id = ".$id;
1569
                    $result = Database::query($sql);
1570
                    if (Database::num_rows($result)) {
1571
                        $event = Database::fetch_array($result, 'ASSOC');
1572
                        $event['description'] = $event['content'];
1573
1574
                        // Getting send to array
1575
                        $event['send_to'] = $this->getUsersAndGroupSubscribedToEvent(
1576
                            $id,
1577
                            $this->course['real_id'],
1578
                            $this->sessionId
1579
                        );
1580
1581
                        // Getting repeat info
1582
                        $event['repeat_info'] = $this->getRepeatedInfoByEvent(
1583
                            $id,
1584
                            $this->course['real_id']
1585
                        );
1586
1587
                        if (!empty($event['parent_event_id'])) {
1588
                            $event['parent_info'] = $this->get_event($event['parent_event_id']);
1589
                        }
1590
1591
                        $event['attachment'] = $this->getAttachmentList(
1592
                            $id,
1593
                            $this->course
1594
                        );
1595
                    }
1596
                }
1597
                break;
1598
            case 'admin':
1599
            case 'platform':
1600
                $sql = "SELECT * FROM ".$this->tbl_global_agenda."
1601
                        WHERE id = $id";
1602
                $result = Database::query($sql);
1603
                if (Database::num_rows($result)) {
1604
                    $event = Database::fetch_array($result, 'ASSOC');
1605
                    $event['description'] = $event['content'];
1606
                }
1607
                break;
1608
        }
1609
1610
        return $event;
1611
    }
1612
1613
    /**
1614
     * Gets personal events.
1615
     *
1616
     * @param int $start
1617
     * @param int $end
1618
     *
1619
     * @return array
1620
     */
1621
    public function getPersonalEvents($start, $end)
1622
    {
1623
        $start = (int) $start;
1624
        $end = (int) $end;
1625
        $startCondition = '';
1626
        $endCondition = '';
1627
1628
        if ($start !== 0) {
1629
            $startCondition = "AND date >= '".api_get_utc_datetime($start)."'";
1630
        }
1631
        if ($start !== 0) {
1632
            $endCondition = "AND (enddate <= '".api_get_utc_datetime($end)."' OR enddate IS NULL)";
1633
        }
1634
        $user_id = api_get_user_id();
1635
1636
        $sql = "SELECT * FROM ".$this->tbl_personal_agenda."
1637
                WHERE user = $user_id $startCondition $endCondition";
1638
1639
        $result = Database::query($sql);
1640
        $my_events = [];
1641
        if (Database::num_rows($result)) {
1642
            while ($row = Database::fetch_array($result, 'ASSOC')) {
1643
                $event = [];
1644
                $event['id'] = 'personal_'.$row['id'];
1645
                $event['title'] = $row['title'];
1646
                $event['className'] = 'personal';
1647
                $event['borderColor'] = $event['backgroundColor'] = $this->event_personal_color;
1648
                $event['editable'] = true;
1649
                $event['sent_to'] = get_lang('Me');
1650
                $event['type'] = 'personal';
1651
1652
                if (!empty($row['date'])) {
1653
                    $event['start'] = $this->formatEventDate($row['date']);
1654
                    $event['start_date_localtime'] = api_get_local_time($row['date']);
1655
                }
1656
1657
                if (!empty($row['enddate'])) {
1658
                    $event['end'] = $this->formatEventDate($row['enddate']);
1659
                    $event['end_date_localtime'] = api_get_local_time($row['enddate']);
1660
                }
1661
1662
                $event['description'] = $row['text'];
1663
                $event['allDay'] = isset($row['all_day']) && $row['all_day'] == 1 ? $row['all_day'] : 0;
1664
                $event['parent_event_id'] = 0;
1665
                $event['has_children'] = 0;
1666
1667
                $my_events[] = $event;
1668
                $this->events[] = $event;
1669
            }
1670
        }
1671
1672
        // Add plugin personal events
1673
1674
        $this->plugin = new AppPlugin();
1675
        $plugins = $this->plugin->getInstalledPluginListObject();
1676
        /** @var Plugin $plugin */
1677
        foreach ($plugins as $plugin) {
1678
            if ($plugin->hasPersonalEvents && method_exists($plugin, 'getPersonalEvents')) {
1679
                $pluginEvents = $plugin->getPersonalEvents($this, $start, $end);
1680
1681
                if (!empty($pluginEvents)) {
1682
                    $this->events = array_merge($this->events, $pluginEvents);
1683
                }
1684
            }
1685
        }
1686
1687
        return $my_events;
1688
    }
1689
1690
    /**
1691
     * Get user/group list per event.
1692
     *
1693
     * @param int $eventId
1694
     * @param int $courseId
1695
     * @param int $sessionId
1696
     * @paraù int $sessionId
1697
     *
1698
     * @return array
1699
     */
1700
    public function getUsersAndGroupSubscribedToEvent(
1701
        $eventId,
1702
        $courseId,
1703
        $sessionId
1704
    ) {
1705
        $eventId = (int) $eventId;
1706
        $courseId = (int) $courseId;
1707
        $sessionId = (int) $sessionId;
1708
1709
        $sessionCondition = "ip.session_id = $sessionId";
1710
        if (empty($sessionId)) {
1711
            $sessionCondition = " (ip.session_id = 0 OR ip.session_id IS NULL) ";
1712
        }
1713
1714
        $tlb_course_agenda = Database::get_course_table(TABLE_AGENDA);
1715
        $tbl_property = Database::get_course_table(TABLE_ITEM_PROPERTY);
1716
1717
        // Get sent_tos
1718
        $sql = "SELECT DISTINCT to_user_id, to_group_id
1719
                FROM $tbl_property ip
1720
                INNER JOIN $tlb_course_agenda agenda
1721
                ON (
1722
                  ip.ref = agenda.id AND
1723
                  ip.c_id = agenda.c_id AND
1724
                  ip.tool = '".TOOL_CALENDAR_EVENT."'
1725
                )
1726
                WHERE
1727
                    ref = $eventId AND
1728
                    ip.visibility = '1' AND
1729
                    ip.c_id = $courseId AND
1730
                    $sessionCondition
1731
                ";
1732
1733
        $result = Database::query($sql);
1734
        $users = [];
1735
        $groups = [];
1736
        $everyone = false;
1737
1738
        while ($row = Database::fetch_array($result, 'ASSOC')) {
1739
            if (!empty($row['to_group_id'])) {
1740
                $groups[] = $row['to_group_id'];
1741
            }
1742
            if (!empty($row['to_user_id'])) {
1743
                $users[] = $row['to_user_id'];
1744
            }
1745
1746
            if (empty($groups) && empty($users)) {
1747
                if ($row['to_group_id'] == 0) {
1748
                    $everyone = true;
1749
                }
1750
            }
1751
        }
1752
1753
        return [
1754
            'everyone' => $everyone,
1755
            'users' => $users,
1756
            'groups' => $groups,
1757
        ];
1758
    }
1759
1760
    /**
1761
     * @param int    $start
1762
     * @param int    $end
1763
     * @param int    $sessionId
1764
     * @param int    $userId
1765
     * @param string $color
1766
     *
1767
     * @return array
1768
     */
1769
    public function getSessionEvents(
1770
        $start,
1771
        $end,
1772
        $sessionId = 0,
1773
        $userId = 0,
1774
        $color = ''
1775
    ) {
1776
        $courses = SessionManager::get_course_list_by_session_id($sessionId);
1777
1778
        if (!empty($courses)) {
1779
            foreach ($courses as $course) {
1780
                $this->getCourseEvents(
1781
                    $start,
1782
                    $end,
1783
                    $course,
1784
                    0,
1785
                    $sessionId,
1786
                    0,
1787
                    $color
1788
                );
1789
            }
1790
        }
1791
    }
1792
1793
    /**
1794
     * @param int    $start
1795
     * @param int    $end
1796
     * @param array  $courseInfo
1797
     * @param int    $groupId
1798
     * @param int    $sessionId
1799
     * @param int    $user_id
1800
     * @param string $color
1801
     *
1802
     * @return array
1803
     */
1804
    public function getCourseEvents(
1805
        $start,
1806
        $end,
1807
        $courseInfo,
1808
        $groupId = 0,
1809
        $sessionId = 0,
1810
        $user_id = 0,
1811
        $color = ''
1812
    ) {
1813
        $start = isset($start) && !empty($start) ? api_get_utc_datetime(intval($start)) : null;
1814
        $end = isset($end) && !empty($end) ? api_get_utc_datetime(intval($end)) : null;
1815
1816
        if (empty($courseInfo)) {
1817
            return [];
1818
        }
1819
        $courseId = $courseInfo['real_id'];
1820
1821
        if (empty($courseId)) {
1822
            return [];
1823
        }
1824
1825
        $sessionId = (int) $sessionId;
1826
        $user_id = (int) $user_id;
1827
1828
        $groupList = GroupManager::get_group_list(
1829
            null,
1830
            $courseInfo,
1831
            null,
1832
            $sessionId
1833
        );
1834
1835
        $groupNameList = [];
1836
        if (!empty($groupList)) {
1837
            foreach ($groupList as $group) {
1838
                $groupNameList[$group['iid']] = $group['name'];
1839
            }
1840
        }
1841
1842
        if (api_is_platform_admin() || api_is_allowed_to_edit()) {
1843
            $isAllowToEdit = true;
1844
        } else {
1845
            $isAllowToEdit = CourseManager::is_course_teacher(
1846
                api_get_user_id(),
1847
                $courseInfo['code']
1848
            );
1849
        }
1850
1851
        $isAllowToEditByHrm = false;
1852
        if (!empty($sessionId)) {
1853
            $allowDhrToEdit = api_get_configuration_value('allow_agenda_edit_for_hrm');
1854
            if ($allowDhrToEdit) {
1855
                $isHrm = SessionManager::isUserSubscribedAsHRM($sessionId, api_get_user_id());
1856
                if ($isHrm) {
1857
                    $isAllowToEdit = $isAllowToEditByHrm = true;
1858
                }
1859
            }
1860
        }
1861
1862
        $groupMemberships = [];
1863
        if (!empty($groupId)) {
1864
            $groupMemberships = [$groupId];
1865
        } else {
1866
            if ($isAllowToEdit) {
1867
                if (!empty($groupList)) {
1868
                    // c_item_property.to_group_id field was migrated to use
1869
                    // c_group_info.iid
1870
                    $groupMemberships = array_column($groupList, 'iid');
1871
                }
1872
            } else {
1873
                // get only related groups from user
1874
                $groupMemberships = GroupManager::get_group_ids(
1875
                    $courseId,
1876
                    api_get_user_id()
1877
                );
1878
            }
1879
        }
1880
1881
        $tlb_course_agenda = Database::get_course_table(TABLE_AGENDA);
1882
        $tbl_property = Database::get_course_table(TABLE_ITEM_PROPERTY);
1883
1884
        $shareEventsInSessions = 1 == api_get_course_setting('agenda_share_events_in_sessions', $courseInfo);
1885
1886
        $agendaSessionCondition = str_replace(
1887
            ' AND ',
1888
            '',
1889
            api_get_session_condition($sessionId, true, $shareEventsInSessions, 'agenda.session_id')
1890
        );
1891
        $ipSessionCondition = api_get_session_condition($sessionId, true, $shareEventsInSessions, 'ip.session_id');
1892
1893
        $sessionCondition = "($agendaSessionCondition $ipSessionCondition)";
1894
1895
        if ($isAllowToEdit) {
1896
            // No group filter was asked
1897
            if (empty($groupId)) {
1898
                if (empty($user_id)) {
1899
                    // Show all events not added in group
1900
                    $userCondition = ' (ip.to_group_id IS NULL OR ip.to_group_id = 0) ';
1901
                    // admin see only his stuff
1902
                    if ($this->type === 'personal') {
1903
                        $userCondition = " (ip.to_user_id = ".api_get_user_id()." AND (ip.to_group_id IS NULL OR ip.to_group_id = 0) ) ";
1904
                        $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) ) ";
1905
                    }
1906
1907
                    if (!empty($groupMemberships)) {
1908
                        // Show events sent to selected groups
1909
                        $userCondition .= " OR (ip.to_user_id = 0 OR ip.to_user_id is NULL) AND (ip.to_group_id IN (".implode(", ", $groupMemberships).")) ";
1910
                    }
1911
                } else {
1912
                    // Show events of requested user in no group
1913
                    $userCondition = " (ip.to_user_id = $user_id AND (ip.to_group_id IS NULL OR ip.to_group_id = 0)) ";
1914
                    // Show events sent to selected groups
1915
                    if (!empty($groupMemberships)) {
1916
                        $userCondition .= " OR (ip.to_user_id = $user_id) AND (ip.to_group_id IN (".implode(", ", $groupMemberships).")) ";
1917
                    }
1918
                }
1919
            } else {
1920
                // Show only selected groups (depending of user status)
1921
                $userCondition = " (ip.to_user_id = 0 OR ip.to_user_id is NULL) AND (ip.to_group_id IN (".implode(", ", $groupMemberships).")) ";
1922
1923
                if (!empty($groupMemberships)) {
1924
                    // Show send to $user_id in selected groups
1925
                    $userCondition .= " OR (ip.to_user_id = $user_id) AND (ip.to_group_id IN (".implode(", ", $groupMemberships).")) ";
1926
                }
1927
            }
1928
        } else {
1929
            // No group filter was asked
1930
            if (empty($groupId)) {
1931
                // Show events sent to everyone and no group
1932
                $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) ';
1933
1934
                // Show events sent to selected groups
1935
                if (!empty($groupMemberships)) {
1936
                    $userCondition .= " OR (ip.to_user_id = 0 OR ip.to_user_id is NULL) AND (ip.to_group_id IN (".implode(", ", $groupMemberships)."))) ";
1937
                } else {
1938
                    $userCondition .= " ) ";
1939
                }
1940
                $userCondition .= " OR (ip.to_user_id = ".api_get_user_id()." AND (ip.to_group_id IS NULL OR ip.to_group_id = 0)) ";
1941
            } else {
1942
                if (!empty($groupMemberships)) {
1943
                    // Show send to everyone - and only selected groups
1944
                    $userCondition = " (ip.to_user_id = 0 OR ip.to_user_id is NULL) AND (ip.to_group_id IN (".implode(", ", $groupMemberships).")) ";
1945
                }
1946
            }
1947
1948
            // Show sent to only me and no group
1949
            if (!empty($groupMemberships)) {
1950
                $userCondition .= " OR (ip.to_user_id = ".api_get_user_id().") AND (ip.to_group_id IN (".implode(", ", $groupMemberships).")) ";
1951
            } else {
1952
                // Show sent to only me and selected groups
1953
            }
1954
        }
1955
1956
        if (api_is_allowed_to_edit()) {
1957
            $visibilityCondition = " (ip.visibility IN ('1', '0'))  ";
1958
        } else {
1959
            $visibilityCondition = " (ip.visibility = '1') ";
1960
        }
1961
1962
        $sql = "SELECT DISTINCT
1963
                    agenda.*,
1964
                    ip.visibility,
1965
                    ip.to_group_id,
1966
                    ip.insert_user_id,
1967
                    ip.ref,
1968
                    to_user_id
1969
                FROM $tlb_course_agenda agenda
1970
                INNER JOIN $tbl_property ip
1971
                ON (
1972
                    agenda.id = ip.ref AND
1973
                    agenda.c_id = ip.c_id AND
1974
                    ip.tool = '".TOOL_CALENDAR_EVENT."'
1975
                )
1976
                WHERE
1977
                    $sessionCondition AND
1978
                    ($userCondition) AND
1979
                    $visibilityCondition AND
1980
                    agenda.c_id = $courseId
1981
        ";
1982
        $dateCondition = '';
1983
        if (!empty($start) && !empty($end)) {
1984
            $dateCondition .= "AND (
1985
                 agenda.start_date BETWEEN '".$start."' AND '".$end."' OR
1986
                 agenda.end_date BETWEEN '".$start."' AND '".$end."' OR
1987
                 (
1988
                     agenda.start_date IS NOT NULL AND agenda.end_date IS NOT NULL AND
1989
                     YEAR(agenda.start_date) = YEAR(agenda.end_date) AND
1990
                     MONTH('$start') BETWEEN MONTH(agenda.start_date) AND MONTH(agenda.end_date)
1991
                 )
1992
            )";
1993
        }
1994
1995
        $sql .= $dateCondition;
1996
        $result = Database::query($sql);
1997
1998
        $coachCanEdit = false;
1999
        if (!empty($sessionId)) {
2000
            $coachCanEdit = api_is_coach($sessionId, $courseId) || api_is_platform_admin();
2001
        }
2002
2003
        if (Database::num_rows($result)) {
2004
            $eventsAdded = array_column($this->events, 'unique_id');
2005
            while ($row = Database::fetch_array($result, 'ASSOC')) {
2006
                $event = [];
2007
                $event['id'] = 'course_'.$row['id'];
2008
                $event['unique_id'] = $row['iid'];
2009
                // To avoid doubles
2010
                if (in_array($event['unique_id'], $eventsAdded)) {
2011
                    continue;
2012
                }
2013
2014
                $eventsAdded[] = $event['unique_id'];
2015
                $eventId = $row['ref'];
2016
                $items = $this->getUsersAndGroupSubscribedToEvent(
2017
                    $eventId,
2018
                    $courseId,
2019
                    $this->sessionId
2020
                );
2021
                $group_to_array = $items['groups'];
2022
                $user_to_array = $items['users'];
2023
                $attachmentList = $this->getAttachmentList(
2024
                    $row['id'],
2025
                    $courseInfo
2026
                );
2027
                $event['attachment'] = '';
2028
                if (!empty($attachmentList)) {
2029
                    foreach ($attachmentList as $attachment) {
2030
                        $has_attachment = Display::return_icon(
2031
                            'attachment.gif',
2032
                            get_lang('Attachment')
2033
                        );
2034
                        $user_filename = $attachment['filename'];
2035
                        $url = api_get_path(WEB_CODE_PATH).'calendar/download.php?file='.$attachment['path'].'&course_id='.$courseId.'&'.api_get_cidreq();
2036
                        $event['attachment'] .= $has_attachment.
2037
                            Display::url(
2038
                                $user_filename,
2039
                                $url
2040
                            ).'<br />';
2041
                    }
2042
                }
2043
2044
                $event['title'] = $row['title'];
2045
                $event['className'] = 'course';
2046
                $event['allDay'] = 'false';
2047
                $event['course_id'] = $courseId;
2048
                $event['borderColor'] = $event['backgroundColor'] = $this->event_course_color;
2049
2050
                $sessionInfo = [];
2051
                if (isset($row['session_id']) && !empty($row['session_id'])) {
2052
                    $sessionInfo = api_get_session_info($sessionId);
2053
                    $event['borderColor'] = $event['backgroundColor'] = $this->event_session_color;
2054
                }
2055
2056
                $event['session_name'] = isset($sessionInfo['name']) ? $sessionInfo['name'] : '';
2057
                $event['course_name'] = isset($courseInfo['title']) ? $courseInfo['title'] : '';
2058
2059
                if (isset($row['to_group_id']) && !empty($row['to_group_id'])) {
2060
                    $event['borderColor'] = $event['backgroundColor'] = $this->event_group_color;
2061
                }
2062
2063
                if (!empty($color)) {
2064
                    $event['borderColor'] = $event['backgroundColor'] = $color;
2065
                }
2066
2067
                if (isset($row['color']) && !empty($row['color'])) {
2068
                    $event['borderColor'] = $event['backgroundColor'] = $row['color'];
2069
                }
2070
2071
                $event['editable'] = false;
2072
                if ($this->getIsAllowedToEdit() && $this->type == 'course') {
2073
                    $event['editable'] = true;
2074
                    if (!empty($sessionId)) {
2075
                        if ($coachCanEdit == false) {
2076
                            $event['editable'] = false;
2077
                        }
2078
                        if ($isAllowToEditByHrm) {
2079
                            $event['editable'] = true;
2080
                        }
2081
                        if ($sessionId != $row['session_id']) {
2082
                            $event['editable'] = false;
2083
                        }
2084
                    }
2085
                    // if user is author then he can edit the item
2086
                    if (api_get_user_id() == $row['insert_user_id']) {
2087
                        $event['editable'] = true;
2088
                    }
2089
                }
2090
2091
                if (!empty($row['start_date'])) {
2092
                    $event['start'] = $this->formatEventDate($row['start_date']);
2093
                    $event['start_date_localtime'] = api_get_local_time($row['start_date']);
2094
                }
2095
                if (!empty($row['end_date'])) {
2096
                    $event['end'] = $this->formatEventDate($row['end_date']);
2097
                    $event['end_date_localtime'] = api_get_local_time($row['end_date']);
2098
                }
2099
2100
                $event['sent_to'] = '';
2101
                $event['type'] = 'course';
2102
                if ($row['session_id'] != 0) {
2103
                    $event['type'] = 'session';
2104
                }
2105
2106
                // Event Sent to a group?
2107
                if (isset($row['to_group_id']) && !empty($row['to_group_id'])) {
2108
                    $sent_to = [];
2109
                    if (!empty($group_to_array)) {
2110
                        foreach ($group_to_array as $group_item) {
2111
                            $sent_to[] = $groupNameList[$group_item];
2112
                        }
2113
                    }
2114
                    $sent_to = implode('@@', $sent_to);
2115
                    $sent_to = str_replace(
2116
                        '@@',
2117
                        '</div><div class="label_tag notice">',
2118
                        $sent_to
2119
                    );
2120
                    $event['sent_to'] = '<div class="label_tag notice">'.$sent_to.'</div>';
2121
                    $event['type'] = 'group';
2122
                }
2123
2124
                // Event sent to a user?
2125
                if (isset($row['to_user_id'])) {
2126
                    $sent_to = [];
2127
                    if (!empty($user_to_array)) {
2128
                        foreach ($user_to_array as $item) {
2129
                            $user_info = api_get_user_info($item);
2130
                            // Add username as tooltip for $event['sent_to'] - ref #4226
2131
                            $username = api_htmlentities(
2132
                                sprintf(
2133
                                    get_lang('LoginX'),
2134
                                    $user_info['username']
2135
                                ),
2136
                                ENT_QUOTES
2137
                            );
2138
                            $sent_to[] = "<span title='".$username."'>".$user_info['complete_name']."</span>";
2139
                        }
2140
                    }
2141
                    $sent_to = implode('@@', $sent_to);
2142
                    $sent_to = str_replace(
2143
                        '@@',
2144
                        '</div><div class="label_tag notice">',
2145
                        $sent_to
2146
                    );
2147
                    $event['sent_to'] = '<div class="label_tag notice">'.$sent_to.'</div>';
2148
                }
2149
2150
                //Event sent to everyone!
2151
                if (empty($event['sent_to'])) {
2152
                    $event['sent_to'] = '<div class="label_tag notice">'.get_lang('Everyone').'</div>';
2153
                }
2154
2155
                $event['description'] = Security::remove_XSS($row['content']);
2156
                $event['visibility'] = $row['visibility'];
2157
                $event['real_id'] = $row['id'];
2158
                $event['allDay'] = isset($row['all_day']) && $row['all_day'] == 1 ? $row['all_day'] : 0;
2159
                $event['parent_event_id'] = $row['parent_event_id'];
2160
                $event['has_children'] = $this->hasChildren($row['id'], $courseId) ? 1 : 0;
2161
                $event['comment'] = Security::remove_XSS($row['comment']);
2162
                $this->events[] = $event;
2163
            }
2164
        }
2165
2166
        return $this->events;
2167
    }
2168
2169
    /**
2170
     * @param int $start tms
2171
     * @param int $end   tms
2172
     *
2173
     * @return array
2174
     */
2175
    public function getPlatformEvents($start, $end)
2176
    {
2177
        $start = isset($start) && !empty($start) ? api_get_utc_datetime(intval($start)) : null;
2178
        $end = isset($end) && !empty($end) ? api_get_utc_datetime(intval($end)) : null;
2179
        $dateCondition = '';
2180
2181
        if (!empty($start) && !empty($end)) {
2182
            $dateCondition .= "AND (
2183
                 start_date BETWEEN '".$start."' AND '".$end."' OR
2184
                 end_date BETWEEN '".$start."' AND '".$end."' OR
2185
                 (
2186
                     start_date IS NOT NULL AND end_date IS NOT NULL AND
2187
                     YEAR(start_date) = YEAR(end_date) AND
2188
                     MONTH('$start') BETWEEN MONTH(start_date) AND MONTH(end_date)
2189
                 )
2190
            )";
2191
        }
2192
2193
        $access_url_id = api_get_current_access_url_id();
2194
2195
        $sql = "SELECT *
2196
                FROM ".$this->tbl_global_agenda."
2197
                WHERE access_url_id = $access_url_id
2198
                $dateCondition";
2199
        $result = Database::query($sql);
2200
        $my_events = [];
2201
        if (Database::num_rows($result)) {
2202
            while ($row = Database::fetch_array($result, 'ASSOC')) {
2203
                $event = [];
2204
                $event['id'] = 'platform_'.$row['id'];
2205
                $event['title'] = $row['title'];
2206
                $event['className'] = 'platform';
2207
                $event['allDay'] = 'false';
2208
                $event['borderColor'] = $event['backgroundColor'] = $this->event_platform_color;
2209
                $event['editable'] = false;
2210
                $event['type'] = 'admin';
2211
2212
                if (api_is_platform_admin() && $this->type === 'admin') {
2213
                    $event['editable'] = true;
2214
                }
2215
2216
                if (!empty($row['start_date'])) {
2217
                    $event['start'] = $this->formatEventDate($row['start_date']);
2218
                    $event['start_date_localtime'] = api_get_local_time($row['start_date']);
2219
                }
2220
2221
                if (!empty($row['end_date'])) {
2222
                    $event['end'] = $this->formatEventDate($row['end_date']);
2223
                    $event['end_date_localtime'] = api_get_local_time($row['end_date']);
2224
                }
2225
                $event['allDay'] = isset($row['all_day']) && $row['all_day'] == 1 ? $row['all_day'] : 0;
2226
                $event['parent_event_id'] = 0;
2227
                $event['has_children'] = 0;
2228
                $event['description'] = $row['content'];
2229
2230
                $my_events[] = $event;
2231
                $this->events[] = $event;
2232
            }
2233
        }
2234
2235
        return $my_events;
2236
    }
2237
2238
    /**
2239
     * @param FormValidator $form
2240
     * @param array         $groupList
2241
     * @param array         $userList
2242
     * @param array         $sendTo               array('users' => [1, 2], 'groups' => [3, 4])
2243
     * @param array         $attributes
2244
     * @param bool          $addOnlyItemsInSendTo
2245
     * @param bool          $required
2246
     */
2247
    public function setSendToSelect(
2248
        $form,
2249
        $groupList = [],
2250
        $userList = [],
2251
        $sendTo = [],
2252
        $attributes = [],
2253
        $addOnlyItemsInSendTo = false,
2254
        $required = false
2255
    ) {
2256
        $params = [
2257
            'id' => 'users_to_send_id',
2258
            'data-placeholder' => get_lang('Select'),
2259
            'multiple' => 'multiple',
2260
            'class' => 'multiple-select',
2261
        ];
2262
2263
        if (!empty($attributes)) {
2264
            $params = array_merge($params, $attributes);
2265
            if (empty($params['multiple'])) {
2266
                unset($params['multiple']);
2267
            }
2268
        }
2269
2270
        $sendToGroups = isset($sendTo['groups']) ? $sendTo['groups'] : [];
2271
        $sendToUsers = isset($sendTo['users']) ? $sendTo['users'] : [];
2272
2273
        /** @var HTML_QuickForm_select $select */
2274
        $select = $form->addSelect(
2275
            'users_to_send',
2276
            get_lang('To'),
2277
            null,
2278
            $params
2279
        );
2280
2281
        if ($required) {
2282
            $form->setRequired($select);
2283
        }
2284
2285
        $selectedEveryoneOptions = [];
2286
        if (isset($sendTo['everyone']) && $sendTo['everyone']) {
2287
            $selectedEveryoneOptions = ['selected'];
2288
            $sendToUsers = [];
2289
        }
2290
2291
        $select->addOption(
2292
            get_lang('Everyone'),
2293
            'everyone',
2294
            $selectedEveryoneOptions
2295
        );
2296
2297
        $options = [];
2298
        if (is_array($groupList)) {
2299
            foreach ($groupList as $group) {
2300
                $count_users = isset($group['count_users']) ? $group['count_users'] : $group['userNb'];
2301
                $count_users = " &ndash; $count_users ".get_lang('Users');
2302
                $option = [
2303
                    'text' => $group['name'].$count_users,
2304
                    'value' => "GROUP:".$group['id'],
2305
                ];
2306
                $selected = in_array(
2307
                    $group['id'],
2308
                    $sendToGroups
2309
                ) ? true : false;
2310
                if ($selected) {
2311
                    $option['selected'] = 'selected';
2312
                }
2313
2314
                if ($addOnlyItemsInSendTo) {
2315
                    if ($selected) {
2316
                        $options[] = $option;
2317
                    }
2318
                } else {
2319
                    $options[] = $option;
2320
                }
2321
            }
2322
            $select->addOptGroup($options, get_lang('Groups'));
2323
        }
2324
2325
        // adding the individual users to the select form
2326
        if (is_array($userList)) {
2327
            $options = [];
2328
            foreach ($userList as $user) {
2329
                if ($user['status'] == ANONYMOUS) {
2330
                    continue;
2331
                }
2332
                $option = [
2333
                    'text' => api_get_person_name(
2334
                            $user['firstname'],
2335
                            $user['lastname']
2336
                        ).' ('.$user['username'].')',
2337
                    'value' => "USER:".$user['user_id'],
2338
                ];
2339
2340
                $selected = in_array(
2341
                    $user['user_id'],
2342
                    $sendToUsers
2343
                ) ? true : false;
2344
2345
                if ($selected) {
2346
                    $option['selected'] = 'selected';
2347
                }
2348
2349
                if ($addOnlyItemsInSendTo) {
2350
                    if ($selected) {
2351
                        $options[] = $option;
2352
                    }
2353
                } else {
2354
                    $options[] = $option;
2355
                }
2356
            }
2357
2358
            $select->addOptGroup($options, get_lang('Users'));
2359
        }
2360
    }
2361
2362
    /**
2363
     * Separates the users and groups array
2364
     * users have a value USER:XXX (with XXX the user id
2365
     * groups have a value GROUP:YYY (with YYY the group id)
2366
     * use the 'everyone' key.
2367
     *
2368
     * @author Julio Montoya based in separate_users_groups in agenda.inc.php
2369
     *
2370
     * @param array $to
2371
     *
2372
     * @return array
2373
     */
2374
    public function parseSendToArray($to)
2375
    {
2376
        $groupList = [];
2377
        $userList = [];
2378
        $sendTo = null;
2379
2380
        $sendTo['everyone'] = false;
2381
        if (is_array($to) && count($to) > 0) {
2382
            foreach ($to as $item) {
2383
                if ($item == 'everyone') {
2384
                    $sendTo['everyone'] = true;
2385
                } else {
2386
                    list($type, $id) = explode(':', $item);
2387
                    switch ($type) {
2388
                        case 'GROUP':
2389
                            $groupList[] = $id;
2390
                            break;
2391
                        case 'USER':
2392
                            $userList[] = $id;
2393
                            break;
2394
                    }
2395
                }
2396
            }
2397
            $sendTo['groups'] = $groupList;
2398
            $sendTo['users'] = $userList;
2399
        }
2400
2401
        return $sendTo;
2402
    }
2403
2404
    /**
2405
     * @param array $params
2406
     *
2407
     * @return FormValidator
2408
     */
2409
    public function getForm($params = [])
2410
    {
2411
        $action = isset($params['action']) ? Security::remove_XSS($params['action']) : null;
2412
        $id = isset($params['id']) ? (int) $params['id'] : 0;
2413
2414
        $url = api_get_self().'?action='.$action.'&id='.$id.'&type='.$this->type;
2415
        if ($this->type == 'course') {
2416
            $url = api_get_self().'?'.api_get_cidreq().'&action='.$action.'&id='.$id.'&type='.$this->type;
2417
        }
2418
2419
        $form = new FormValidator(
2420
            'add_event',
2421
            'post',
2422
            $url,
2423
            null,
2424
            ['enctype' => 'multipart/form-data']
2425
        );
2426
2427
        $idAttach = isset($params['id_attach']) ? (int) $params['id_attach'] : null;
2428
        $groupId = api_get_group_id();
2429
        $form_Title = get_lang('AddCalendarItem');
2430
        if (!empty($id)) {
2431
            $form_Title = get_lang('ModifyCalendarItem');
2432
        }
2433
2434
        $form->addHeader($form_Title);
2435
        $form->addElement('hidden', 'id', $id);
2436
        $form->addElement('hidden', 'action', $action);
2437
        $form->addElement('hidden', 'id_attach', $idAttach);
2438
2439
        $isSubEventEdition = false;
2440
        $isParentFromSerie = false;
2441
        $showAttachmentForm = true;
2442
2443
        if ($this->type == 'course') {
2444
            // Edition mode.
2445
            if (!empty($id)) {
2446
                $showAttachmentForm = false;
2447
                if (isset($params['parent_event_id']) && !empty($params['parent_event_id'])) {
2448
                    $isSubEventEdition = true;
2449
                }
2450
                if (!empty($params['repeat_info'])) {
2451
                    $isParentFromSerie = true;
2452
                }
2453
            }
2454
        }
2455
2456
        if ($isSubEventEdition) {
2457
            $form->addElement(
2458
                'label',
2459
                null,
2460
                Display::return_message(
2461
                    get_lang('EditingThisEventWillRemoveItFromTheSerie'),
2462
                    'warning'
2463
                )
2464
            );
2465
        }
2466
2467
        $form->addElement('text', 'title', get_lang('ItemTitle'));
2468
2469
        if (isset($groupId) && !empty($groupId)) {
2470
            $form->addElement(
2471
                'hidden',
2472
                'users_to_send[]',
2473
                "GROUP:$groupId"
2474
            );
2475
            $form->addElement('hidden', 'to', 'true');
2476
        } else {
2477
            $sendTo = isset($params['send_to']) ? $params['send_to'] : ['everyone' => true];
2478
            if ($this->type == 'course') {
2479
                $this->showToForm($form, $sendTo, [], false, true);
2480
            }
2481
        }
2482
2483
        $form->addDateRangePicker(
2484
            'date_range',
2485
            get_lang('DateRange'),
2486
            false,
2487
            ['id' => 'date_range']
2488
        );
2489
        $form->addElement('checkbox', 'all_day', null, get_lang('AllDay'));
2490
2491
        if ($this->type == 'course') {
2492
            $repeat = $form->addElement(
2493
                'checkbox',
2494
                'repeat',
2495
                null,
2496
                get_lang('RepeatEvent'),
2497
                ['onclick' => 'return plus_repeated_event();']
2498
            );
2499
            $form->addElement(
2500
                'html',
2501
                '<div id="options2" style="display:none">'
2502
            );
2503
            $form->addElement(
2504
                'select',
2505
                'repeat_type',
2506
                get_lang('RepeatType'),
2507
                self::getRepeatTypes()
2508
            );
2509
            $form->addElement(
2510
                'date_picker',
2511
                'repeat_end_day',
2512
                get_lang('RepeatEnd'),
2513
                ['id' => 'repeat_end_date_form']
2514
            );
2515
2516
            if ($isSubEventEdition || $isParentFromSerie) {
2517
                $repeatInfo = $params['repeat_info'];
2518
                if ($isSubEventEdition) {
2519
                    $parentEvent = $params['parent_info'];
2520
                    $repeatInfo = $parentEvent['repeat_info'];
2521
                }
2522
                $params['repeat'] = 1;
2523
                $params['repeat_type'] = $repeatInfo['cal_type'];
2524
                $params['repeat_end_day'] = substr(
2525
                    api_get_local_time($repeatInfo['cal_end']),
2526
                    0,
2527
                    10
2528
                );
2529
2530
                $form->freeze(['repeat_type', 'repeat_end_day']);
2531
                $repeat->_attributes['disabled'] = 'disabled';
2532
            }
2533
            $form->addElement('html', '</div>');
2534
        }
2535
2536
        if (!empty($id)) {
2537
            if (empty($params['end_date'])) {
2538
                $params['date_range'] = $params['end_date'];
2539
            }
2540
2541
            $params['date_range'] =
2542
                substr(api_get_local_time($params['start_date']), 0, 16).' / '.
2543
                substr(api_get_local_time($params['end_date']), 0, 16);
2544
        }
2545
2546
        $toolbar = 'Agenda';
2547
        if (!api_is_allowed_to_edit(null, true)) {
2548
            $toolbar = 'AgendaStudent';
2549
        }
2550
2551
        $form->addElement(
2552
            'html_editor',
2553
            'content',
2554
            get_lang('Description'),
2555
            null,
2556
            [
2557
                'ToolbarSet' => $toolbar,
2558
                'Width' => '100%',
2559
                'Height' => '200',
2560
            ]
2561
        );
2562
2563
        if ($this->type == 'course') {
2564
            $form->addElement('textarea', 'comment', get_lang('Comment'));
2565
            $form->addLabel(
2566
                get_lang('FilesAttachment'),
2567
                '<div id="filepaths" class="file-upload-event">
2568
2569
                        <div id="filepath_1">
2570
                            <input type="file" name="attach_1"/>
2571
2572
                            <label>'.get_lang('Description').'</label>
2573
                            <input class="form-control" type="text" name="legend[]" />
2574
                        </div>
2575
2576
                    </div>'
2577
            );
2578
2579
            $form->addLabel(
2580
                '',
2581
                '<span id="link-more-attach">
2582
                    <a href="javascript://" onclick="return add_image_form()">'.
2583
                get_lang('AddOneMoreFile').'</a>
2584
                 </span>&nbsp;('.sprintf(
2585
                    get_lang('MaximunFileSizeX'),
2586
                    format_file_size(
2587
                        api_get_setting('message_max_upload_filesize')
2588
                    )
2589
                ).')'
2590
            );
2591
2592
            if (isset($params['attachment']) && !empty($params['attachment'])) {
2593
                $attachmentList = $params['attachment'];
2594
                foreach ($attachmentList as $attachment) {
2595
                    $params['file_comment'] = $attachment['comment'];
2596
                    if (!empty($attachment['path'])) {
2597
                        $form->addElement(
2598
                            'checkbox',
2599
                            'delete_attachment['.$attachment['id'].']',
2600
                            null,
2601
                            get_lang(
2602
                                'DeleteAttachment'
2603
                            ).': '.$attachment['filename']
2604
                        );
2605
                    }
2606
                }
2607
            }
2608
2609
            $form->addElement(
2610
                'textarea',
2611
                'file_comment',
2612
                get_lang('FileComment')
2613
            );
2614
        }
2615
2616
        if (empty($id)) {
2617
            $form->addElement(
2618
                'checkbox',
2619
                'add_announcement',
2620
                null,
2621
                get_lang('AddAnnouncement').'&nbsp('.get_lang('SendMail').')'
2622
            );
2623
        }
2624
2625
        if ($id) {
2626
            $form->addButtonUpdate(get_lang('ModifyEvent'));
2627
        } else {
2628
            $form->addButtonSave(get_lang('AgendaAdd'));
2629
        }
2630
2631
        $form->setDefaults($params);
2632
        $form->addRule(
2633
            'date_range',
2634
            get_lang('ThisFieldIsRequired'),
2635
            'required'
2636
        );
2637
        $form->addRule('title', get_lang('ThisFieldIsRequired'), 'required');
2638
2639
        return $form;
2640
    }
2641
2642
    /**
2643
     * @param FormValidator $form
2644
     * @param array         $sendTo               array('everyone' => false, 'users' => [1, 2], 'groups' => [3, 4])
2645
     * @param array         $attributes
2646
     * @param bool          $addOnlyItemsInSendTo
2647
     * @param bool          $required
2648
     *
2649
     * @return bool
2650
     */
2651
    public function showToForm(
2652
        $form,
2653
        $sendTo = [],
2654
        $attributes = [],
2655
        $addOnlyItemsInSendTo = false,
2656
        $required = false
2657
    ) {
2658
        if ($this->type != 'course') {
2659
            return false;
2660
        }
2661
2662
        $order = 'lastname';
2663
        if (api_is_western_name_order()) {
2664
            $order = 'firstname';
2665
        }
2666
2667
        $userList = CourseManager::get_user_list_from_course_code(
2668
            api_get_course_id(),
2669
            $this->sessionId,
2670
            null,
2671
            $order
2672
        );
2673
2674
        $groupList = CourseManager::get_group_list_of_course(
2675
            api_get_course_id(),
2676
            $this->sessionId
2677
        );
2678
2679
        $this->setSendToSelect(
2680
            $form,
2681
            $groupList,
2682
            $userList,
2683
            $sendTo,
2684
            $attributes,
2685
            $addOnlyItemsInSendTo,
2686
            $required
2687
        );
2688
2689
        return true;
2690
    }
2691
2692
    /**
2693
     * @param int   $id
2694
     * @param int   $visibility 0= invisible, 1 visible
2695
     * @param array $courseInfo
2696
     * @param int   $userId
2697
     */
2698
    public static function changeVisibility(
2699
        $id,
2700
        $visibility,
2701
        $courseInfo,
2702
        $userId = null
2703
    ) {
2704
        $id = intval($id);
2705
        if (empty($userId)) {
2706
            $userId = api_get_user_id();
2707
        } else {
2708
            $userId = intval($userId);
2709
        }
2710
2711
        if ($visibility == 0) {
2712
            api_item_property_update(
2713
                $courseInfo,
2714
                TOOL_CALENDAR_EVENT,
2715
                $id,
2716
                'invisible',
2717
                $userId
2718
            );
2719
        } else {
2720
            api_item_property_update(
2721
                $courseInfo,
2722
                TOOL_CALENDAR_EVENT,
2723
                $id,
2724
                'visible',
2725
                $userId
2726
            );
2727
        }
2728
    }
2729
2730
    /**
2731
     * Get repeat types.
2732
     *
2733
     * @return array
2734
     */
2735
    public static function getRepeatTypes()
2736
    {
2737
        return [
2738
            'daily' => get_lang('RepeatDaily'),
2739
            'weekly' => get_lang('RepeatWeekly'),
2740
            'monthlyByDate' => get_lang('RepeatMonthlyByDate'),
2741
            //monthlyByDay"> get_lang('RepeatMonthlyByDay');
2742
            //monthlyByDayR' => get_lang('RepeatMonthlyByDayR'),
2743
            'yearly' => get_lang('RepeatYearly'),
2744
        ];
2745
    }
2746
2747
    /**
2748
     * Show a list with all the attachments according to the post's id.
2749
     *
2750
     * @param int   $eventId
2751
     * @param array $courseInfo
2752
     *
2753
     * @return array with the post info
2754
     */
2755
    public function getAttachmentList($eventId, $courseInfo)
2756
    {
2757
        $tableAttachment = Database::get_course_table(TABLE_AGENDA_ATTACHMENT);
2758
        $courseId = (int) $courseInfo['real_id'];
2759
        $eventId = (int) $eventId;
2760
2761
        $sql = "SELECT id, path, filename, comment
2762
                FROM $tableAttachment
2763
                WHERE
2764
                    c_id = $courseId AND
2765
                    agenda_id = $eventId";
2766
        $result = Database::query($sql);
2767
        $list = [];
2768
        if (Database::num_rows($result) != 0) {
2769
            $list = Database::store_result($result, 'ASSOC');
2770
        }
2771
2772
        return $list;
2773
    }
2774
2775
    /**
2776
     * Show a list with all the attachments according to the post's id.
2777
     *
2778
     * @param int   $attachmentId
2779
     * @param int   $eventId
2780
     * @param array $courseInfo
2781
     *
2782
     * @return array with the post info
2783
     */
2784
    public function getAttachment($attachmentId, $eventId, $courseInfo)
2785
    {
2786
        if (empty($courseInfo) || empty($attachmentId) || empty($eventId)) {
2787
            return [];
2788
        }
2789
2790
        $tableAttachment = Database::get_course_table(TABLE_AGENDA_ATTACHMENT);
2791
        $courseId = (int) $courseInfo['real_id'];
2792
        $eventId = (int) $eventId;
2793
        $attachmentId = (int) $attachmentId;
2794
2795
        $row = [];
2796
        $sql = "SELECT id, path, filename, comment
2797
                FROM $tableAttachment
2798
                WHERE
2799
                    c_id = $courseId AND
2800
                    agenda_id = $eventId AND
2801
                    id = $attachmentId
2802
                ";
2803
        $result = Database::query($sql);
2804
        if (Database::num_rows($result) != 0) {
2805
            $row = Database::fetch_array($result, 'ASSOC');
2806
        }
2807
2808
        return $row;
2809
    }
2810
2811
    /**
2812
     * Add an attachment file into agenda.
2813
     *
2814
     * @param int    $eventId
2815
     * @param array  $fileUserUpload ($_FILES['user_upload'])
2816
     * @param string $comment        about file
2817
     * @param array  $courseInfo
2818
     *
2819
     * @return string
2820
     */
2821
    public function addAttachment(
2822
        $eventId,
2823
        $fileUserUpload,
2824
        $comment,
2825
        $courseInfo
2826
    ) {
2827
        $agenda_table_attachment = Database::get_course_table(TABLE_AGENDA_ATTACHMENT);
2828
        $eventId = (int) $eventId;
2829
2830
        // Storing the attachments
2831
        $upload_ok = false;
2832
        if (!empty($fileUserUpload['name'])) {
2833
            $upload_ok = process_uploaded_file($fileUserUpload);
2834
        }
2835
2836
        if (!empty($upload_ok)) {
2837
            $courseDir = $courseInfo['directory'].'/upload/calendar';
2838
            $sys_course_path = api_get_path(SYS_COURSE_PATH);
2839
            $uploadDir = $sys_course_path.$courseDir;
2840
2841
            // Try to add an extension to the file if it hasn't one
2842
            $new_file_name = add_ext_on_mime(
2843
                stripslashes($fileUserUpload['name']),
2844
                $fileUserUpload['type']
2845
            );
2846
2847
            // user's file name
2848
            $file_name = $fileUserUpload['name'];
2849
2850
            if (!filter_extension($new_file_name)) {
2851
                return Display::return_message(
2852
                    get_lang('UplUnableToSaveFileFilteredExtension'),
2853
                    'error'
2854
                );
2855
            } else {
2856
                $new_file_name = uniqid('');
2857
                $new_path = $uploadDir.'/'.$new_file_name;
2858
                $result = @move_uploaded_file(
2859
                    $fileUserUpload['tmp_name'],
2860
                    $new_path
2861
                );
2862
                $courseId = api_get_course_int_id();
2863
                $size = intval($fileUserUpload['size']);
2864
                // Storing the attachments if any
2865
                if ($result) {
2866
                    $params = [
2867
                        'c_id' => $courseId,
2868
                        'filename' => $file_name,
2869
                        'comment' => $comment,
2870
                        'path' => $new_file_name,
2871
                        'agenda_id' => $eventId,
2872
                        'size' => $size,
2873
                    ];
2874
                    $id = Database::insert($agenda_table_attachment, $params);
2875
                    if ($id) {
2876
                        $sql = "UPDATE $agenda_table_attachment
2877
                                SET id = iid WHERE iid = $id";
2878
                        Database::query($sql);
2879
2880
                        api_item_property_update(
2881
                            $courseInfo,
2882
                            'calendar_event_attachment',
2883
                            $id,
2884
                            'AgendaAttachmentAdded',
2885
                            api_get_user_id()
2886
                        );
2887
                    }
2888
                }
2889
            }
2890
        }
2891
    }
2892
2893
    /**
2894
     * @param int    $attachmentId
2895
     * @param int    $eventId
2896
     * @param array  $fileUserUpload
2897
     * @param string $comment
2898
     * @param array  $courseInfo
2899
     */
2900
    public function updateAttachment(
2901
        $attachmentId,
2902
        $eventId,
2903
        $fileUserUpload,
2904
        $comment,
2905
        $courseInfo
2906
    ) {
2907
        $attachment = $this->getAttachment(
2908
            $attachmentId,
2909
            $eventId,
2910
            $courseInfo
2911
        );
2912
        if (!empty($attachment)) {
2913
            $this->deleteAttachmentFile($attachmentId, $courseInfo);
2914
        }
2915
        $this->addAttachment($eventId, $fileUserUpload, $comment, $courseInfo);
2916
    }
2917
2918
    /**
2919
     * This function delete a attachment file by id.
2920
     *
2921
     * @param int   $attachmentId
2922
     * @param array $courseInfo
2923
     *
2924
     * @return string
2925
     */
2926
    public function deleteAttachmentFile($attachmentId, $courseInfo)
2927
    {
2928
        $table = Database::get_course_table(TABLE_AGENDA_ATTACHMENT);
2929
        $attachmentId = (int) $attachmentId;
2930
        $courseId = $courseInfo['real_id'];
2931
2932
        if (empty($courseId) || empty($attachmentId)) {
2933
            return false;
2934
        }
2935
2936
        $sql = "DELETE FROM $table
2937
                WHERE c_id = $courseId AND id = ".$attachmentId;
2938
        $result = Database::query($sql);
2939
2940
        // update item_property
2941
        api_item_property_update(
2942
            $courseInfo,
2943
            'calendar_event_attachment',
2944
            $attachmentId,
2945
            'AgendaAttachmentDeleted',
2946
            api_get_user_id()
2947
        );
2948
2949
        if (!empty($result)) {
2950
            return Display::return_message(
2951
                get_lang("AttachmentFileDeleteSuccess"),
2952
                'confirmation'
2953
            );
2954
        }
2955
    }
2956
2957
    /**
2958
     * @param int $eventId
2959
     *
2960
     * @return array
2961
     */
2962
    public function getAllRepeatEvents($eventId)
2963
    {
2964
        $events = [];
2965
        $eventId = (int) $eventId;
2966
2967
        switch ($this->type) {
2968
            case 'personal':
2969
                break;
2970
            case 'course':
2971
                if (!empty($this->course['real_id'])) {
2972
                    $sql = "SELECT * FROM ".$this->tbl_course_agenda."
2973
                            WHERE
2974
                                c_id = ".$this->course['real_id']." AND
2975
                                parent_event_id = ".$eventId;
2976
                    $result = Database::query($sql);
2977
                    if (Database::num_rows($result)) {
2978
                        while ($row = Database::fetch_array($result, 'ASSOC')) {
2979
                            $events[] = $row;
2980
                        }
2981
                    }
2982
                }
2983
                break;
2984
        }
2985
2986
        return $events;
2987
    }
2988
2989
    /**
2990
     * @param int $eventId
2991
     * @param int $courseId
2992
     *
2993
     * @return bool
2994
     */
2995
    public function hasChildren($eventId, $courseId)
2996
    {
2997
        $eventId = (int) $eventId;
2998
        $courseId = (int) $courseId;
2999
3000
        $sql = "SELECT count(DISTINCT(id)) as count
3001
                FROM ".$this->tbl_course_agenda."
3002
                WHERE
3003
                    c_id = $courseId AND
3004
                    parent_event_id = $eventId";
3005
        $result = Database::query($sql);
3006
        if (Database::num_rows($result)) {
3007
            $row = Database::fetch_array($result, 'ASSOC');
3008
3009
            return $row['count'] > 0;
3010
        }
3011
3012
        return false;
3013
    }
3014
3015
    /**
3016
     * @param int    $filter
3017
     * @param string $view
3018
     *
3019
     * @return string
3020
     */
3021
    public function displayActions($view, $filter = 0)
3022
    {
3023
        $groupInfo = GroupManager::get_group_properties(api_get_group_id());
3024
        $groupIid = isset($groupInfo['iid']) ? $groupInfo['iid'] : 0;
3025
3026
        $codePath = api_get_path(WEB_CODE_PATH);
3027
3028
        $currentUserId = api_get_user_id();
3029
        $cidReq = api_get_cidreq();
3030
3031
        $actionsLeft = '';
3032
        $actionsLeft .= Display::url(
3033
            Display::return_icon('calendar.png', get_lang('Calendar'), [], ICON_SIZE_MEDIUM),
3034
            $codePath."calendar/agenda_js.php?type={$this->type}&$cidReq"
3035
        );
3036
        $actionsLeft .= Display::url(
3037
            Display::return_icon('week.png', get_lang('AgendaList'), [], ICON_SIZE_MEDIUM),
3038
            $codePath."calendar/agenda_list.php?type={$this->type}&$cidReq"
3039
        );
3040
3041
        $form = '';
3042
        if (api_is_allowed_to_edit(false, true) ||
3043
            ('personal' === $this->type && !api_is_anonymous() && 'true' === api_get_setting('allow_personal_agenda')) ||
3044
            (
3045
                '1' === api_get_course_setting('allow_user_edit_agenda') && !api_is_anonymous() &&
3046
                api_is_allowed_to_session_edit(false, true))
3047
            || (
3048
                GroupManager::user_has_access($currentUserId, $groupIid, GroupManager::GROUP_TOOL_CALENDAR)
3049
                && GroupManager::is_tutor_of_group($currentUserId, $groupInfo)
3050
            )
3051
        ) {
3052
            $actionsLeft .= Display::url(
3053
                Display::return_icon('new_event.png', get_lang('AgendaAdd'), [], ICON_SIZE_MEDIUM),
3054
                $codePath."calendar/agenda.php?action=add&type={$this->type}&$cidReq"
3055
            );
3056
3057
            $actionsLeft .= Display::url(
3058
                Display::return_icon('import_calendar.png', get_lang('ICalFileImport'), [], ICON_SIZE_MEDIUM),
3059
                $codePath."calendar/agenda.php?action=importical&type={$this->type}&$cidReq"
3060
            );
3061
3062
            if ($this->type === 'course') {
3063
                if (!isset($_GET['action'])) {
3064
                    $form = new FormValidator(
3065
                        'form-search',
3066
                        'post',
3067
                        '',
3068
                        '',
3069
                        [],
3070
                        FormValidator::LAYOUT_INLINE
3071
                    );
3072
                    $attributes = [
3073
                        'multiple' => false,
3074
                        'id' => 'select_form_id_search',
3075
                    ];
3076
                    $selectedValues = $this->parseAgendaFilter($filter);
3077
                    $this->showToForm($form, $selectedValues, $attributes);
3078
                    $form = $form->returnForm();
3079
                }
3080
            }
3081
        }
3082
3083
        if ($this->type === 'personal' && !api_is_anonymous()) {
3084
            $actionsLeft .= Display::url(
3085
                Display::return_icon('1day.png', get_lang('SessionsPlanCalendar'), [], ICON_SIZE_MEDIUM),
3086
                $codePath.'calendar/planification.php'
3087
            );
3088
3089
            if (api_is_student_boss() || api_is_platform_admin()) {
3090
                $actionsLeft .= Display::url(
3091
                    Display::return_icon('calendar-user.png', get_lang('MyStudentsSchedule'), [], ICON_SIZE_MEDIUM),
3092
                    $codePath.'mySpace/calendar_plan.php'
3093
                );
3094
            }
3095
        }
3096
3097
        if (api_is_platform_admin() ||
3098
            api_is_teacher() ||
3099
            api_is_student_boss() ||
3100
            api_is_drh() ||
3101
            api_is_session_admin() ||
3102
            api_is_coach()
3103
        ) {
3104
            if ($this->type == 'personal') {
3105
                $form = null;
3106
                if (!isset($_GET['action'])) {
3107
                    $form = new FormValidator(
3108
                        'form-search',
3109
                        'get',
3110
                        api_get_self().'?type=personal&',
3111
                        '',
3112
                        [],
3113
                        FormValidator::LAYOUT_INLINE
3114
                    );
3115
3116
                    $sessions = [];
3117
3118
                    if (api_is_drh()) {
3119
                        $sessionList = SessionManager::get_sessions_followed_by_drh($currentUserId);
3120
                        if (!empty($sessionList)) {
3121
                            foreach ($sessionList as $sessionItem) {
3122
                                $sessions[$sessionItem['id']] = strip_tags($sessionItem['name']);
3123
                            }
3124
                        }
3125
                    } else {
3126
                        $sessions = SessionManager::get_sessions_by_user($currentUserId);
3127
                        $sessions = array_column($sessions, 'session_name', 'session_id');
3128
                    }
3129
3130
                    $form->addHidden('type', 'personal');
3131
                    $sessions = ['0' => get_lang('SelectAnOption')] + $sessions;
3132
3133
                    $form->addSelect(
3134
                        'session_id',
3135
                        get_lang('Session'),
3136
                        $sessions,
3137
                        ['id' => 'session_id', 'onchange' => 'submit();']
3138
                    );
3139
3140
                    $form->addButtonReset(get_lang('Reset'));
3141
                    $form = $form->returnForm();
3142
                }
3143
            }
3144
        }
3145
3146
        $actionsRight = '';
3147
        if ($view == 'calendar') {
3148
            $actionsRight .= $form;
3149
        }
3150
3151
        $toolbar = Display::toolbarAction(
3152
            'toolbar-agenda',
3153
            [$actionsLeft, $actionsRight]
3154
        );
3155
3156
        return $toolbar;
3157
    }
3158
3159
    /**
3160
     * @return FormValidator
3161
     */
3162
    public function getImportCalendarForm()
3163
    {
3164
        $form = new FormValidator(
3165
            'frm_import_ical',
3166
            'post',
3167
            api_get_self().'?action=importical&type='.$this->type,
3168
            ['enctype' => 'multipart/form-data']
3169
        );
3170
        $form->addHeader(get_lang('ICalFileImport'));
3171
        $form->addElement('file', 'ical_import', get_lang('ICalFileImport'));
3172
        $form->addRule(
3173
            'ical_import',
3174
            get_lang('ThisFieldIsRequired'),
3175
            'required'
3176
        );
3177
        $form->addButtonImport(get_lang('Import'), 'ical_submit');
3178
3179
        return $form;
3180
    }
3181
3182
    /**
3183
     * @param array $courseInfo
3184
     * @param $file
3185
     *
3186
     * @return false|string
3187
     */
3188
    public function importEventFile($courseInfo, $file)
3189
    {
3190
        $charset = api_get_system_encoding();
3191
        $filepath = api_get_path(SYS_ARCHIVE_PATH).$file['name'];
3192
        $messages = [];
3193
3194
        if (!@move_uploaded_file($file['tmp_name'], $filepath)) {
3195
            error_log(
3196
                'Problem moving uploaded file: '.$file['error'].' in '.__FILE__.' line '.__LINE__
3197
            );
3198
3199
            return false;
3200
        }
3201
3202
        $data = file_get_contents($filepath);
3203
3204
        $trans = [
3205
            'DAILY' => 'daily',
3206
            'WEEKLY' => 'weekly',
3207
            'MONTHLY' => 'monthlyByDate',
3208
            'YEARLY' => 'yearly',
3209
        ];
3210
        $sentTo = ['everyone' => true];
3211
        $calendar = Sabre\VObject\Reader::read($data);
3212
        $currentTimeZone = api_get_timezone();
3213
        if (!empty($calendar->VEVENT)) {
3214
            /** @var Sabre\VObject\Component\VEvent $event */
3215
            foreach ($calendar->VEVENT as $event) {
3216
                $tempDate = $event->DTSTART->getValue();
3217
                if ('Z' == substr($tempDate, -1) && 'UTC' != date('e', strtotime($tempDate))) {
3218
                    $event->DTSTART->setValue(gmdate('Ymd\THis\Z', strtotime($tempDate)));
3219
                }
3220
                $tempDate = $event->DTEND->getValue();
3221
                if ('Z' == substr($tempDate, -1) && 'UTC' != date('e', strtotime($tempDate))) {
3222
                    $event->DTEND->setValue(gmdate('Ymd\THis\Z', strtotime($tempDate)));
3223
                }
3224
                $start = $event->DTSTART->getDateTime();
3225
                $end = $event->DTEND->getDateTime();
3226
                //Sabre\VObject\DateTimeParser::parseDateTime(string $dt, \Sabre\VObject\DateTimeZone $tz)
3227
3228
                $startDateTime = api_get_local_time(
3229
                    $start->format('Y-m-d H:i:s'),
3230
                    $currentTimeZone,
3231
                    $start->format('e')
3232
                );
3233
                $endDateTime = api_get_local_time(
3234
                    $end->format('Y-m-d H:i'),
3235
                    $currentTimeZone,
3236
                    $end->format('e')
3237
                );
3238
                $title = api_convert_encoding(
3239
                    (string) $event->summary,
3240
                    $charset,
3241
                    'UTF-8'
3242
                );
3243
                $description = api_convert_encoding(
3244
                    (string) $event->description,
3245
                    $charset,
3246
                    'UTF-8'
3247
                );
3248
3249
                $id = $this->addEvent(
3250
                    $startDateTime,
3251
                    $endDateTime,
3252
                    'false',
3253
                    $title,
3254
                    $description,
3255
                    $sentTo
3256
                );
3257
3258
                $messages[] = " $title - ".$startDateTime." - ".$endDateTime;
3259
3260
                //$attendee = (string)$event->attendee;
3261
                /** @var Sabre\VObject\Property\ICalendar\Recur $repeat */
3262
                $repeat = $event->RRULE;
3263
                if ($id && !empty($repeat)) {
3264
                    $repeat = $repeat->getParts();
3265
                    $freq = $trans[$repeat['FREQ']];
3266
3267
                    if (isset($repeat['UNTIL']) && !empty($repeat['UNTIL'])) {
3268
                        // Check if datetime or just date (strlen == 8)
3269
                        if (strlen($repeat['UNTIL']) == 8) {
3270
                            // Fix the datetime format to avoid exception in the next step
3271
                            $repeat['UNTIL'] .= 'T000000';
3272
                        }
3273
                        $until = Sabre\VObject\DateTimeParser::parseDateTime(
3274
                            $repeat['UNTIL'],
3275
                            new DateTimeZone($currentTimeZone)
3276
                        );
3277
                        $until = $until->format('Y-m-d H:i:s');
3278
                        $this->addRepeatedItem(
3279
                            $id,
3280
                            $freq,
3281
                            $until,
3282
                            $sentTo
3283
                        );
3284
                    }
3285
3286
                    if (!empty($repeat['COUNT'])) {
3287
                        /*$count = $repeat['COUNT'];
3288
                        $interval = $repeat['INTERVAL'];
3289
                        $endDate = null;
3290
                        switch($freq) {
3291
                            case 'daily':
3292
                                $start = api_strtotime($startDateTime);
3293
                                $date = new DateTime($startDateTime);
3294
                                $days = $count * $interval;
3295
                                var_dump($days);
3296
                                $date->add(new DateInterval("P".$days."D"));
3297
                                $endDate = $date->format('Y-m-d H:i');
3298
                                //$endDate = $count *
3299
                                for ($i = 0; $i < $count; $i++) {
3300
                                    $days = 86400 * 7
3301
                                }
3302
                            }
3303
                        }*/
3304
                        //$res = agenda_add_repeat_item($courseInfo, $id, $freq, $count, $attendee);
3305
                        /*$this->addRepeatedItem(
3306
                            $id,
3307
                            $freq,
3308
                            $endDate,
3309
                            $sentTo
3310
                        );*/
3311
                    }
3312
                }
3313
            }
3314
        }
3315
3316
        if (!empty($messages)) {
3317
            $messages = implode('<br /> ', $messages);
3318
        } else {
3319
            $messages = get_lang('NoAgendaItems');
3320
        }
3321
3322
        return $messages;
3323
    }
3324
3325
    /**
3326
     * Parse filter turns USER:12 to ['users' => [12])] or G:1 ['groups' => [1]].
3327
     *
3328
     * @param int $filter
3329
     *
3330
     * @return array
3331
     */
3332
    public function parseAgendaFilter($filter)
3333
    {
3334
        $everyone = false;
3335
        $groupId = null;
3336
        $userId = null;
3337
3338
        if ($filter == 'everyone') {
3339
            $everyone = true;
3340
        } else {
3341
            if (substr($filter, 0, 1) == 'G') {
3342
                $groupId = str_replace('GROUP:', '', $filter);
3343
            } else {
3344
                $userId = str_replace('USER:', '', $filter);
3345
            }
3346
        }
3347
        if (empty($userId) && empty($groupId)) {
3348
            $everyone = true;
3349
        }
3350
3351
        return [
3352
            'everyone' => $everyone,
3353
            'users' => [$userId],
3354
            'groups' => [$groupId],
3355
        ];
3356
    }
3357
3358
    /**
3359
     *    This function retrieves all the agenda items of all the courses the user is subscribed to.
3360
     */
3361
    public static function get_myagendaitems(
3362
        $user_id,
3363
        $courses_dbs,
3364
        $month,
3365
        $year
3366
    ) {
3367
        $user_id = intval($user_id);
3368
3369
        $items = [];
3370
        $my_list = [];
3371
3372
        // get agenda-items for every course
3373
        foreach ($courses_dbs as $key => $array_course_info) {
3374
            //databases of the courses
3375
            $TABLEAGENDA = Database::get_course_table(TABLE_AGENDA);
3376
            $TABLE_ITEMPROPERTY = Database::get_course_table(
3377
                TABLE_ITEM_PROPERTY
3378
            );
3379
3380
            $group_memberships = GroupManager::get_group_ids(
3381
                $array_course_info['real_id'],
3382
                $user_id
3383
            );
3384
            $course_user_status = CourseManager::getUserInCourseStatus(
3385
                $user_id,
3386
                $array_course_info['real_id']
3387
            );
3388
            // if the user is administrator of that course we show all the agenda items
3389
            if ($course_user_status == '1') {
3390
                //echo "course admin";
3391
                $sqlquery = "SELECT DISTINCT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref
3392
							FROM ".$TABLEAGENDA." agenda,
3393
								 ".$TABLE_ITEMPROPERTY." ip
3394
							WHERE agenda.id = ip.ref
3395
							AND MONTH(agenda.start_date)='".$month."'
3396
							AND YEAR(agenda.start_date)='".$year."'
3397
							AND ip.tool='".TOOL_CALENDAR_EVENT."'
3398
							AND ip.visibility='1'
3399
							GROUP BY agenda.id
3400
							ORDER BY start_date ";
3401
            } else {
3402
                // if the user is not an administrator of that course
3403
                if (is_array($group_memberships) && count(
3404
                        $group_memberships
3405
                    ) > 0
3406
                ) {
3407
                    $sqlquery = "SELECT	agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref
3408
								FROM ".$TABLEAGENDA." agenda,
3409
									".$TABLE_ITEMPROPERTY." ip
3410
								WHERE agenda.id = ip.ref
3411
								AND MONTH(agenda.start_date)='".$month."'
3412
								AND YEAR(agenda.start_date)='".$year."'
3413
								AND ip.tool='".TOOL_CALENDAR_EVENT."'
3414
								AND	( ip.to_user_id='".$user_id."' OR (ip.to_group_id IS NULL OR ip.to_group_id IN (0, ".implode(
3415
                            ", ",
3416
                            $group_memberships
3417
                        ).")) )
3418
								AND ip.visibility='1'
3419
								ORDER BY start_date ";
3420
                } else {
3421
                    $sqlquery = "SELECT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref
3422
								FROM ".$TABLEAGENDA." agenda,
3423
									".$TABLE_ITEMPROPERTY." ip
3424
								WHERE agenda.id = ip.ref
3425
								AND MONTH(agenda.start_date)='".$month."'
3426
								AND YEAR(agenda.start_date)='".$year."'
3427
								AND ip.tool='".TOOL_CALENDAR_EVENT."'
3428
								AND ( ip.to_user_id='".$user_id."' OR ip.to_group_id='0' OR ip.to_group_id IS NULL)
3429
								AND ip.visibility='1'
3430
								ORDER BY start_date ";
3431
                }
3432
            }
3433
            $result = Database::query($sqlquery);
3434
3435
            while ($item = Database::fetch_array($result, 'ASSOC')) {
3436
                $agendaday = -1;
3437
                if (!empty($item['start_date'])) {
3438
                    $item['start_date'] = api_get_local_time(
3439
                        $item['start_date']
3440
                    );
3441
                    $item['start_date_tms'] = api_strtotime(
3442
                        $item['start_date']
3443
                    );
3444
                    $agendaday = date("j", $item['start_date_tms']);
3445
                }
3446
                if (!empty($item['end_date'])) {
3447
                    $item['end_date'] = api_get_local_time($item['end_date']);
3448
                }
3449
3450
                $url = api_get_path(
3451
                        WEB_CODE_PATH
3452
                    )."calendar/agenda.php?cidReq=".urlencode(
3453
                        $array_course_info["code"]
3454
                    )."&day=$agendaday&month=$month&year=$year#$agendaday";
3455
3456
                $item['url'] = $url;
3457
                $item['course_name'] = $array_course_info['title'];
3458
                $item['calendar_type'] = 'course';
3459
                $item['course_id'] = $array_course_info['course_id'];
3460
3461
                $my_list[$agendaday][] = $item;
3462
            }
3463
        }
3464
3465
        // sorting by hour for every day
3466
        $agendaitems = [];
3467
        foreach ($items as $agendaday => $tmpitems) {
3468
            if (!isset($agendaitems[$agendaday])) {
3469
                $agendaitems[$agendaday] = '';
3470
            }
3471
            sort($tmpitems);
3472
            foreach ($tmpitems as $val) {
3473
                $agendaitems[$agendaday] .= $val;
3474
            }
3475
        }
3476
3477
        return $my_list;
3478
    }
3479
3480
    /**
3481
     * This function retrieves one personal agenda item returns it.
3482
     *
3483
     * @param    array    The array containing existing events. We add to this array.
3484
     * @param    int        Day
3485
     * @param    int        Month
3486
     * @param    int        Year (4 digits)
3487
     * @param    int        Week number
3488
     * @param    string    Type of view (month_view, week_view, day_view)
3489
     *
3490
     * @return array The results of the database query, or null if not found
3491
     */
3492
    public static function get_global_agenda_items(
3493
        $agendaitems,
3494
        $day,
3495
        $month,
3496
        $year,
3497
        $week,
3498
        $type
3499
    ) {
3500
        $tbl_global_agenda = Database::get_main_table(
3501
            TABLE_MAIN_SYSTEM_CALENDAR
3502
        );
3503
        $month = intval($month);
3504
        $year = intval($year);
3505
        $week = intval($week);
3506
        $day = intval($day);
3507
        // 1. creating the SQL statement for getting the personal agenda items in MONTH view
3508
3509
        $current_access_url_id = api_get_current_access_url_id();
3510
3511
        if ($type == "month_view" || $type == "") {
3512
            // We are in month view
3513
            $sql = "SELECT * FROM ".$tbl_global_agenda."
3514
                    WHERE
3515
                        MONTH(start_date) = ".$month." AND
3516
                        YEAR(start_date) = ".$year."  AND
3517
                        access_url_id = $current_access_url_id
3518
                    ORDER BY start_date ASC";
3519
        }
3520
        // 2. creating the SQL statement for getting the personal agenda items in WEEK view
3521
        if ($type == "week_view") { // we are in week view
3522
            $start_end_day_of_week = self::calculate_start_end_of_week(
3523
                $week,
3524
                $year
3525
            );
3526
            $start_day = $start_end_day_of_week['start']['day'];
3527
            $start_month = $start_end_day_of_week['start']['month'];
3528
            $start_year = $start_end_day_of_week['start']['year'];
3529
            $end_day = $start_end_day_of_week['end']['day'];
3530
            $end_month = $start_end_day_of_week['end']['month'];
3531
            $end_year = $start_end_day_of_week['end']['year'];
3532
            // in sql statements you have to use year-month-day for date calculations
3533
            $start_filter = $start_year."-".$start_month."-".$start_day." 00:00:00";
3534
            $start_filter = api_get_utc_datetime($start_filter);
3535
3536
            $end_filter = $end_year."-".$end_month."-".$end_day." 23:59:59";
3537
            $end_filter = api_get_utc_datetime($end_filter);
3538
            $sql = " SELECT * FROM ".$tbl_global_agenda." WHERE start_date>='".$start_filter."' AND start_date<='".$end_filter."' AND  access_url_id = $current_access_url_id ";
3539
        }
3540
        // 3. creating the SQL statement for getting the personal agenda items in DAY view
3541
        if ($type == "day_view") { // we are in day view
3542
            // we could use mysql date() function but this is only available from 4.1 and higher
3543
            $start_filter = $year."-".$month."-".$day." 00:00:00";
3544
            $start_filter = api_get_utc_datetime($start_filter);
3545
3546
            $end_filter = $year."-".$month."-".$day." 23:59:59";
3547
            $end_filter = api_get_utc_datetime($end_filter);
3548
            $sql = " SELECT * FROM ".$tbl_global_agenda." WHERE start_date>='".$start_filter."' AND start_date<='".$end_filter."'  AND  access_url_id = $current_access_url_id";
3549
        }
3550
3551
        $result = Database::query($sql);
3552
3553
        while ($item = Database::fetch_array($result)) {
3554
            if (!empty($item['start_date'])) {
3555
                $item['start_date'] = api_get_local_time($item['start_date']);
3556
                $item['start_date_tms'] = api_strtotime($item['start_date']);
3557
            }
3558
            if (!empty($item['end_date'])) {
3559
                $item['end_date'] = api_get_local_time($item['end_date']);
3560
            }
3561
3562
            // we break the date field in the database into a date and a time part
3563
            $agenda_db_date = explode(" ", $item['start_date']);
3564
            $date = $agenda_db_date[0];
3565
            $time = $agenda_db_date[1];
3566
            // we divide the date part into a day, a month and a year
3567
            $agendadate = explode("-", $date);
3568
            $year = intval($agendadate[0]);
3569
            $month = intval($agendadate[1]);
3570
            $day = intval($agendadate[2]);
3571
            // we divide the time part into hour, minutes, seconds
3572
            $agendatime = explode(":", $time);
3573
            $hour = $agendatime[0];
3574
            $minute = $agendatime[1];
3575
            $second = $agendatime[2];
3576
3577
            if ($type == 'month_view') {
3578
                $item['calendar_type'] = 'global';
3579
                $agendaitems[$day][] = $item;
3580
                continue;
3581
            }
3582
3583
            $start_time = api_format_date(
3584
                $item['start_date'],
3585
                TIME_NO_SEC_FORMAT
3586
            );
3587
            $end_time = '';
3588
            if (!empty($item['end_date'])) {
3589
                $end_time = ' - '.api_format_date(
3590
                        $item['end_date'],
3591
                        DATE_TIME_FORMAT_LONG
3592
                    );
3593
            }
3594
3595
            // if the student has specified a course we a add a link to that course
3596
            if ($item['course'] != "") {
3597
                $url = api_get_path(
3598
                        WEB_CODE_PATH
3599
                    )."admin/agenda.php?cidReq=".urlencode(
3600
                        $item['course']
3601
                    )."&day=$day&month=$month&year=$year#$day"; // RH  //Patrick Cool: to highlight the relevant agenda item
3602
                $course_link = "<a href=\"$url\" title=\"".$item['course']."\">".$item['course']."</a>";
3603
            } else {
3604
                $course_link = "";
3605
            }
3606
            // Creating the array that will be returned. If we have week or month view we have an array with the date as the key
3607
            // if we have a day_view we use a half hour as index => key 33 = 16h30
3608
            if ($type !== "day_view") {
3609
                // This is the array construction for the WEEK or MONTH view
3610
                //Display the Agenda global in the tab agenda (administrator)
3611
                $agendaitems[$day] .= "<i>$start_time $end_time</i>&nbsp;-&nbsp;";
3612
                $agendaitems[$day] .= "<b>".get_lang('GlobalEvent')."</b>";
3613
                $agendaitems[$day] .= "<div>".$item['title']."</div><br>";
3614
            } else {
3615
                // this is the array construction for the DAY view
3616
                $halfhour = 2 * $agendatime['0'];
3617
                if ($agendatime['1'] >= '30') {
3618
                    $halfhour = $halfhour + 1;
3619
                }
3620
                if (!is_array($agendaitems[$halfhour])) {
3621
                    $content = $agendaitems[$halfhour];
3622
                }
3623
                $agendaitems[$halfhour] = $content."<div><i>$hour:$minute</i> <b>".get_lang(
3624
                        'GlobalEvent'
3625
                    ).":  </b>".$item['title']."</div>";
3626
            }
3627
        }
3628
3629
        return $agendaitems;
3630
    }
3631
3632
    /**
3633
     * This function retrieves all the personal agenda items and add them to the agenda items found by the other
3634
     * functions.
3635
     */
3636
    public static function get_personal_agenda_items(
3637
        $user_id,
3638
        $agendaitems,
3639
        $day,
3640
        $month,
3641
        $year,
3642
        $week,
3643
        $type
3644
    ) {
3645
        $tbl_personal_agenda = Database::get_main_table(TABLE_PERSONAL_AGENDA);
3646
        $user_id = intval($user_id);
3647
3648
        // 1. creating the SQL statement for getting the personal agenda items in MONTH view
3649
        if ($type === "month_view" || $type === "") {
3650
            // we are in month view
3651
            $sql = "SELECT * FROM $tbl_personal_agenda
3652
                    WHERE
3653
                        user='".$user_id."' AND
3654
                        MONTH(date)='".$month."' AND
3655
                        YEAR(date) = '".$year."'
3656
                     ORDER BY date ASC";
3657
        }
3658
3659
        // 2. creating the SQL statement for getting the personal agenda items in WEEK view
3660
        // we are in week view
3661
        if ($type == "week_view") {
3662
            $start_end_day_of_week = self::calculate_start_end_of_week(
3663
                $week,
3664
                $year
3665
            );
3666
            $start_day = $start_end_day_of_week['start']['day'];
3667
            $start_month = $start_end_day_of_week['start']['month'];
3668
            $start_year = $start_end_day_of_week['start']['year'];
3669
            $end_day = $start_end_day_of_week['end']['day'];
3670
            $end_month = $start_end_day_of_week['end']['month'];
3671
            $end_year = $start_end_day_of_week['end']['year'];
3672
            // in sql statements you have to use year-month-day for date calculations
3673
            $start_filter = $start_year."-".$start_month."-".$start_day." 00:00:00";
3674
            $start_filter = api_get_utc_datetime($start_filter);
3675
            $end_filter = $end_year."-".$end_month."-".$end_day." 23:59:59";
3676
            $end_filter = api_get_utc_datetime($end_filter);
3677
            $sql = " SELECT * FROM ".$tbl_personal_agenda." WHERE user='".$user_id."' AND date>='".$start_filter."' AND date<='".$end_filter."'";
3678
        }
3679
        // 3. creating the SQL statement for getting the personal agenda items in DAY view
3680
        if ($type == "day_view") {
3681
            // we are in day view
3682
            // we could use mysql date() function but this is only available from 4.1 and higher
3683
            $start_filter = $year."-".$month."-".$day." 00:00:00";
3684
            $start_filter = api_get_utc_datetime($start_filter);
3685
            $end_filter = $year."-".$month."-".$day." 23:59:59";
3686
            $end_filter = api_get_utc_datetime($end_filter);
3687
            $sql = " SELECT * FROM ".$tbl_personal_agenda." WHERE user='".$user_id."' AND date>='".$start_filter."' AND date<='".$end_filter."'";
3688
        }
3689
3690
        $result = Database::query($sql);
3691
        while ($item = Database::fetch_array($result, 'ASSOC')) {
3692
            $time_minute = api_convert_and_format_date(
3693
                $item['date'],
3694
                TIME_NO_SEC_FORMAT
3695
            );
3696
            $item['date'] = api_get_local_time($item['date']);
3697
            $item['start_date_tms'] = api_strtotime($item['date']);
3698
            $item['content'] = $item['text'];
3699
3700
            // we break the date field in the database into a date and a time part
3701
            $agenda_db_date = explode(" ", $item['date']);
3702
            $date = $agenda_db_date[0];
3703
            $time = $agenda_db_date[1];
3704
            // we divide the date part into a day, a month and a year
3705
            $agendadate = explode("-", $item['date']);
3706
            $year = intval($agendadate[0]);
3707
            $month = intval($agendadate[1]);
3708
            $day = intval($agendadate[2]);
3709
            // we divide the time part into hour, minutes, seconds
3710
            $agendatime = explode(":", $time);
3711
3712
            $hour = $agendatime[0];
3713
            $minute = $agendatime[1];
3714
            $second = $agendatime[2];
3715
3716
            if ($type == 'month_view') {
3717
                $item['calendar_type'] = 'personal';
3718
                $item['start_date'] = $item['date'];
3719
                $agendaitems[$day][] = $item;
3720
                continue;
3721
            }
3722
3723
            // if the student has specified a course we a add a link to that course
3724
            if ($item['course'] != "") {
3725
                $url = api_get_path(
3726
                        WEB_CODE_PATH
3727
                    )."calendar/agenda.php?cidReq=".urlencode(
3728
                        $item['course']
3729
                    )."&day=$day&month=$month&year=$year#$day"; // RH  //Patrick Cool: to highlight the relevant agenda item
3730
                $course_link = "<a href=\"$url\" title=\"".$item['course']."\">".$item['course']."</a>";
3731
            } else {
3732
                $course_link = "";
3733
            }
3734
            // Creating the array that will be returned. If we have week or month view we have an array with the date as the key
3735
            // if we have a day_view we use a half hour as index => key 33 = 16h30
3736
            if ($type !== "day_view") {
3737
                // This is the array construction for the WEEK or MONTH view
3738
3739
                //Display events in agenda
3740
                $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 />";
3741
            } else {
3742
                // this is the array construction for the DAY view
3743
                $halfhour = 2 * $agendatime['0'];
3744
                if ($agendatime['1'] >= '30') {
3745
                    $halfhour = $halfhour + 1;
3746
                }
3747
3748
                //Display events by list
3749
                $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>";
3750
            }
3751
        }
3752
3753
        return $agendaitems;
3754
    }
3755
3756
    /**
3757
     * Show the monthcalender of the given month.
3758
     *
3759
     * @param    array    Agendaitems
3760
     * @param    int    Month number
3761
     * @param    int    Year number
3762
     * @param    array    Array of strings containing long week day names (deprecated, you can send an empty array
3763
     *                          instead)
3764
     * @param    string    The month name
3765
     */
3766
    public static function display_mymonthcalendar(
3767
        $user_id,
3768
        $agendaitems,
3769
        $month,
3770
        $year,
3771
        $weekdaynames,
3772
        $monthName,
3773
        $show_content = true
3774
    ) {
3775
        global $DaysShort, $course_path;
3776
        //Handle leap year
3777
        $numberofdays = [
3778
            0,
3779
            31,
3780
            28,
3781
            31,
3782
            30,
3783
            31,
3784
            30,
3785
            31,
3786
            31,
3787
            30,
3788
            31,
3789
            30,
3790
            31,
3791
        ];
3792
        if (($year % 400 == 0) or ($year % 4 == 0 and $year % 100 != 0)) {
3793
            $numberofdays[2] = 29;
3794
        }
3795
        //Get the first day of the month
3796
        $dayone = getdate(mktime(0, 0, 0, $month, 1, $year));
3797
        //Start the week on monday
3798
        $startdayofweek = $dayone['wday'] != 0 ? ($dayone['wday'] - 1) : 6;
3799
        $g_cc = (isset($_GET['courseCode']) ? $_GET['courseCode'] : '');
3800
3801
        $next_month = ($month == 1 ? 12 : $month - 1);
3802
        $prev_month = ($month == 12 ? 1 : $month + 1);
3803
3804
        $next_year = ($month == 1 ? $year - 1 : $year);
3805
        $prev_year = ($month == 12 ? $year + 1 : $year);
3806
3807
        if ($show_content) {
3808
            $back_url = Display::url(
3809
                get_lang('Previous'),
3810
                api_get_self()."?coursePath=".urlencode(
3811
                    $course_path
3812
                )."&courseCode=".Security::remove_XSS(
3813
                    $g_cc
3814
                )."&action=view&view=month&month=".$next_month."&year=".$next_year
3815
            );
3816
            $next_url = Display::url(
3817
                get_lang('Next'),
3818
                api_get_self()."?coursePath=".urlencode(
3819
                    $course_path
3820
                )."&courseCode=".Security::remove_XSS(
3821
                    $g_cc
3822
                )."&action=view&view=month&month=".$prev_month."&year=".$prev_year
3823
            );
3824
        } else {
3825
            $back_url = Display::url(
3826
                get_lang('Previous'),
3827
                '',
3828
                [
3829
                    'onclick' => "load_calendar('".$user_id."','".$next_month."', '".$next_year."'); ",
3830
                    'class' => 'btn ui-button ui-widget ui-state-default',
3831
                ]
3832
            );
3833
            $next_url = Display::url(
3834
                get_lang('Next'),
3835
                '',
3836
                [
3837
                    'onclick' => "load_calendar('".$user_id."','".$prev_month."', '".$prev_year."'); ",
3838
                    'class' => 'pull-right btn ui-button ui-widget ui-state-default',
3839
                ]
3840
            );
3841
        }
3842
        $html = '';
3843
        $html .= '<div class="actions">';
3844
        $html .= '<div class="row">';
3845
        $html .= '<div class="col-md-4">'.$back_url.'</div>';
3846
        $html .= '<div class="col-md-4"><p class="agenda-title text-center">'.$monthName." ".$year.'</p></div>';
3847
        $html .= '<div class="col-md-4">'.$next_url.'</div>';
3848
        $html .= '</div>';
3849
        $html .= '</div>';
3850
        $html .= '<table id="agenda_list2" class="table table-bordered">';
3851
        $html .= '<tr>';
3852
        for ($ii = 1; $ii < 8; $ii++) {
3853
            $html .= '<td class="weekdays">'.$DaysShort[$ii % 7].'</td>';
3854
        }
3855
        $html .= '</tr>';
3856
3857
        $curday = -1;
3858
        $today = getdate();
3859
        while ($curday <= $numberofdays[$month]) {
3860
            $html .= "<tr>";
3861
            for ($ii = 0; $ii < 7; $ii++) {
3862
                if (($curday == -1) && ($ii == $startdayofweek)) {
3863
                    $curday = 1;
3864
                }
3865
                if (($curday > 0) && ($curday <= $numberofdays[$month])) {
3866
                    $bgcolor = $class = 'class="days_week"';
3867
                    $dayheader = Display::div(
3868
                        $curday,
3869
                        ['class' => 'agenda_day']
3870
                    );
3871
                    if (($curday == $today['mday']) && ($year == $today['year']) && ($month == $today['mon'])) {
3872
                        $class = "class=\"days_today\" style=\"width:10%;\"";
3873
                    }
3874
3875
                    $html .= "<td ".$class.">".$dayheader;
3876
3877
                    if (!empty($agendaitems[$curday])) {
3878
                        $items = $agendaitems[$curday];
3879
                        $items = msort($items, 'start_date_tms');
3880
3881
                        foreach ($items as $value) {
3882
                            $value['title'] = Security::remove_XSS(
3883
                                $value['title']
3884
                            );
3885
                            $start_time = api_format_date(
3886
                                $value['start_date'],
3887
                                TIME_NO_SEC_FORMAT
3888
                            );
3889
                            $end_time = '';
3890
3891
                            if (!empty($value['end_date'])) {
3892
                                $end_time = '-&nbsp;<i>'.api_format_date(
3893
                                        $value['end_date'],
3894
                                        DATE_TIME_FORMAT_LONG
3895
                                    ).'</i>';
3896
                            }
3897
                            $complete_time = '<i>'.api_format_date(
3898
                                    $value['start_date'],
3899
                                    DATE_TIME_FORMAT_LONG
3900
                                ).'</i>&nbsp;'.$end_time;
3901
                            $time = '<i>'.$start_time.'</i>';
3902
3903
                            switch ($value['calendar_type']) {
3904
                                case 'personal':
3905
                                    $bg_color = '#D0E7F4';
3906
                                    $icon = Display::return_icon(
3907
                                        'user.png',
3908
                                        get_lang('MyAgenda'),
3909
                                        [],
3910
                                        ICON_SIZE_SMALL
3911
                                    );
3912
                                    break;
3913
                                case 'global':
3914
                                    $bg_color = '#FFBC89';
3915
                                    $icon = Display::return_icon(
3916
                                        'view_remove.png',
3917
                                        get_lang('GlobalEvent'),
3918
                                        [],
3919
                                        ICON_SIZE_SMALL
3920
                                    );
3921
                                    break;
3922
                                case 'course':
3923
                                    $bg_color = '#CAFFAA';
3924
                                    $icon_name = 'course.png';
3925
                                    if (!empty($value['session_id'])) {
3926
                                        $icon_name = 'session.png';
3927
                                    }
3928
                                    if ($show_content) {
3929
                                        $icon = Display::url(
3930
                                            Display::return_icon(
3931
                                                $icon_name,
3932
                                                $value['course_name'].' '.get_lang(
3933
                                                    'Course'
3934
                                                ),
3935
                                                [],
3936
                                                ICON_SIZE_SMALL
3937
                                            ),
3938
                                            $value['url']
3939
                                        );
3940
                                    } else {
3941
                                        $icon = Display::return_icon(
3942
                                            $icon_name,
3943
                                            $value['course_name'].' '.get_lang(
3944
                                                'Course'
3945
                                            ),
3946
                                            [],
3947
                                            ICON_SIZE_SMALL
3948
                                        );
3949
                                    }
3950
                                    break;
3951
                                default:
3952
                                    break;
3953
                            }
3954
3955
                            $result = '<div class="rounded_div_agenda" style="background-color:'.$bg_color.';">';
3956
3957
                            if ($show_content) {
3958
                                //Setting a personal event to green
3959
                                $icon = Display::div(
3960
                                    $icon,
3961
                                    ['style' => 'float:right']
3962
                                );
3963
3964
                                $link = $value['calendar_type'].'_'.$value['id'].'_'.$value['course_id'].'_'.$value['session_id'];
3965
3966
                                //Link to bubble
3967
                                $url = Display::url(
3968
                                    cut($value['title'], 40),
3969
                                    '#',
3970
                                    ['id' => $link, 'class' => 'opener']
3971
                                );
3972
                                $result .= $time.' '.$icon.' '.Display::div(
3973
                                        $url
3974
                                    );
3975
3976
                                //Hidden content
3977
                                $content = Display::div(
3978
                                    $icon.Display::tag(
3979
                                        'h2',
3980
                                        $value['course_name']
3981
                                    ).'<hr />'.Display::tag(
3982
                                        'h3',
3983
                                        $value['title']
3984
                                    ).$complete_time.'<hr />'.Security::remove_XSS(
3985
                                        $value['content']
3986
                                    )
3987
                                );
3988
3989
                                //Main div
3990
                                $result .= Display::div(
3991
                                    $content,
3992
                                    [
3993
                                        'id' => 'main_'.$link,
3994
                                        'class' => 'dialog',
3995
                                        'style' => 'display:none',
3996
                                    ]
3997
                                );
3998
                                $result .= '</div>';
3999
                                $html .= $result;
4000
                            } else {
4001
                                $html .= $result .= $icon.'</div>';
4002
                            }
4003
                        }
4004
                    }
4005
                    $html .= "</td>";
4006
                    $curday++;
4007
                } else {
4008
                    $html .= "<td></td>";
4009
                }
4010
            }
4011
            $html .= "</tr>";
4012
        }
4013
        $html .= "</table>";
4014
        echo $html;
4015
    }
4016
4017
    /**
4018
     * Get personal agenda items between two dates (=all events from all registered courses).
4019
     *
4020
     * @param int $user_id user ID of the user
4021
     * @param    string    Optional start date in datetime format (if no start date is given, uses today)
4022
     * @param    string    Optional end date in datetime format (if no date is given, uses one year from now)
4023
     *
4024
     * @return array array of events ordered by start date, in
4025
     *               [0]('datestart','dateend','title'),[1]('datestart','dateend','title','link','coursetitle') format,
4026
     *               where datestart and dateend are in yyyyMMddhhmmss format
4027
     *
4028
     * @deprecated use agenda events
4029
     */
4030
    public static function get_personal_agenda_items_between_dates(
4031
        $user_id,
4032
        $date_start = '',
4033
        $date_end = ''
4034
    ) {
4035
        $items = [];
4036
        if ($user_id != strval(intval($user_id))) {
4037
            return $items;
4038
        }
4039
        if (empty($date_start)) {
4040
            $date_start = date('Y-m-d H:i:s');
4041
        }
4042
        if (empty($date_end)) {
4043
            $date_end = date(
4044
                'Y-m-d H:i:s',
4045
                mktime(0, 0, 0, date("m"), date("d"), date("Y") + 1)
4046
            );
4047
        }
4048
        $expr = '/\d{4}-\d{2}-\d{2}\ \d{2}:\d{2}:\d{2}/';
4049
        if (!preg_match($expr, $date_start)) {
4050
            return $items;
4051
        }
4052
        if (!preg_match($expr, $date_end)) {
4053
            return $items;
4054
        }
4055
4056
        // get agenda-items for every course
4057
        $courses = api_get_user_courses($user_id, false);
4058
        foreach ($courses as $id => $course) {
4059
            $c = api_get_course_info_by_id($course['real_id']);
4060
            //databases of the courses
4061
            $t_a = Database::get_course_table(TABLE_AGENDA, $course['db']);
4062
            $t_ip = Database::get_course_table(
4063
                TABLE_ITEM_PROPERTY,
4064
                $course['db']
4065
            );
4066
            // get the groups to which the user belong
4067
            $group_memberships = GroupManager:: get_group_ids(
4068
                $course['db'],
4069
                $user_id
4070
            );
4071
            // if the user is administrator of that course we show all the agenda items
4072
            if ($course['status'] == '1') {
4073
                //echo "course admin";
4074
                $sqlquery = "SELECT ".
4075
                    " DISTINCT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref ".
4076
                    " FROM ".$t_a." agenda, ".
4077
                    $t_ip." ip ".
4078
                    " WHERE agenda.id = ip.ref ".
4079
                    " AND agenda.start_date>='$date_start' ".
4080
                    " AND agenda.end_date<='$date_end' ".
4081
                    " AND ip.tool='".TOOL_CALENDAR_EVENT."' ".
4082
                    " AND ip.visibility='1' ".
4083
                    " GROUP BY agenda.id ".
4084
                    " ORDER BY start_date ";
4085
            } else {
4086
                // if the user is not an administrator of that course, then...
4087
                if (is_array($group_memberships) && count(
4088
                        $group_memberships
4089
                    ) > 0
4090
                ) {
4091
                    $sqlquery = "SELECT ".
4092
                        "DISTINCT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref ".
4093
                        " FROM ".$t_a." agenda, ".
4094
                        $t_ip." ip ".
4095
                        " WHERE agenda.id = ip.ref ".
4096
                        " AND agenda.start_date>='$date_start' ".
4097
                        " AND agenda.end_date<='$date_end' ".
4098
                        " AND ip.tool='".TOOL_CALENDAR_EVENT."' ".
4099
                        " AND	( ip.to_user_id='".$user_id."' OR (ip.to_group_id IS NULL OR ip.to_group_id IN (0, ".implode(
4100
                            ", ",
4101
                            $group_memberships
4102
                        ).")) ) ".
4103
                        " AND ip.visibility='1' ".
4104
                        " ORDER BY start_date ";
4105
                } else {
4106
                    $sqlquery = "SELECT ".
4107
                        "DISTINCT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref ".
4108
                        " FROM ".$t_a." agenda, ".
4109
                        $t_ip." ip ".
4110
                        " WHERE agenda.id = ip.ref ".
4111
                        " AND agenda.start_date>='$date_start' ".
4112
                        " AND agenda.end_date<='$date_end' ".
4113
                        " AND ip.tool='".TOOL_CALENDAR_EVENT."' ".
4114
                        " AND ( ip.to_user_id='".$user_id."' OR ip.to_group_id='0' OR ip.to_group_id IS NULL) ".
4115
                        " AND ip.visibility='1' ".
4116
                        " ORDER BY start_date ";
4117
                }
4118
            }
4119
4120
            $result = Database::query($sqlquery);
4121
            while ($item = Database::fetch_array($result)) {
4122
                $agendaday = date("j", strtotime($item['start_date']));
4123
                $month = date("n", strtotime($item['start_date']));
4124
                $year = date("Y", strtotime($item['start_date']));
4125
                $URL = api_get_path(
4126
                        WEB_PATH
4127
                    )."main/calendar/agenda.php?cidReq=".urlencode(
4128
                        $course["code"]
4129
                    )."&day=$agendaday&month=$month&year=$year#$agendaday";
4130
                list($year, $month, $day, $hour, $min, $sec) = explode(
4131
                    '[-: ]',
4132
                    $item['start_date']
4133
                );
4134
                $start_date = $year.$month.$day.$hour.$min;
4135
                list($year, $month, $day, $hour, $min, $sec) = explode(
4136
                    '[-: ]',
4137
                    $item['end_date']
4138
                );
4139
                $end_date = $year.$month.$day.$hour.$min;
4140
4141
                $items[] = [
4142
                    'datestart' => $start_date,
4143
                    'dateend' => $end_date,
4144
                    'title' => $item['title'],
4145
                    'link' => $URL,
4146
                    'coursetitle' => $c['name'],
4147
                ];
4148
            }
4149
        }
4150
4151
        return $items;
4152
    }
4153
4154
    /**
4155
     * This function calculates the startdate of the week (monday)
4156
     * and the enddate of the week (sunday)
4157
     * and returns it as an array.
4158
     */
4159
    public static function calculate_start_end_of_week($week_number, $year)
4160
    {
4161
        // determine the start and end date
4162
        // step 1: we calculate a timestamp for a day in this week
4163
        $random_day_in_week = mktime(
4164
                0,
4165
                0,
4166
                0,
4167
                1,
4168
                1,
4169
                $year
4170
            ) + ($week_number) * (7 * 24 * 60 * 60); // we calculate a random day in this week
4171
        // step 2: we which day this is (0=sunday, 1=monday, ...)
4172
        $number_day_in_week = date('w', $random_day_in_week);
4173
        // step 3: we calculate the timestamp of the monday of the week we are in
4174
        $start_timestamp = $random_day_in_week - (($number_day_in_week - 1) * 24 * 60 * 60);
4175
        // step 4: we calculate the timestamp of the sunday of the week we are in
4176
        $end_timestamp = $random_day_in_week + ((7 - $number_day_in_week + 1) * 24 * 60 * 60) - 3600;
4177
        // step 5: calculating the start_day, end_day, start_month, end_month, start_year, end_year
4178
        $start_day = date('j', $start_timestamp);
4179
        $start_month = date('n', $start_timestamp);
4180
        $start_year = date('Y', $start_timestamp);
4181
        $end_day = date('j', $end_timestamp);
4182
        $end_month = date('n', $end_timestamp);
4183
        $end_year = date('Y', $end_timestamp);
4184
        $start_end_array['start']['day'] = $start_day;
4185
        $start_end_array['start']['month'] = $start_month;
4186
        $start_end_array['start']['year'] = $start_year;
4187
        $start_end_array['end']['day'] = $end_day;
4188
        $start_end_array['end']['month'] = $end_month;
4189
        $start_end_array['end']['year'] = $end_year;
4190
4191
        return $start_end_array;
4192
    }
4193
4194
    /**
4195
     * @return bool
4196
     */
4197
    public function getIsAllowedToEdit()
4198
    {
4199
        return $this->isAllowedToEdit;
4200
    }
4201
4202
    /**
4203
     * @param bool $isAllowedToEdit
4204
     */
4205
    public function setIsAllowedToEdit($isAllowedToEdit)
4206
    {
4207
        $this->isAllowedToEdit = $isAllowedToEdit;
4208
    }
4209
4210
    /**
4211
     * Format needed for the Fullcalendar js lib.
4212
     *
4213
     * @param string $utcTime
4214
     *
4215
     * @return bool|string
4216
     */
4217
    public function formatEventDate($utcTime)
4218
    {
4219
        $utcTimeZone = new DateTimeZone('UTC');
4220
        $platformTimeZone = new DateTimeZone(api_get_timezone());
4221
4222
        $eventDate = new DateTime($utcTime, $utcTimeZone);
4223
        $eventDate->setTimezone($platformTimeZone);
4224
4225
        return $eventDate->format(DateTime::ISO8601);
4226
    }
4227
}
4228