Passed
Push — master ( ec2ac4...5107be )
by Julito
09:28 queued 10s
created

Agenda::setSessionId()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

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