Completed
Push — master ( b77cfe...000f93 )
by Julito
22:58 queued 11:19
created

Agenda::sendEmail()   A

Complexity

Conditions 2

Size

Total Lines 18
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 11
nop 2
dl 0
loc 18
rs 9.4285
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  Opitonal. 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
                    if ($isGroupAccess) {
88
                        $isAllowToEdit = true;
89
                    } else {
90
                        $isAllowToEdit = false;
91
                    }
92
                }
93
94
                if (!empty($sessionId)) {
95
                    $allowDhrToEdit = api_get_configuration_value('allow_agenda_edit_for_hrm');
96
                    if ($allowDhrToEdit) {
97
                        $isHrm = SessionManager::isUserSubscribedAsHRM($sessionId, api_get_user_id());
98
                        if ($isHrm) {
99
                            $isAllowToEdit = true;
100
                        }
101
                    }
102
                }
103
                break;
104
            case 'admin':
105
                $isAllowToEdit = api_is_platform_admin();
106
                break;
107
            case 'personal':
108
                $isAllowToEdit = !api_is_anonymous();
109
                break;
110
        }
111
112
        $this->setIsAllowedToEdit($isAllowToEdit);
113
        $this->events = [];
114
115
        $agendaColors = array_merge(
116
            [
117
                'platform' => 'red', //red
118
                'course' => '#458B00', //green
119
                'group' => '#A0522D', //siena
120
                'session' => '#00496D', // kind of green
121
                'other_session' => '#999', // kind of green
122
                'personal' => 'steel blue', //steel blue
123
                'student_publication' => '#FF8C00', //DarkOrange
124
            ],
125
            api_get_configuration_value('agenda_colors') ?: []
126
        );
127
128
        // Event colors
129
        $this->event_platform_color = $agendaColors['platform'];
130
        $this->event_course_color = $agendaColors['course'];
131
        $this->event_group_color = $agendaColors['group'];
132
        $this->event_session_color = $agendaColors['session'];
133
        $this->eventOtherSessionColor = $agendaColors['other_session'];
134
        $this->event_personal_color = $agendaColors['personal'];
135
        $this->eventStudentPublicationColor = $agendaColors['student_publication'];
136
    }
137
138
    /**
139
     * @param int $senderId
140
     */
141
    public function setSenderId($senderId)
142
    {
143
        $this->senderId = intval($senderId);
144
    }
145
146
    /**
147
     * @return int
148
     */
149
    public function getSenderId()
150
    {
151
        return $this->senderId;
152
    }
153
154
    /**
155
     * @param string $type can be 'personal', 'admin'  or  'course'
156
     */
157
    public function setType($type)
158
    {
159
        $typeList = $this->getTypes();
160
        if (in_array($type, $typeList)) {
161
            $this->type = $type;
162
        }
163
    }
164
165
    /**
166
     * @param int $id
167
     */
168
    public function setSessionId($id)
169
    {
170
        $this->sessionId = intval($id);
171
    }
172
173
    /**
174
     * @param array $sessionInfo
175
     */
176
    public function setSessionInfo($sessionInfo)
177
    {
178
        $this->sessionInfo = $sessionInfo;
179
    }
180
181
    /**
182
     * @return int $id
183
     */
184
    public function getSessionId()
185
    {
186
        return $this->sessionId;
187
    }
188
189
    /**
190
     * @param array $courseInfo
191
     */
192
    public function set_course($courseInfo)
193
    {
194
        $this->course = $courseInfo;
195
    }
196
197
    /**
198
     * @return array
199
     */
200
    public function getTypes()
201
    {
202
        return $this->types;
203
    }
204
205
    /**
206
     * Adds an event to the calendar.
207
     *
208
     * @param string $start                 datetime format: 2012-06-14 09:00:00
209
     * @param string $end                   datetime format: 2012-06-14 09:00:00
210
     * @param string $allDay                (true, false)
211
     * @param string $title
212
     * @param string $content
213
     * @param array  $usersToSend           array('everyone') or a list of user/group ids
214
     * @param bool   $addAsAnnouncement     event as a *course* announcement
215
     * @param int    $parentEventId
216
     * @param array  $attachmentArray       array of $_FILES['']
217
     * @param array  $attachmentCommentList
218
     * @param string $eventComment
219
     * @param string $color
220
     *
221
     * @return int
222
     */
223
    public function addEvent(
224
        $start,
225
        $end,
226
        $allDay,
227
        $title,
228
        $content,
229
        $usersToSend = [],
230
        $addAsAnnouncement = false,
231
        $parentEventId = null,
232
        $attachmentArray = [],
233
        $attachmentCommentList = [],
234
        $eventComment = null,
235
        $color = ''
236
    ) {
237
        $start = api_get_utc_datetime($start);
238
        $end = api_get_utc_datetime($end);
239
        $allDay = isset($allDay) && $allDay === 'true' ? 1 : 0;
240
        $id = null;
241
242
        switch ($this->type) {
243
            case 'personal':
244
                $attributes = [
245
                    'user' => api_get_user_id(),
246
                    'title' => $title,
247
                    'text' => $content,
248
                    'date' => $start,
249
                    'enddate' => $end,
250
                    'all_day' => $allDay,
251
                    'color' => $color,
252
                ];
253
254
                $id = Database::insert(
255
                    $this->tbl_personal_agenda,
256
                    $attributes
257
                );
258
                break;
259
            case 'course':
260
                $attributes = [
261
                    'title' => $title,
262
                    'content' => $content,
263
                    'start_date' => $start,
264
                    'end_date' => $end,
265
                    'all_day' => $allDay,
266
                    'session_id' => $this->getSessionId(),
267
                    'c_id' => $this->course['real_id'],
268
                    'comment' => $eventComment,
269
                    'color' => $color,
270
                ];
271
272
                if (!empty($parentEventId)) {
273
                    $attributes['parent_event_id'] = $parentEventId;
274
                }
275
276
                $senderId = $this->getSenderId();
277
                $sessionId = $this->getSessionId();
278
279
                // Simple course event.
280
                $id = Database::insert($this->tbl_course_agenda, $attributes);
281
282
                if ($id) {
283
                    $sql = "UPDATE ".$this->tbl_course_agenda." SET id = iid WHERE iid = $id";
284
                    Database::query($sql);
285
286
                    $groupId = api_get_group_id();
287
                    $groupInfo = [];
288
                    if ($groupId) {
289
                        $groupInfo = GroupManager::get_group_properties(
290
                            $groupId
291
                        );
292
                    }
293
294
                    if (!empty($usersToSend)) {
295
                        $sendTo = $this->parseSendToArray($usersToSend);
296
                        if ($sendTo['everyone']) {
297
                            api_item_property_update(
298
                                $this->course,
299
                                TOOL_CALENDAR_EVENT,
300
                                $id,
301
                                'AgendaAdded',
302
                                $senderId,
303
                                $groupInfo,
304
                                '',
305
                                $start,
306
                                $end,
307
                                $sessionId
308
                            );
309
                            api_item_property_update(
310
                                $this->course,
311
                                TOOL_CALENDAR_EVENT,
312
                                $id,
313
                                'visible',
314
                                $senderId,
315
                                $groupInfo,
316
                                '',
317
                                $start,
318
                                $end,
319
                                $sessionId
320
                            );
321
                        } else {
322
                            // Storing the selected groups
323
                            if (!empty($sendTo['groups'])) {
324
                                foreach ($sendTo['groups'] as $group) {
325
                                    $groupInfoItem = [];
326
                                    if ($group) {
327
                                        $groupInfoItem = GroupManager::get_group_properties(
328
                                            $group
329
                                        );
330
                                        if ($groupInfoItem) {
331
                                            $groupIidItem = $groupInfoItem['iid'];
332
                                        }
333
                                    }
334
335
                                    api_item_property_update(
336
                                        $this->course,
337
                                        TOOL_CALENDAR_EVENT,
338
                                        $id,
339
                                        'AgendaAdded',
340
                                        $senderId,
341
                                        $groupInfoItem,
342
                                        0,
343
                                        $start,
344
                                        $end,
345
                                        $sessionId
346
                                    );
347
348
                                    api_item_property_update(
349
                                        $this->course,
350
                                        TOOL_CALENDAR_EVENT,
351
                                        $id,
352
                                        'visible',
353
                                        $senderId,
354
                                        $groupInfoItem,
355
                                        0,
356
                                        $start,
357
                                        $end,
358
                                        $sessionId
359
                                    );
360
                                }
361
                            }
362
363
                            // storing the selected users
364
                            if (!empty($sendTo['users'])) {
365
                                foreach ($sendTo['users'] as $userId) {
366
                                    api_item_property_update(
367
                                        $this->course,
368
                                        TOOL_CALENDAR_EVENT,
369
                                        $id,
370
                                        'AgendaAdded',
371
                                        $senderId,
372
                                        $groupInfo,
373
                                        $userId,
374
                                        $start,
375
                                        $end,
376
                                        $sessionId
377
                                    );
378
379
                                    api_item_property_update(
380
                                        $this->course,
381
                                        TOOL_CALENDAR_EVENT,
382
                                        $id,
383
                                        'visible',
384
                                        $senderId,
385
                                        $groupInfo,
386
                                        $userId,
387
                                        $start,
388
                                        $end,
389
                                        $sessionId
390
                                    );
391
                                }
392
                            }
393
                        }
394
                    }
395
396
                    // Add announcement.
397
                    if ($addAsAnnouncement) {
398
                        $this->storeAgendaEventAsAnnouncement(
399
                            $id,
400
                            $usersToSend
401
                        );
402
                    }
403
404
                    // Add attachment.
405
                    if (isset($attachmentArray) && !empty($attachmentArray)) {
406
                        $counter = 0;
407
                        foreach ($attachmentArray as $attachmentItem) {
408
                            $this->addAttachment(
409
                                $id,
410
                                $attachmentItem,
411
                                $attachmentCommentList[$counter],
412
                                $this->course
413
                            );
414
                            $counter++;
415
                        }
416
                    }
417
                }
418
                break;
419
            case 'admin':
420
                if (api_is_platform_admin()) {
421
                    $attributes = [
422
                        'title' => $title,
423
                        'content' => $content,
424
                        'start_date' => $start,
425
                        'end_date' => $end,
426
                        'all_day' => $allDay,
427
                        'access_url_id' => api_get_current_access_url_id(),
428
                    ];
429
430
                    $id = Database::insert(
431
                        $this->tbl_global_agenda,
432
                        $attributes
433
                    );
434
                }
435
                break;
436
        }
437
438
        return $id;
439
    }
440
441
    /**
442
     * @param int $eventId
443
     * @param int $courseId
444
     *
445
     * @return array
446
     */
447
    public function getRepeatedInfoByEvent($eventId, $courseId)
448
    {
449
        $repeatTable = Database::get_course_table(TABLE_AGENDA_REPEAT);
450
        $eventId = intval($eventId);
451
        $courseId = intval($courseId);
452
        $sql = "SELECT * FROM $repeatTable
453
                WHERE c_id = $courseId AND cal_id = $eventId";
454
        $res = Database::query($sql);
455
        $repeatInfo = [];
456
        if (Database::num_rows($res) > 0) {
457
            $repeatInfo = Database::fetch_array($res, 'ASSOC');
458
        }
459
460
        return $repeatInfo;
461
    }
462
463
    /**
464
     * @param int    $eventId
465
     * @param string $type
466
     * @param string $end     in local time
467
     * @param array  $sentTo
468
     *
469
     * @return bool
470
     */
471
    public function addRepeatedItem($eventId, $type, $end, $sentTo = [])
472
    {
473
        $t_agenda = Database::get_course_table(TABLE_AGENDA);
474
        $t_agenda_r = Database::get_course_table(TABLE_AGENDA_REPEAT);
475
476
        if (empty($this->course)) {
477
            return false;
478
        }
479
480
        $course_id = $this->course['real_id'];
481
        $eventId = intval($eventId);
482
483
        $sql = "SELECT title, content, start_date, end_date, all_day
484
                FROM $t_agenda
485
                WHERE c_id = $course_id AND id = $eventId";
486
        $res = Database::query($sql);
487
488
        if (Database::num_rows($res) !== 1) {
489
            return false;
490
        }
491
492
        $row = Database::fetch_array($res);
493
        $origStartDate = api_strtotime($row['start_date'], 'UTC');
494
        $origEndDate = api_strtotime($row['end_date'], 'UTC');
495
        $diff = $origEndDate - $origStartDate;
496
497
        $title = $row['title'];
498
        $content = $row['content'];
499
        $allDay = $row['all_day'];
500
501
        $now = time();
502
        $type = Database::escape_string($type);
503
        $end = api_strtotime($end);
504
505
        if (1 <= $end && $end <= 500) {
506
            // We assume that, with this type of value, the user actually gives a count of repetitions
507
            //and that he wants us to calculate the end date with that (particularly in case of imports from ical)
508
            switch ($type) {
509
                case 'daily':
510
                    $end = $origStartDate + (86400 * $end);
511
                    break;
512
                case 'weekly':
513
                    $end = $this->addWeek($origStartDate, $end);
514
                    break;
515
                case 'monthlyByDate':
516
                    $end = $this->addMonth($origStartDate, $end);
517
                    break;
518
                case 'monthlyByDay':
519
                    //TODO
520
                    break;
521
                case 'monthlyByDayR':
522
                    //TODO
523
                    break;
524
                case 'yearly':
525
                    $end = $this->addYear($origStartDate, $end);
526
                    break;
527
            }
528
        }
529
530
        $typeList = [
531
            'daily',
532
            'weekly',
533
            'monthlyByDate',
534
            'monthlyByDay',
535
            'monthlyByDayR',
536
            'yearly',
537
        ];
538
539
        // The event has to repeat *in the future*. We don't allow repeated
540
        // events in the past
541
        if ($end > $now && in_array($type, $typeList)) {
542
            $sql = "INSERT INTO $t_agenda_r (c_id, cal_id, cal_type, cal_end)
543
                    VALUES ($course_id, '$eventId', '$type', '$end')";
544
            Database::query($sql);
545
546
            switch ($type) {
547
                // @todo improve loop.
548
                case 'daily':
549
                    for ($i = $origStartDate + 86400; $i <= $end; $i += 86400) {
550
                        $start = date('Y-m-d H:i:s', $i);
551
                        $repeatEnd = date('Y-m-d H:i:s', $i + $diff);
552
                        $this->addEvent(
553
                            $start,
554
                            $repeatEnd,
555
                            $allDay,
556
                            $title,
557
                            $content,
558
                            $sentTo,
559
                            false,
560
                            $eventId
561
                        );
562
                    }
563
                    break;
564
                case 'weekly':
565
                    for ($i = $origStartDate + 604800; $i <= $end; $i += 604800) {
566
                        $start = date('Y-m-d H:i:s', $i);
567
                        $repeatEnd = date('Y-m-d H:i:s', $i + $diff);
568
                        $this->addEvent(
569
                            $start,
570
                            $repeatEnd,
571
                            $allDay,
572
                            $title,
573
                            $content,
574
                            $sentTo,
575
                            false,
576
                            $eventId
577
                        );
578
                    }
579
                    break;
580
                case 'monthlyByDate':
581
                    $next_start = $this->addMonth($origStartDate);
582
                    while ($next_start <= $end) {
583
                        $start = date('Y-m-d H:i:s', $next_start);
584
                        $repeatEnd = date('Y-m-d H:i:s', $next_start + $diff);
585
                        $this->addEvent(
586
                            $start,
587
                            $repeatEnd,
588
                            $allDay,
589
                            $title,
590
                            $content,
591
                            $sentTo,
592
                            false,
593
                            $eventId
594
                        );
595
                        $next_start = $this->addMonth($next_start);
596
                    }
597
                    break;
598
                case 'monthlyByDay':
599
                    //not yet implemented
600
                    break;
601
                case 'monthlyByDayR':
602
                    //not yet implemented
603
                    break;
604
                case 'yearly':
605
                    $next_start = $this->addYear($origStartDate);
606
                    while ($next_start <= $end) {
607
                        $start = date('Y-m-d H:i:s', $next_start);
608
                        $repeatEnd = date('Y-m-d H:i:s', $next_start + $diff);
609
                        $this->addEvent(
610
                            $start,
611
                            $repeatEnd,
612
                            $allDay,
613
                            $title,
614
                            $content,
615
                            $sentTo,
616
                            false,
617
                            $eventId
618
                        );
619
                        $next_start = $this->addYear($next_start);
620
                    }
621
                    break;
622
            }
623
        }
624
625
        return true;
626
    }
627
628
    /**
629
     * @param int   $item_id
630
     * @param array $sentTo
631
     *
632
     * @return int
633
     */
634
    public function storeAgendaEventAsAnnouncement($item_id, $sentTo = [])
635
    {
636
        $table_agenda = Database::get_course_table(TABLE_AGENDA);
637
        $course_id = api_get_course_int_id();
638
639
        // Check params
640
        if (empty($item_id) || $item_id != strval(intval($item_id))) {
641
            return -1;
642
        }
643
644
        // Get the agenda item.
645
        $item_id = intval($item_id);
646
        $sql = "SELECT * FROM $table_agenda
647
                WHERE c_id = $course_id AND id = ".$item_id;
648
        $res = Database::query($sql);
649
650
        if (Database::num_rows($res) > 0) {
651
            $row = Database::fetch_array($res, 'ASSOC');
652
653
            // Sending announcement
654
            if (!empty($sentTo)) {
655
                $id = AnnouncementManager::add_announcement(
656
                    api_get_course_info(),
657
                    api_get_session_id(),
658
                    $row['title'],
659
                    $row['content'],
660
                    $sentTo,
661
                    null,
662
                    null,
663
                    $row['end_date']
664
                );
665
666
                AnnouncementManager::sendEmail(
667
                    api_get_course_info(),
668
                    api_get_session_id(),
669
                    $id
670
                );
671
672
                return $id;
673
            }
674
        }
675
676
        return -1;
677
    }
678
679
    /**
680
     * Edits an event.
681
     *
682
     * @param int    $id
683
     * @param string $start                 datetime format: 2012-06-14 09:00:00
684
     * @param string $end                   datetime format: 2012-06-14 09:00:00
685
     * @param int    $allDay                is all day 'true' or 'false'
686
     * @param string $title
687
     * @param string $content
688
     * @param array  $usersToSend
689
     * @param array  $attachmentArray
690
     * @param array  $attachmentCommentList
691
     * @param string $comment
692
     * @param string $color
693
     * @param bool   $addAnnouncement
694
     * @param bool   $updateContent
695
     * @param int    $authorId
696
     *
697
     * @return bool
698
     */
699
    public function editEvent(
700
        $id,
701
        $start,
702
        $end,
703
        $allDay,
704
        $title,
705
        $content,
706
        $usersToSend = [],
707
        $attachmentArray = [],
708
        $attachmentCommentList = [],
709
        $comment = null,
710
        $color = '',
711
        $addAnnouncement = false,
712
        $updateContent = true,
713
        $authorId = 0
714
    ) {
715
        $start = api_get_utc_datetime($start);
716
        $end = api_get_utc_datetime($end);
717
        $allDay = isset($allDay) && $allDay == 'true' ? 1 : 0;
718
        $authorId = empty($authorId) ? api_get_user_id() : (int) $authorId;
719
720
        switch ($this->type) {
721
            case 'personal':
722
                $eventInfo = $this->get_event($id);
723
                if ($eventInfo['user'] != api_get_user_id()) {
724
                    break;
725
                }
726
                $attributes = [
727
                    'title' => $title,
728
                    'date' => $start,
729
                    'enddate' => $end,
730
                    'all_day' => $allDay,
731
                ];
732
733
                if ($updateContent) {
734
                    $attributes['text'] = $content;
735
                }
736
737
                if (!empty($color)) {
738
                    $attributes['color'] = $color;
739
                }
740
741
                Database::update(
742
                    $this->tbl_personal_agenda,
743
                    $attributes,
744
                    ['id = ?' => $id]
745
                );
746
                break;
747
            case 'course':
748
                $eventInfo = $this->get_event($id);
749
750
                if (empty($eventInfo)) {
751
                    return false;
752
                }
753
754
                $groupId = api_get_group_id();
755
                $groupIid = 0;
756
                $groupInfo = [];
757
                if ($groupId) {
758
                    $groupInfo = GroupManager::get_group_properties($groupId);
759
                    if ($groupInfo) {
760
                        $groupIid = $groupInfo['iid'];
761
                    }
762
                }
763
764
                $course_id = $this->course['real_id'];
765
766
                if (empty($course_id)) {
767
                    return false;
768
                }
769
770
                if ($this->getIsAllowedToEdit()) {
771
                    $attributes = [
772
                        'title' => $title,
773
                        'start_date' => $start,
774
                        'end_date' => $end,
775
                        'all_day' => $allDay,
776
                        'comment' => $comment,
777
                    ];
778
779
                    if ($updateContent) {
780
                        $attributes['content'] = $content;
781
                    }
782
783
                    if (!empty($color)) {
784
                        $attributes['color'] = $color;
785
                    }
786
787
                    Database::update(
788
                        $this->tbl_course_agenda,
789
                        $attributes,
790
                        [
791
                            'id = ? AND c_id = ? AND session_id = ? ' => [
792
                                $id,
793
                                $course_id,
794
                                $this->sessionId,
795
                            ],
796
                        ]
797
                    );
798
799
                    if (!empty($usersToSend)) {
800
                        $sendTo = $this->parseSendToArray($usersToSend);
801
802
                        $usersToDelete = array_diff(
803
                            $eventInfo['send_to']['users'],
804
                            $sendTo['users']
805
                        );
806
                        $usersToAdd = array_diff(
807
                            $sendTo['users'],
808
                            $eventInfo['send_to']['users']
809
                        );
810
811
                        $groupsToDelete = array_diff(
812
                            $eventInfo['send_to']['groups'],
813
                            $sendTo['groups']
814
                        );
815
                        $groupToAdd = array_diff(
816
                            $sendTo['groups'],
817
                            $eventInfo['send_to']['groups']
818
                        );
819
820
                        if ($sendTo['everyone']) {
821
                            // Delete all from group
822
                            if (isset($eventInfo['send_to']['groups']) &&
823
                                !empty($eventInfo['send_to']['groups'])
824
                            ) {
825
                                foreach ($eventInfo['send_to']['groups'] as $group) {
826
                                    $groupIidItem = 0;
827
                                    if ($group) {
828
                                        $groupInfoItem = GroupManager::get_group_properties(
829
                                            $group
830
                                        );
831
                                        if ($groupInfoItem) {
832
                                            $groupIidItem = $groupInfoItem['iid'];
833
                                        }
834
                                    }
835
836
                                    api_item_property_delete(
837
                                        $this->course,
838
                                        TOOL_CALENDAR_EVENT,
839
                                        $id,
840
                                        0,
841
                                        $groupIidItem,
842
                                        $this->sessionId
843
                                    );
844
                                }
845
                            }
846
847
                            // Storing the selected users.
848
                            if (isset($eventInfo['send_to']['users']) &&
849
                                !empty($eventInfo['send_to']['users'])
850
                            ) {
851
                                foreach ($eventInfo['send_to']['users'] as $userId) {
852
                                    api_item_property_delete(
853
                                        $this->course,
854
                                        TOOL_CALENDAR_EVENT,
855
                                        $id,
856
                                        $userId,
857
                                        $groupIid,
858
                                        $this->sessionId
859
                                    );
860
                                }
861
                            }
862
863
                            // Add to everyone only.
864
                            api_item_property_update(
865
                                $this->course,
866
                                TOOL_CALENDAR_EVENT,
867
                                $id,
868
                                'visible',
869
                                $authorId,
870
                                $groupInfo,
871
                                null,
872
                                $start,
873
                                $end,
874
                                $this->sessionId
875
                            );
876
                        } else {
877
                            // Delete "everyone".
878
                            api_item_property_delete(
879
                                $this->course,
880
                                TOOL_CALENDAR_EVENT,
881
                                $id,
882
                                0,
883
                                0,
884
                                $this->sessionId
885
                            );
886
887
                            // Add groups
888
                            if (!empty($groupToAdd)) {
889
                                foreach ($groupToAdd as $group) {
890
                                    $groupInfoItem = [];
891
                                    if ($group) {
892
                                        $groupInfoItem = GroupManager::get_group_properties(
893
                                            $group
894
                                        );
895
                                    }
896
897
                                    api_item_property_update(
898
                                        $this->course,
899
                                        TOOL_CALENDAR_EVENT,
900
                                        $id,
901
                                        'visible',
902
                                        $authorId,
903
                                        $groupInfoItem,
904
                                        0,
905
                                        $start,
906
                                        $end,
907
                                        $this->sessionId
908
                                    );
909
                                }
910
                            }
911
912
                            // Delete groups.
913
                            if (!empty($groupsToDelete)) {
914
                                foreach ($groupsToDelete as $group) {
915
                                    $groupIidItem = 0;
916
                                    $groupInfoItem = [];
917
                                    if ($group) {
918
                                        $groupInfoItem = GroupManager::get_group_properties(
919
                                            $group
920
                                        );
921
                                        if ($groupInfoItem) {
922
                                            $groupIidItem = $groupInfoItem['iid'];
923
                                        }
924
                                    }
925
926
                                    api_item_property_delete(
927
                                        $this->course,
928
                                        TOOL_CALENDAR_EVENT,
929
                                        $id,
930
                                        0,
931
                                        $groupIidItem,
932
                                        $this->sessionId
933
                                    );
934
                                }
935
                            }
936
937
                            // Add users.
938
                            if (!empty($usersToAdd)) {
939
                                foreach ($usersToAdd as $userId) {
940
                                    api_item_property_update(
941
                                        $this->course,
942
                                        TOOL_CALENDAR_EVENT,
943
                                        $id,
944
                                        'visible',
945
                                        $authorId,
946
                                        $groupInfo,
947
                                        $userId,
948
                                        $start,
949
                                        $end,
950
                                        $this->sessionId
951
                                    );
952
                                }
953
                            }
954
955
                            // Delete users.
956
                            if (!empty($usersToDelete)) {
957
                                foreach ($usersToDelete as $userId) {
958
                                    api_item_property_delete(
959
                                        $this->course,
960
                                        TOOL_CALENDAR_EVENT,
961
                                        $id,
962
                                        $userId,
963
                                        $groupInfo,
964
                                        $this->sessionId
965
                                    );
966
                                }
967
                            }
968
                        }
969
                    }
970
971
                    // Add announcement.
972
                    if (isset($addAnnouncement) && !empty($addAnnouncement)) {
973
                        $this->storeAgendaEventAsAnnouncement(
974
                            $id,
975
                            $usersToSend
976
                        );
977
                    }
978
979
                    // Add attachment.
980
                    if (isset($attachmentArray) && !empty($attachmentArray)) {
981
                        $counter = 0;
982
                        foreach ($attachmentArray as $attachmentItem) {
983
                            $this->updateAttachment(
984
                                $attachmentItem['id'],
985
                                $id,
986
                                $attachmentItem,
987
                                $attachmentCommentList[$counter],
988
                                $this->course
989
                            );
990
                            $counter++;
991
                        }
992
                    }
993
994
                    return true;
995
                } else {
996
                    return false;
997
                }
998
                break;
999
            case 'admin':
1000
            case 'platform':
1001
                if (api_is_platform_admin()) {
1002
                    $attributes = [
1003
                        'title' => $title,
1004
                        'start_date' => $start,
1005
                        'end_date' => $end,
1006
                        'all_day' => $allDay,
1007
                    ];
1008
1009
                    if ($updateContent) {
1010
                        $attributes['content'] = $content;
1011
                    }
1012
                    Database::update(
1013
                        $this->tbl_global_agenda,
1014
                        $attributes,
1015
                        ['id = ?' => $id]
1016
                    );
1017
                }
1018
                break;
1019
        }
1020
    }
1021
1022
    /**
1023
     * @param int  $id
1024
     * @param bool $deleteAllItemsFromSerie
1025
     */
1026
    public function deleteEvent($id, $deleteAllItemsFromSerie = false)
1027
    {
1028
        switch ($this->type) {
1029
            case 'personal':
1030
                $eventInfo = $this->get_event($id);
1031
                if ($eventInfo['user'] == api_get_user_id()) {
1032
                    Database::delete(
1033
                        $this->tbl_personal_agenda,
1034
                        ['id = ?' => $id]
1035
                    );
1036
                }
1037
                break;
1038
            case 'course':
1039
                $course_id = api_get_course_int_id();
1040
                $sessionId = api_get_session_id();
1041
                $isAllowToEdit = api_is_allowed_to_edit(null, true);
1042
1043
                if ($isAllowToEdit == false && !empty($sessionId)) {
1044
                    $allowDhrToEdit = api_get_configuration_value('allow_agenda_edit_for_hrm');
1045
                    if ($allowDhrToEdit) {
1046
                        $isHrm = SessionManager::isUserSubscribedAsHRM(
1047
                            $sessionId,
1048
                            api_get_user_id()
1049
                        );
1050
                        if ($isHrm) {
1051
                            $isAllowToEdit = true;
1052
                        }
1053
                    }
1054
                }
1055
1056
                if (!empty($course_id) && $isAllowToEdit) {
1057
                    // Delete
1058
                    $eventInfo = $this->get_event($id);
1059
                    if ($deleteAllItemsFromSerie) {
1060
                        /* This is one of the children.
1061
                           Getting siblings and delete 'Em all + the father! */
1062
                        if (isset($eventInfo['parent_event_id']) && !empty($eventInfo['parent_event_id'])) {
1063
                            // Removing items.
1064
                            $events = $this->getAllRepeatEvents(
1065
                                $eventInfo['parent_event_id']
1066
                            );
1067
                            if (!empty($events)) {
1068
                                foreach ($events as $event) {
1069
                                    $this->deleteEvent($event['id']);
1070
                                }
1071
                            }
1072
                            // Removing parent.
1073
                            $this->deleteEvent($eventInfo['parent_event_id']);
1074
                        } else {
1075
                            // This is the father looking for the children.
1076
                            $events = $this->getAllRepeatEvents($id);
1077
                            if (!empty($events)) {
1078
                                foreach ($events as $event) {
1079
                                    $this->deleteEvent($event['id']);
1080
                                }
1081
                            }
1082
                        }
1083
                    }
1084
1085
                    // Removing from events.
1086
                    Database::delete(
1087
                        $this->tbl_course_agenda,
1088
                        ['id = ? AND c_id = ?' => [$id, $course_id]]
1089
                    );
1090
1091
                    api_item_property_update(
1092
                        $this->course,
1093
                        TOOL_CALENDAR_EVENT,
1094
                        $id,
1095
                        'delete',
1096
                        api_get_user_id()
1097
                    );
1098
1099
                    // Removing from series.
1100
                    Database::delete(
1101
                        $this->table_repeat,
1102
                        [
1103
                            'cal_id = ? AND c_id = ?' => [
1104
                                $id,
1105
                                $course_id,
1106
                            ],
1107
                        ]
1108
                    );
1109
1110
                    if (isset($eventInfo['attachment']) && !empty($eventInfo['attachment'])) {
1111
                        foreach ($eventInfo['attachment'] as $attachment) {
1112
                            self::deleteAttachmentFile(
1113
                                $attachment['id'],
1114
                                $this->course
1115
                            );
1116
                        }
1117
                    }
1118
                }
1119
                break;
1120
            case 'admin':
1121
                if (api_is_platform_admin()) {
1122
                    Database::delete(
1123
                        $this->tbl_global_agenda,
1124
                        ['id = ?' => $id]
1125
                    );
1126
                }
1127
                break;
1128
        }
1129
    }
1130
1131
    /**
1132
     * Get agenda events.
1133
     *
1134
     * @param int    $start
1135
     * @param int    $end
1136
     * @param int    $course_id
1137
     * @param int    $groupId
1138
     * @param int    $user_id
1139
     * @param string $format
1140
     *
1141
     * @return array|string
1142
     */
1143
    public function getEvents(
1144
        $start,
1145
        $end,
1146
        $course_id = null,
1147
        $groupId = null,
1148
        $user_id = 0,
1149
        $format = 'json'
1150
    ) {
1151
        switch ($this->type) {
1152
            case 'admin':
1153
                $this->getPlatformEvents($start, $end);
1154
                break;
1155
            case 'course':
1156
                $courseInfo = api_get_course_info_by_id($course_id);
1157
1158
                // Session coach can see all events inside a session.
1159
                if (api_is_coach()) {
1160
                    // Own course
1161
                    $this->getCourseEvents(
1162
                        $start,
1163
                        $end,
1164
                        $courseInfo,
1165
                        $groupId,
1166
                        $this->sessionId,
1167
                        $user_id
1168
                    );
1169
1170
                    // Others
1171
                    $this->getSessionEvents(
1172
                        $start,
1173
                        $end,
1174
                        $this->sessionId,
1175
                        $user_id,
1176
                        $this->eventOtherSessionColor
1177
                    );
1178
                } else {
1179
                    $this->getCourseEvents(
1180
                        $start,
1181
                        $end,
1182
                        $courseInfo,
1183
                        $groupId,
1184
                        $this->sessionId,
1185
                        $user_id
1186
                    );
1187
                }
1188
                break;
1189
            case 'personal':
1190
            default:
1191
                $sessionFilterActive = false;
1192
                if (!empty($this->sessionId)) {
1193
                    $sessionFilterActive = true;
1194
                }
1195
1196
                if ($sessionFilterActive == false) {
1197
                    // Getting personal events
1198
                    $this->getPersonalEvents($start, $end);
1199
1200
                    // Getting platform/admin events
1201
                    $this->getPlatformEvents($start, $end);
1202
                }
1203
1204
                $ignoreVisibility = api_get_configuration_value('personal_agenda_show_all_session_events');
1205
1206
                // Getting course events
1207
                $my_course_list = [];
1208
                if (!api_is_anonymous()) {
1209
                    $session_list = SessionManager::get_sessions_by_user(
1210
                        api_get_user_id(),
1211
                        $ignoreVisibility
1212
                    );
1213
                    $my_course_list = CourseManager::get_courses_list_by_user_id(
1214
                        api_get_user_id(),
1215
                        false
1216
                    );
1217
                }
1218
1219
                if (api_is_drh()) {
1220
                    if (api_drh_can_access_all_session_content()) {
1221
                        $session_list = [];
1222
                        $sessionList = SessionManager::get_sessions_followed_by_drh(
1223
                            api_get_user_id(),
1224
                            null,
1225
                            null,
1226
                            null,
1227
                            true,
1228
                            false
1229
                        );
1230
1231
                        if (!empty($sessionList)) {
1232
                            foreach ($sessionList as $sessionItem) {
1233
                                $sessionId = $sessionItem['id'];
1234
                                $courses = SessionManager::get_course_list_by_session_id(
1235
                                    $sessionId
1236
                                );
1237
                                $sessionInfo = [
1238
                                    'session_id' => $sessionId,
1239
                                    'courses' => $courses,
1240
                                ];
1241
                                $session_list[] = $sessionInfo;
1242
                            }
1243
                        }
1244
                    }
1245
                }
1246
1247
                if (!empty($session_list)) {
1248
                    foreach ($session_list as $session_item) {
1249
                        if ($sessionFilterActive) {
1250
                            if ($this->sessionId != $session_item['session_id']) {
1251
                                continue;
1252
                            }
1253
                        }
1254
1255
                        $my_courses = $session_item['courses'];
1256
                        $my_session_id = $session_item['session_id'];
1257
1258
                        if (!empty($my_courses)) {
1259
                            foreach ($my_courses as $course_item) {
1260
                                $courseInfo = api_get_course_info_by_id(
1261
                                    $course_item['real_id']
1262
                                );
1263
                                $this->getCourseEvents(
1264
                                    $start,
1265
                                    $end,
1266
                                    $courseInfo,
1267
                                    0,
1268
                                    $my_session_id
1269
                                );
1270
                            }
1271
                        }
1272
                    }
1273
                }
1274
1275
                if (!empty($my_course_list) && $sessionFilterActive == false) {
1276
                    foreach ($my_course_list as $courseInfoItem) {
1277
                        $courseInfo = api_get_course_info_by_id(
1278
                            $courseInfoItem['real_id']
1279
                        );
1280
                        if (isset($course_id) && !empty($course_id)) {
1281
                            if ($courseInfo['real_id'] == $course_id) {
1282
                                $this->getCourseEvents(
1283
                                    $start,
1284
                                    $end,
1285
                                    $courseInfo,
1286
                                    0,
1287
                                    0,
1288
                                    $user_id
1289
                                );
1290
                            }
1291
                        } else {
1292
                            $this->getCourseEvents(
1293
                                $start,
1294
                                $end,
1295
                                $courseInfo,
1296
                                0,
1297
                                0,
1298
                                $user_id
1299
                            );
1300
                        }
1301
                    }
1302
                }
1303
                break;
1304
        }
1305
1306
        switch ($format) {
1307
            case 'json':
1308
                if (empty($this->events)) {
1309
                    return '[]';
1310
                }
1311
1312
                return json_encode($this->events);
1313
                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...
1314
            case 'array':
1315
                if (empty($this->events)) {
1316
                    return [];
1317
                }
1318
1319
                return $this->events;
1320
                break;
1321
        }
1322
    }
1323
1324
    /**
1325
     * @param int $id
1326
     * @param int $minute_delta
1327
     *
1328
     * @return int
1329
     */
1330
    public function resizeEvent($id, $minute_delta)
1331
    {
1332
        $id = (int) $id;
1333
        $delta = (int) $minute_delta;
1334
        $event = $this->get_event($id);
1335
        if (!empty($event)) {
1336
            switch ($this->type) {
1337
                case 'personal':
1338
                    $sql = "UPDATE $this->tbl_personal_agenda SET
1339
                            enddate = DATE_ADD(enddate, INTERVAL $delta MINUTE)
1340
							WHERE id = ".$id;
1341
                    Database::query($sql);
1342
                    break;
1343
                case 'course':
1344
                    $sql = "UPDATE $this->tbl_course_agenda SET
1345
                            end_date = DATE_ADD(end_date, INTERVAL $delta MINUTE)
1346
							WHERE 
1347
							    c_id = ".$this->course['real_id']." AND 
1348
							    id = ".$id;
1349
                    Database::query($sql);
1350
                    break;
1351
                case 'admin':
1352
                    $sql = "UPDATE $this->tbl_global_agenda SET
1353
                            end_date = DATE_ADD(end_date, INTERVAL $delta MINUTE)
1354
							WHERE id = ".$id;
1355
                    Database::query($sql);
1356
                    break;
1357
            }
1358
        }
1359
1360
        return 1;
1361
    }
1362
1363
    /**
1364
     * @param int $id
1365
     * @param int $minute_delta minutes
1366
     * @param int $allDay
1367
     *
1368
     * @return int
1369
     */
1370
    public function move_event($id, $minute_delta, $allDay)
1371
    {
1372
        $id = (int) $id;
1373
        $event = $this->get_event($id);
1374
1375
        if (empty($event)) {
1376
            return false;
1377
        }
1378
1379
        // we convert the hour delta into minutes and add the minute delta
1380
        $delta = (int) $minute_delta;
1381
        $allDay = (int) $allDay;
1382
1383
        if (!empty($event)) {
1384
            switch ($this->type) {
1385
                case 'personal':
1386
                    $sql = "UPDATE $this->tbl_personal_agenda SET
1387
                            all_day = $allDay, date = DATE_ADD(date, INTERVAL $delta MINUTE),
1388
                            enddate = DATE_ADD(enddate, INTERVAL $delta MINUTE)
1389
							WHERE id=".$id;
1390
                    Database::query($sql);
1391
                    break;
1392
                case 'course':
1393
                    $sql = "UPDATE $this->tbl_course_agenda SET
1394
                            all_day = $allDay, 
1395
                            start_date = DATE_ADD(start_date, INTERVAL $delta MINUTE),
1396
                            end_date = DATE_ADD(end_date, INTERVAL $delta MINUTE)
1397
							WHERE 
1398
							    c_id = ".$this->course['real_id']." AND 
1399
							    id=".$id;
1400
                    Database::query($sql);
1401
                    break;
1402
                case 'admin':
1403
                    $sql = "UPDATE $this->tbl_global_agenda SET
1404
                            all_day = $allDay,
1405
                            start_date = DATE_ADD(start_date,INTERVAL $delta MINUTE),
1406
                            end_date = DATE_ADD(end_date, INTERVAL $delta MINUTE)
1407
							WHERE id=".$id;
1408
                    Database::query($sql);
1409
                    break;
1410
            }
1411
        }
1412
1413
        return 1;
1414
    }
1415
1416
    /**
1417
     * Gets a single event.
1418
     *
1419
     * @param int $id event id
1420
     *
1421
     * @return array
1422
     */
1423
    public function get_event($id)
1424
    {
1425
        // make sure events of the personal agenda can only be seen by the user himself
1426
        $id = (int) $id;
1427
        $event = null;
1428
        switch ($this->type) {
1429
            case 'personal':
1430
                $sql = "SELECT * FROM ".$this->tbl_personal_agenda."
1431
                        WHERE id = $id AND user = ".api_get_user_id();
1432
                $result = Database::query($sql);
1433
                if (Database::num_rows($result)) {
1434
                    $event = Database::fetch_array($result, 'ASSOC');
1435
                    $event['description'] = $event['text'];
1436
                    $event['content'] = $event['text'];
1437
                    $event['start_date'] = $event['date'];
1438
                    $event['end_date'] = $event['enddate'];
1439
                }
1440
                break;
1441
            case 'course':
1442
                if (!empty($this->course['real_id'])) {
1443
                    $sql = "SELECT * FROM ".$this->tbl_course_agenda."
1444
                            WHERE c_id = ".$this->course['real_id']." AND id = ".$id;
1445
                    $result = Database::query($sql);
1446
                    if (Database::num_rows($result)) {
1447
                        $event = Database::fetch_array($result, 'ASSOC');
1448
                        $event['description'] = $event['content'];
1449
1450
                        // Getting send to array
1451
                        $event['send_to'] = $this->getUsersAndGroupSubscribedToEvent(
1452
                            $id,
1453
                            $this->course['real_id'],
1454
                            $this->sessionId
1455
                        );
1456
1457
                        // Getting repeat info
1458
                        $event['repeat_info'] = $this->getRepeatedInfoByEvent(
1459
                            $id,
1460
                            $this->course['real_id']
1461
                        );
1462
1463
                        if (!empty($event['parent_event_id'])) {
1464
                            $event['parent_info'] = $this->get_event(
1465
                                $event['parent_event_id']
1466
                            );
1467
                        }
1468
1469
                        $event['attachment'] = $this->getAttachmentList(
1470
                            $id,
1471
                            $this->course
1472
                        );
1473
                    }
1474
                }
1475
                break;
1476
            case 'admin':
1477
            case 'platform':
1478
                $sql = "SELECT * FROM ".$this->tbl_global_agenda."
1479
                        WHERE id = $id";
1480
                $result = Database::query($sql);
1481
                if (Database::num_rows($result)) {
1482
                    $event = Database::fetch_array($result, 'ASSOC');
1483
                    $event['description'] = $event['content'];
1484
                }
1485
                break;
1486
        }
1487
1488
        return $event;
1489
    }
1490
1491
    /**
1492
     * Gets personal events.
1493
     *
1494
     * @param int $start
1495
     * @param int $end
1496
     *
1497
     * @return array
1498
     */
1499
    public function getPersonalEvents($start, $end)
1500
    {
1501
        $start = intval($start);
1502
        $end = intval($end);
1503
        $startCondition = '';
1504
        $endCondition = '';
1505
1506
        if ($start !== 0) {
1507
            $start = api_get_utc_datetime($start);
1508
            $startCondition = "AND date >= '".$start."'";
1509
        }
1510
        if ($start !== 0) {
1511
            $end = api_get_utc_datetime($end);
1512
            $endCondition = "AND (enddate <= '".$end."' OR enddate IS NULL)";
1513
        }
1514
        $user_id = api_get_user_id();
1515
1516
        $sql = "SELECT * FROM ".$this->tbl_personal_agenda."
1517
                WHERE user = $user_id $startCondition $endCondition";
1518
1519
        $result = Database::query($sql);
1520
        $my_events = [];
1521
        if (Database::num_rows($result)) {
1522
            while ($row = Database::fetch_array($result, 'ASSOC')) {
1523
                $event = [];
1524
                $event['id'] = 'personal_'.$row['id'];
1525
                $event['title'] = $row['title'];
1526
                $event['className'] = 'personal';
1527
                $event['borderColor'] = $event['backgroundColor'] = $this->event_personal_color;
1528
                $event['editable'] = true;
1529
                $event['sent_to'] = get_lang('Me');
1530
                $event['type'] = 'personal';
1531
1532
                if (!empty($row['date'])) {
1533
                    $event['start'] = $this->formatEventDate($row['date']);
1534
                    $event['start_date_localtime'] = api_get_local_time(
1535
                        $row['date']
1536
                    );
1537
                }
1538
1539
                if (!empty($row['enddate'])) {
1540
                    $event['end'] = $this->formatEventDate($row['enddate']);
1541
                    $event['end_date_localtime'] = api_get_local_time(
1542
                        $row['enddate']
1543
                    );
1544
                }
1545
1546
                $event['description'] = $row['text'];
1547
                $event['allDay'] = isset($row['all_day']) && $row['all_day'] == 1 ? $row['all_day'] : 0;
1548
                $event['parent_event_id'] = 0;
1549
                $event['has_children'] = 0;
1550
1551
                $my_events[] = $event;
1552
                $this->events[] = $event;
1553
            }
1554
        }
1555
1556
        return $my_events;
1557
    }
1558
1559
    /**
1560
     * Get user/group list per event.
1561
     *
1562
     * @param int $eventId
1563
     * @param int $courseId
1564
     * @param int $sessionId
1565
     * @paraù int $sessionId
1566
     *
1567
     * @return array
1568
     */
1569
    public function getUsersAndGroupSubscribedToEvent(
1570
        $eventId,
1571
        $courseId,
1572
        $sessionId
1573
    ) {
1574
        $eventId = (int) $eventId;
1575
        $courseId = (int) $courseId;
1576
        $sessionId = (int) $sessionId;
1577
1578
        $sessionCondition = "ip.session_id = $sessionId";
1579
        if (empty($sessionId)) {
1580
            $sessionCondition = " (ip.session_id = 0 OR ip.session_id IS NULL) ";
1581
        }
1582
1583
        $tlb_course_agenda = Database::get_course_table(TABLE_AGENDA);
1584
        $tbl_property = Database::get_course_table(TABLE_ITEM_PROPERTY);
1585
1586
        // Get sent_tos
1587
        $sql = "SELECT DISTINCT to_user_id, to_group_id
1588
                FROM $tbl_property ip
1589
                INNER JOIN $tlb_course_agenda agenda
1590
                ON (
1591
                  ip.ref = agenda.id AND
1592
                  ip.c_id = agenda.c_id AND
1593
                  ip.tool = '".TOOL_CALENDAR_EVENT."'
1594
                )
1595
                WHERE
1596
                    ref = $eventId AND
1597
                    ip.visibility = '1' AND
1598
                    ip.c_id = $courseId AND
1599
                    $sessionCondition
1600
                ";
1601
1602
        $result = Database::query($sql);
1603
        $users = [];
1604
        $groups = [];
1605
        $everyone = false;
1606
1607
        while ($row = Database::fetch_array($result, 'ASSOC')) {
1608
            if (!empty($row['to_group_id'])) {
1609
                $groups[] = $row['to_group_id'];
1610
            }
1611
            if (!empty($row['to_user_id'])) {
1612
                $users[] = $row['to_user_id'];
1613
            }
1614
1615
            if (empty($groups) && empty($users)) {
1616
                if ($row['to_group_id'] == 0) {
1617
                    $everyone = true;
1618
                }
1619
            }
1620
        }
1621
1622
        return [
1623
            'everyone' => $everyone,
1624
            'users' => $users,
1625
            'groups' => $groups,
1626
        ];
1627
    }
1628
1629
    /**
1630
     * @param int    $start
1631
     * @param int    $end
1632
     * @param int    $sessionId
1633
     * @param int    $userId
1634
     * @param string $color
1635
     *
1636
     * @return array
1637
     */
1638
    public function getSessionEvents(
1639
        $start,
1640
        $end,
1641
        $sessionId = 0,
1642
        $userId = 0,
1643
        $color = ''
1644
    ) {
1645
        $courses = SessionManager::get_course_list_by_session_id($sessionId);
1646
1647
        if (!empty($courses)) {
1648
            foreach ($courses as $course) {
1649
                $this->getCourseEvents(
1650
                    $start,
1651
                    $end,
1652
                    $course,
1653
                    0,
1654
                    $sessionId,
1655
                    0,
1656
                    $color
1657
                );
1658
            }
1659
        }
1660
    }
1661
1662
    /**
1663
     * @param int    $start
1664
     * @param int    $end
1665
     * @param array  $courseInfo
1666
     * @param int    $groupId
1667
     * @param int    $sessionId
1668
     * @param int    $user_id
1669
     * @param string $color
1670
     *
1671
     * @return array
1672
     */
1673
    public function getCourseEvents(
1674
        $start,
1675
        $end,
1676
        $courseInfo,
1677
        $groupId = 0,
1678
        $sessionId = 0,
1679
        $user_id = 0,
1680
        $color = ''
1681
    ) {
1682
        $start = isset($start) && !empty($start) ? api_get_utc_datetime(intval($start)) : null;
1683
        $end = isset($end) && !empty($end) ? api_get_utc_datetime(intval($end)) : null;
1684
1685
        if (empty($courseInfo)) {
1686
            return [];
1687
        }
1688
        $courseId = $courseInfo['real_id'];
1689
1690
        if (empty($courseId)) {
1691
            return [];
1692
        }
1693
1694
        $sessionId = (int) $sessionId;
1695
        $user_id = (int) $user_id;
1696
1697
        $groupList = GroupManager::get_group_list(
1698
            null,
1699
            $courseInfo,
1700
            null,
1701
            $sessionId
1702
        );
1703
1704
        $groupNameList = [];
1705
        if (!empty($groupList)) {
1706
            foreach ($groupList as $group) {
1707
                $groupNameList[$group['iid']] = $group['name'];
1708
            }
1709
        }
1710
1711
        if (api_is_platform_admin() || api_is_allowed_to_edit()) {
1712
            $isAllowToEdit = true;
1713
        } else {
1714
            $isAllowToEdit = CourseManager::is_course_teacher(
1715
                api_get_user_id(),
1716
                $courseInfo['code']
1717
            );
1718
        }
1719
1720
        $isAllowToEditByHrm = false;
1721
        if (!empty($sessionId)) {
1722
            $allowDhrToEdit = api_get_configuration_value('allow_agenda_edit_for_hrm');
1723
            if ($allowDhrToEdit) {
1724
                $isHrm = SessionManager::isUserSubscribedAsHRM($sessionId, api_get_user_id());
1725
                if ($isHrm) {
1726
                    $isAllowToEdit = $isAllowToEditByHrm = true;
1727
                }
1728
            }
1729
        }
1730
1731
        $groupMemberships = [];
1732
        if (!empty($groupId)) {
1733
            $groupMemberships = [$groupId];
1734
        } else {
1735
            if ($isAllowToEdit) {
1736
                if (!empty($groupList)) {
1737
                    // c_item_property.to_group_id field was migrated to use
1738
                    // c_group_info.iid
1739
                    $groupMemberships = array_column($groupList, 'iid');
1740
                }
1741
            } else {
1742
                // get only related groups from user
1743
                $groupMemberships = GroupManager::get_group_ids(
1744
                    $courseId,
1745
                    api_get_user_id()
1746
                );
1747
            }
1748
        }
1749
1750
        $tlb_course_agenda = Database::get_course_table(TABLE_AGENDA);
1751
        $tbl_property = Database::get_course_table(TABLE_ITEM_PROPERTY);
1752
1753
        if (empty($sessionId)) {
1754
            $sessionCondition = "
1755
            (
1756
                agenda.session_id = 0 AND (ip.session_id IS NULL OR ip.session_id = 0)
1757
            ) ";
1758
        } else {
1759
            $sessionCondition = "
1760
            (
1761
                agenda.session_id = $sessionId AND
1762
                ip.session_id = $sessionId
1763
            ) ";
1764
        }
1765
1766
        if ($isAllowToEdit) {
1767
            // No group filter was asked
1768
            if (empty($groupId)) {
1769
                if (empty($user_id)) {
1770
                    // Show all events not added in group
1771
                    $userCondition = ' (ip.to_group_id IS NULL OR ip.to_group_id = 0) ';
1772
                    // admin see only his stuff
1773
                    if ($this->type === 'personal') {
1774
                        $userCondition = " (ip.to_user_id = ".api_get_user_id()." AND (ip.to_group_id IS NULL OR ip.to_group_id = 0) ) ";
1775
                        $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) ) ";
1776
                    }
1777
1778
                    if (!empty($groupMemberships)) {
1779
                        // Show events sent to selected groups
1780
                        $userCondition .= " OR (ip.to_user_id = 0 OR ip.to_user_id is NULL) AND (ip.to_group_id IN (".implode(", ", $groupMemberships).")) ";
1781
                    }
1782
                } else {
1783
                    // Show events of requested user in no group
1784
                    $userCondition = " (ip.to_user_id = $user_id AND (ip.to_group_id IS NULL OR ip.to_group_id = 0)) ";
1785
                    // Show events sent to selected groups
1786
                    if (!empty($groupMemberships)) {
1787
                        $userCondition .= " OR (ip.to_user_id = $user_id) AND (ip.to_group_id IN (".implode(", ", $groupMemberships).")) ";
1788
                    }
1789
                }
1790
            } else {
1791
                // Show only selected groups (depending of user status)
1792
                $userCondition = " (ip.to_user_id = 0 OR ip.to_user_id is NULL) AND (ip.to_group_id IN (".implode(", ", $groupMemberships).")) ";
1793
1794
                if (!empty($groupMemberships)) {
1795
                    // Show send to $user_id in selected groups
1796
                    $userCondition .= " OR (ip.to_user_id = $user_id) AND (ip.to_group_id IN (".implode(", ", $groupMemberships).")) ";
1797
                }
1798
            }
1799
        } else {
1800
            // No group filter was asked
1801
            if (empty($groupId)) {
1802
                // Show events sent to everyone and no group
1803
                $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) ';
1804
1805
                // Show events sent to selected groups
1806
                if (!empty($groupMemberships)) {
1807
                    $userCondition .= " OR (ip.to_user_id = 0 OR ip.to_user_id is NULL) AND (ip.to_group_id IN (".implode(", ", $groupMemberships)."))) ";
1808
                } else {
1809
                    $userCondition .= " ) ";
1810
                }
1811
                $userCondition .= " OR (ip.to_user_id = ".api_get_user_id()." AND (ip.to_group_id IS NULL OR ip.to_group_id = 0)) ";
1812
            } else {
1813
                if (!empty($groupMemberships)) {
1814
                    // Show send to everyone - and only selected groups
1815
                    $userCondition = " (ip.to_user_id = 0 OR ip.to_user_id is NULL) AND (ip.to_group_id IN (".implode(", ", $groupMemberships).")) ";
1816
                }
1817
            }
1818
1819
            // Show sent to only me and no group
1820
            if (!empty($groupMemberships)) {
1821
                $userCondition .= " OR (ip.to_user_id = ".api_get_user_id().") AND (ip.to_group_id IN (".implode(", ", $groupMemberships).")) ";
1822
            } else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
1823
                // Show sent to only me and selected groups
1824
            }
1825
        }
1826
1827
        if (api_is_allowed_to_edit()) {
1828
            $visibilityCondition = " (ip.visibility IN ('1', '0'))  ";
1829
        } else {
1830
            $visibilityCondition = " (ip.visibility = '1') ";
1831
        }
1832
1833
        $sql = "SELECT DISTINCT
1834
                    agenda.*,
1835
                    ip.visibility,
1836
                    ip.to_group_id,
1837
                    ip.insert_user_id,
1838
                    ip.ref,
1839
                    to_user_id
1840
                FROM $tlb_course_agenda agenda
1841
                INNER JOIN $tbl_property ip
1842
                ON (
1843
                    agenda.id = ip.ref AND 
1844
                    agenda.c_id = ip.c_id AND 
1845
                    ip.tool = '".TOOL_CALENDAR_EVENT."'
1846
                )
1847
                WHERE
1848
                    $sessionCondition AND
1849
                    ($userCondition) AND
1850
                    $visibilityCondition AND
1851
                    agenda.c_id = $courseId
1852
        ";
1853
        $dateCondition = '';
1854
        if (!empty($start) && !empty($end)) {
1855
            $dateCondition .= "AND (
1856
                 agenda.start_date BETWEEN '".$start."' AND '".$end."' OR
1857
                 agenda.end_date BETWEEN '".$start."' AND '".$end."' OR
1858
                 (
1859
                     agenda.start_date IS NOT NULL AND agenda.end_date IS NOT NULL AND
1860
                     YEAR(agenda.start_date) = YEAR(agenda.end_date) AND
1861
                     MONTH('$start') BETWEEN MONTH(agenda.start_date) AND MONTH(agenda.end_date)
1862
                 )
1863
            )";
1864
        }
1865
1866
        $sql .= $dateCondition;
1867
        $result = Database::query($sql);
1868
1869
        $coachCanEdit = false;
1870
        if (!empty($sessionId)) {
1871
            $coachCanEdit = api_is_coach($sessionId, $courseId) || api_is_platform_admin();
1872
        }
1873
1874
        if (Database::num_rows($result)) {
1875
            $eventsAdded = array_column($this->events, 'unique_id');
1876
            while ($row = Database::fetch_array($result, 'ASSOC')) {
1877
                $event = [];
1878
                $event['id'] = 'course_'.$row['id'];
1879
                $event['unique_id'] = $row['iid'];
1880
                // To avoid doubles
1881
                if (in_array($event['unique_id'], $eventsAdded)) {
1882
                    continue;
1883
                }
1884
1885
                $eventsAdded[] = $event['unique_id'];
1886
                $eventId = $row['ref'];
1887
                $items = $this->getUsersAndGroupSubscribedToEvent(
1888
                    $eventId,
1889
                    $courseId,
1890
                    $this->sessionId
1891
                );
1892
                $group_to_array = $items['groups'];
1893
                $user_to_array = $items['users'];
1894
                $attachmentList = $this->getAttachmentList(
1895
                    $row['id'],
1896
                    $courseInfo
1897
                );
1898
                $event['attachment'] = '';
1899
                if (!empty($attachmentList)) {
1900
                    foreach ($attachmentList as $attachment) {
1901
                        $has_attachment = Display::return_icon(
1902
                            'attachment.gif',
1903
                            get_lang('Attachment')
1904
                        );
1905
                        $user_filename = $attachment['filename'];
1906
                        $url = api_get_path(WEB_CODE_PATH).'calendar/download.php?file='.$attachment['path'].'&course_id='.$courseId.'&'.api_get_cidreq();
1907
                        $event['attachment'] .= $has_attachment.
1908
                            Display::url(
1909
                                $user_filename,
1910
                                $url
1911
                            ).'<br />';
1912
                    }
1913
                }
1914
1915
                $event['title'] = $row['title'];
1916
                $event['className'] = 'course';
1917
                $event['allDay'] = 'false';
1918
                $event['course_id'] = $courseId;
1919
                $event['borderColor'] = $event['backgroundColor'] = $this->event_course_color;
1920
1921
                $sessionInfo = [];
1922
                if (isset($row['session_id']) && !empty($row['session_id'])) {
1923
                    $sessionInfo = api_get_session_info($sessionId);
1924
                    $event['borderColor'] = $event['backgroundColor'] = $this->event_session_color;
1925
                }
1926
1927
                $event['session_name'] = isset($sessionInfo['name']) ? $sessionInfo['name'] : '';
1928
                $event['course_name'] = isset($courseInfo['title']) ? $courseInfo['title'] : '';
1929
1930
                if (isset($row['to_group_id']) && !empty($row['to_group_id'])) {
1931
                    $event['borderColor'] = $event['backgroundColor'] = $this->event_group_color;
1932
                }
1933
1934
                if (!empty($color)) {
1935
                    $event['borderColor'] = $event['backgroundColor'] = $color;
1936
                }
1937
1938
                if (isset($row['color']) && !empty($row['color'])) {
1939
                    $event['borderColor'] = $event['backgroundColor'] = $row['color'];
1940
                }
1941
1942
                $event['editable'] = false;
1943
                if ($this->getIsAllowedToEdit() && $this->type == 'course') {
1944
                    $event['editable'] = true;
1945
                    if (!empty($sessionId)) {
1946
                        if ($coachCanEdit == false) {
1947
                            $event['editable'] = false;
1948
                        }
1949
                        if ($isAllowToEditByHrm) {
1950
                            $event['editable'] = true;
1951
                        }
1952
                    }
1953
                    // if user is author then he can edit the item
1954
                    if (api_get_user_id() == $row['insert_user_id']) {
1955
                        $event['editable'] = true;
1956
                    }
1957
                }
1958
1959
                if (!empty($row['start_date'])) {
1960
                    $event['start'] = $this->formatEventDate(
1961
                        $row['start_date']
1962
                    );
1963
                    $event['start_date_localtime'] = api_get_local_time(
1964
                        $row['start_date']
1965
                    );
1966
                }
1967
                if (!empty($row['end_date'])) {
1968
                    $event['end'] = $this->formatEventDate($row['end_date']);
1969
                    $event['end_date_localtime'] = api_get_local_time(
1970
                        $row['end_date']
1971
                    );
1972
                }
1973
1974
                $event['sent_to'] = '';
1975
                $event['type'] = 'course';
1976
                if ($row['session_id'] != 0) {
1977
                    $event['type'] = 'session';
1978
                }
1979
1980
                // Event Sent to a group?
1981
                if (isset($row['to_group_id']) && !empty($row['to_group_id'])) {
1982
                    $sent_to = [];
1983
                    if (!empty($group_to_array)) {
1984
                        foreach ($group_to_array as $group_item) {
1985
                            $sent_to[] = $groupNameList[$group_item];
1986
                        }
1987
                    }
1988
                    $sent_to = implode('@@', $sent_to);
1989
                    $sent_to = str_replace(
1990
                        '@@',
1991
                        '</div><div class="label_tag notice">',
1992
                        $sent_to
1993
                    );
1994
                    $event['sent_to'] = '<div class="label_tag notice">'.$sent_to.'</div>';
1995
                    $event['type'] = 'group';
1996
                }
1997
1998
                // Event sent to a user?
1999
                if (isset($row['to_user_id'])) {
2000
                    $sent_to = [];
2001
                    if (!empty($user_to_array)) {
2002
                        foreach ($user_to_array as $item) {
2003
                            $user_info = api_get_user_info($item);
2004
                            // Add username as tooltip for $event['sent_to'] - ref #4226
2005
                            $username = api_htmlentities(
2006
                                sprintf(
2007
                                    get_lang('LoginX'),
2008
                                    $user_info['username']
2009
                                ),
2010
                                ENT_QUOTES
2011
                            );
2012
                            $sent_to[] = "<span title='".$username."'>".$user_info['complete_name']."</span>";
2013
                        }
2014
                    }
2015
                    $sent_to = implode('@@', $sent_to);
2016
                    $sent_to = str_replace(
2017
                        '@@',
2018
                        '</div><div class="label_tag notice">',
2019
                        $sent_to
2020
                    );
2021
                    $event['sent_to'] = '<div class="label_tag notice">'.$sent_to.'</div>';
2022
                }
2023
2024
                //Event sent to everyone!
2025
                if (empty($event['sent_to'])) {
2026
                    $event['sent_to'] = '<div class="label_tag notice">'.get_lang('Everyone').'</div>';
2027
                }
2028
2029
                $event['description'] = $row['content'];
2030
                $event['visibility'] = $row['visibility'];
2031
                $event['real_id'] = $row['id'];
2032
                $event['allDay'] = isset($row['all_day']) && $row['all_day'] == 1 ? $row['all_day'] : 0;
2033
                $event['parent_event_id'] = $row['parent_event_id'];
2034
                $event['has_children'] = $this->hasChildren($row['id'], $courseId) ? 1 : 0;
2035
                $event['comment'] = $row['comment'];
2036
                $this->events[] = $event;
2037
            }
2038
        }
2039
2040
        return $this->events;
2041
    }
2042
2043
    /**
2044
     * @param int $start tms
2045
     * @param int $end   tms
2046
     *
2047
     * @return array
2048
     */
2049
    public function getPlatformEvents($start, $end)
2050
    {
2051
        $start = isset($start) && !empty($start) ? api_get_utc_datetime(intval($start)) : null;
2052
        $end = isset($end) && !empty($end) ? api_get_utc_datetime(intval($end)) : null;
2053
        $dateCondition = '';
2054
2055
        if (!empty($start) && !empty($end)) {
2056
            $dateCondition .= "AND (
2057
                 start_date BETWEEN '".$start."' AND '".$end."' OR
2058
                 end_date BETWEEN '".$start."' AND '".$end."' OR
2059
                 (
2060
                     start_date IS NOT NULL AND end_date IS NOT NULL AND
2061
                     YEAR(start_date) = YEAR(end_date) AND
2062
                     MONTH('$start') BETWEEN MONTH(start_date) AND MONTH(end_date)
2063
                 )
2064
            )";
2065
        }
2066
2067
        $access_url_id = api_get_current_access_url_id();
2068
2069
        $sql = "SELECT *
2070
                FROM ".$this->tbl_global_agenda."
2071
                WHERE access_url_id = $access_url_id
2072
                $dateCondition";
2073
        $result = Database::query($sql);
2074
        $my_events = [];
2075
        if (Database::num_rows($result)) {
2076
            while ($row = Database::fetch_array($result, 'ASSOC')) {
2077
                $event = [];
2078
                $event['id'] = 'platform_'.$row['id'];
2079
                $event['title'] = $row['title'];
2080
                $event['className'] = 'platform';
2081
                $event['allDay'] = 'false';
2082
                $event['borderColor'] = $event['backgroundColor'] = $this->event_platform_color;
2083
                $event['editable'] = false;
2084
                $event['type'] = 'admin';
2085
2086
                if (api_is_platform_admin() && $this->type == 'admin') {
2087
                    $event['editable'] = true;
2088
                }
2089
2090
                if (!empty($row['start_date'])) {
2091
                    $event['start'] = $this->formatEventDate($row['start_date']);
2092
                    $event['start_date_localtime'] = api_get_local_time($row['start_date']);
2093
                }
2094
2095
                if (!empty($row['end_date'])) {
2096
                    $event['end'] = $this->formatEventDate($row['end_date']);
2097
                    $event['end_date_localtime'] = api_get_local_time($row['end_date']);
2098
                }
2099
                $event['allDay'] = isset($row['all_day']) && $row['all_day'] == 1 ? $row['all_day'] : 0;
2100
                $event['parent_event_id'] = 0;
2101
                $event['has_children'] = 0;
2102
                $event['description'] = $row['content'];
2103
2104
                $my_events[] = $event;
2105
                $this->events[] = $event;
2106
            }
2107
        }
2108
2109
        return $my_events;
2110
    }
2111
2112
    /**
2113
     * @param FormValidator $form
2114
     * @param array         $groupList
2115
     * @param array         $userList
2116
     * @param array         $sendTo               array('users' => [1, 2], 'groups' => [3, 4])
2117
     * @param array         $attributes
2118
     * @param bool          $addOnlyItemsInSendTo
2119
     * @param bool          $required
2120
     */
2121
    public function setSendToSelect(
2122
        $form,
2123
        $groupList = [],
2124
        $userList = [],
2125
        $sendTo = [],
2126
        $attributes = [],
2127
        $addOnlyItemsInSendTo = false,
2128
        $required = false
2129
    ) {
2130
        $params = [
2131
            'id' => 'users_to_send_id',
2132
            'data-placeholder' => get_lang('Select'),
2133
            'multiple' => 'multiple',
2134
            'class' => 'multiple-select',
2135
        ];
2136
2137
        if (!empty($attributes)) {
2138
            $params = array_merge($params, $attributes);
2139
            if (empty($params['multiple'])) {
2140
                unset($params['multiple']);
2141
            }
2142
        }
2143
2144
        $sendToGroups = isset($sendTo['groups']) ? $sendTo['groups'] : [];
2145
        $sendToUsers = isset($sendTo['users']) ? $sendTo['users'] : [];
2146
2147
        /** @var HTML_QuickForm_select $select */
2148
        $select = $form->addSelect(
2149
            'users_to_send',
2150
            get_lang('To'),
2151
            null,
2152
            $params
2153
        );
2154
2155
        if ($required) {
2156
            $form->setRequired($select);
2157
        }
2158
2159
        $selectedEveryoneOptions = [];
2160
        if (isset($sendTo['everyone']) && $sendTo['everyone']) {
2161
            $selectedEveryoneOptions = ['selected'];
2162
            $sendToUsers = [];
2163
        }
2164
2165
        $select->addOption(
2166
            get_lang('Everyone'),
2167
            'everyone',
2168
            $selectedEveryoneOptions
2169
        );
2170
2171
        $options = [];
2172
        if (is_array($groupList)) {
2173
            foreach ($groupList as $group) {
2174
                $count_users = isset($group['count_users']) ? $group['count_users'] : $group['userNb'];
2175
                $count_users = " &ndash; $count_users ".get_lang('Users');
2176
                $option = [
2177
                    'text' => $group['name'].$count_users,
2178
                    'value' => "GROUP:".$group['id'],
2179
                ];
2180
                $selected = in_array(
2181
                    $group['id'],
2182
                    $sendToGroups
2183
                ) ? true : false;
2184
                if ($selected) {
2185
                    $option['selected'] = 'selected';
2186
                }
2187
2188
                if ($addOnlyItemsInSendTo) {
2189
                    if ($selected) {
2190
                        $options[] = $option;
2191
                    }
2192
                } else {
2193
                    $options[] = $option;
2194
                }
2195
            }
2196
            $select->addOptGroup($options, get_lang('Groups'));
2197
        }
2198
2199
        // adding the individual users to the select form
2200
        if (is_array($userList)) {
2201
            $options = [];
2202
            foreach ($userList as $user) {
2203
                if ($user['status'] == ANONYMOUS) {
2204
                    continue;
2205
                }
2206
                $option = [
2207
                    'text' => api_get_person_name(
2208
                            $user['firstname'],
2209
                            $user['lastname']
2210
                        ).' ('.$user['username'].')',
2211
                    'value' => "USER:".$user['user_id'],
2212
                ];
2213
2214
                $selected = in_array(
2215
                    $user['user_id'],
2216
                    $sendToUsers
2217
                ) ? true : false;
2218
2219
                if ($selected) {
2220
                    $option['selected'] = 'selected';
2221
                }
2222
2223
                if ($addOnlyItemsInSendTo) {
2224
                    if ($selected) {
2225
                        $options[] = $option;
2226
                    }
2227
                } else {
2228
                    $options[] = $option;
2229
                }
2230
            }
2231
2232
            $select->addOptGroup($options, get_lang('Users'));
2233
        }
2234
    }
2235
2236
    /**
2237
     * Separates the users and groups array
2238
     * users have a value USER:XXX (with XXX the user id
2239
     * groups have a value GROUP:YYY (with YYY the group id)
2240
     * use the 'everyone' key.
2241
     *
2242
     * @author Julio Montoya based in separate_users_groups in agenda.inc.php
2243
     *
2244
     * @param array $to
2245
     *
2246
     * @return array
2247
     */
2248
    public function parseSendToArray($to)
2249
    {
2250
        $groupList = [];
2251
        $userList = [];
2252
        $sendTo = null;
2253
2254
        $sendTo['everyone'] = false;
2255
        if (is_array($to) && count($to) > 0) {
2256
            foreach ($to as $item) {
2257
                if ($item == 'everyone') {
2258
                    $sendTo['everyone'] = true;
2259
                } else {
2260
                    list($type, $id) = explode(':', $item);
2261
                    switch ($type) {
2262
                        case 'GROUP':
2263
                            $groupList[] = $id;
2264
                            break;
2265
                        case 'USER':
2266
                            $userList[] = $id;
2267
                            break;
2268
                    }
2269
                }
2270
            }
2271
            $sendTo['groups'] = $groupList;
2272
            $sendTo['users'] = $userList;
2273
        }
2274
2275
        return $sendTo;
2276
    }
2277
2278
    /**
2279
     * @param array $params
2280
     *
2281
     * @return FormValidator
2282
     */
2283
    public function getForm($params = [])
2284
    {
2285
        $action = isset($params['action']) ? Security::remove_XSS($params['action']) : null;
2286
        $id = isset($params['id']) ? intval($params['id']) : null;
2287
2288
        if ($this->type == 'course') {
2289
            $url = api_get_self().'?'.api_get_cidreq().'&action='.$action.'&id='.$id.'&type='.$this->type;
2290
        } else {
2291
            $url = api_get_self().'?action='.$action.'&id='.$id.'&type='.$this->type;
2292
        }
2293
2294
        $form = new FormValidator(
2295
            'add_event',
2296
            'post',
2297
            $url,
2298
            null,
2299
            ['enctype' => 'multipart/form-data']
2300
        );
2301
2302
        $idAttach = isset($params['id_attach']) ? intval(
2303
            $params['id_attach']
2304
        ) : null;
2305
        $groupId = api_get_group_id();
2306
2307
        if ($id) {
2308
            $form_title = get_lang('ModifyCalendarItem');
2309
        } else {
2310
            $form_title = get_lang('AddCalendarItem');
2311
        }
2312
2313
        $form->addElement('header', $form_title);
2314
        $form->addElement('hidden', 'id', $id);
2315
        $form->addElement('hidden', 'action', $action);
2316
        $form->addElement('hidden', 'id_attach', $idAttach);
2317
2318
        $isSubEventEdition = false;
2319
        $isParentFromSerie = false;
2320
        $showAttachmentForm = true;
2321
2322
        if ($this->type == 'course') {
2323
            // Edition mode.
2324
            if (!empty($id)) {
2325
                $showAttachmentForm = false;
2326
                if (isset($params['parent_event_id']) && !empty($params['parent_event_id'])) {
2327
                    $isSubEventEdition = true;
2328
                }
2329
                if (!empty($params['repeat_info'])) {
2330
                    $isParentFromSerie = true;
2331
                }
2332
            }
2333
        }
2334
2335
        if ($isSubEventEdition) {
2336
            $form->addElement(
2337
                'label',
2338
                null,
2339
                Display::return_message(
2340
                    get_lang('EditingThisEventWillRemoveItFromTheSerie'),
2341
                    'warning'
2342
                )
2343
            );
2344
        }
2345
2346
        $form->addElement('text', 'title', get_lang('ItemTitle'));
2347
2348
        if (isset($groupId) && !empty($groupId)) {
2349
            $form->addElement(
2350
                'hidden',
2351
                'users_to_send[]',
2352
                "GROUP:$groupId"
2353
            );
2354
            $form->addElement('hidden', 'to', 'true');
2355
        } else {
2356
            $sendTo = isset($params['send_to']) ? $params['send_to'] : ['everyone' => true];
2357
            if ($this->type == 'course') {
2358
                $this->showToForm($form, $sendTo, [], false, true);
2359
            }
2360
        }
2361
2362
        $form->addDateRangePicker(
2363
            'date_range',
2364
            get_lang('DateRange'),
2365
            false,
2366
            ['id' => 'date_range']
2367
        );
2368
        $form->addElement('checkbox', 'all_day', null, get_lang('AllDay'));
2369
2370
        if ($this->type == 'course') {
2371
            $repeat = $form->addElement(
2372
                'checkbox',
2373
                'repeat',
2374
                null,
2375
                get_lang('RepeatEvent'),
2376
                ['onclick' => 'return plus_repeated_event();']
2377
            );
2378
            $form->addElement(
2379
                'html',
2380
                '<div id="options2" style="display:none">'
2381
            );
2382
            $form->addElement(
2383
                'select',
2384
                'repeat_type',
2385
                get_lang('RepeatType'),
2386
                self::getRepeatTypes()
2387
            );
2388
            $form->addElement(
2389
                'date_picker',
2390
                'repeat_end_day',
2391
                get_lang('RepeatEnd'),
2392
                ['id' => 'repeat_end_date_form']
2393
            );
2394
2395
            if ($isSubEventEdition || $isParentFromSerie) {
2396
                if ($isSubEventEdition) {
2397
                    $parentEvent = $params['parent_info'];
2398
                    $repeatInfo = $parentEvent['repeat_info'];
2399
                } else {
2400
                    $repeatInfo = $params['repeat_info'];
2401
                }
2402
                $params['repeat'] = 1;
2403
                $params['repeat_type'] = $repeatInfo['cal_type'];
2404
                $params['repeat_end_day'] = substr(
2405
                    api_get_local_time($repeatInfo['cal_end']),
2406
                    0,
2407
                    10
2408
                );
2409
2410
                $form->freeze(['repeat_type', 'repeat_end_day']);
2411
                $repeat->_attributes['disabled'] = 'disabled';
2412
            }
2413
            $form->addElement('html', '</div>');
2414
        }
2415
2416
        if (!empty($id)) {
2417
            if (empty($params['end_date'])) {
2418
                $params['date_range'] = $params['end_date'];
2419
            }
2420
2421
            $params['date_range'] =
2422
                substr(api_get_local_time($params['start_date']), 0, 16).' / '.
2423
                substr(api_get_local_time($params['end_date']), 0, 16);
2424
        }
2425
2426
        if (!api_is_allowed_to_edit(null, true)) {
2427
            $toolbar = 'AgendaStudent';
2428
        } else {
2429
            $toolbar = 'Agenda';
2430
        }
2431
2432
        $form->addElement(
2433
            'html_editor',
2434
            'content',
2435
            get_lang('Description'),
2436
            null,
2437
            [
2438
                'ToolbarSet' => $toolbar,
2439
                'Width' => '100%',
2440
                'Height' => '200',
2441
            ]
2442
        );
2443
2444
        if ($this->type == 'course') {
2445
            $form->addElement('textarea', 'comment', get_lang('Comment'));
2446
            $form->addLabel(
2447
                get_lang('FilesAttachment'),
2448
                '<span id="filepaths">
2449
                        <div id="filepath_1">
2450
                            <input type="file" name="attach_1"/><br />
2451
                            '.get_lang('Description').'&nbsp;&nbsp;<input type="text" name="legend[]" /><br /><br />
2452
                        </div>
2453
                    </span>'
2454
            );
2455
2456
            $form->addLabel(
2457
                '',
2458
                '<span id="link-more-attach">
2459
                    <a href="javascript://" onclick="return add_image_form()">'.
2460
                get_lang('AddOneMoreFile').'</a>
2461
                 </span>&nbsp;('.sprintf(
2462
                    get_lang('MaximunFileSizeX'),
2463
                    format_file_size(
2464
                        api_get_setting('message_max_upload_filesize')
2465
                    )
2466
                ).')'
2467
            );
2468
2469
            if (isset($params['attachment']) && !empty($params['attachment'])) {
2470
                $attachmentList = $params['attachment'];
2471
                foreach ($attachmentList as $attachment) {
2472
                    $params['file_comment'] = $attachment['comment'];
2473
                    if (!empty($attachment['path'])) {
2474
                        $form->addElement(
2475
                            'checkbox',
2476
                            'delete_attachment['.$attachment['id'].']',
2477
                            null,
2478
                            get_lang(
2479
                                'DeleteAttachment'
2480
                            ).': '.$attachment['filename']
2481
                        );
2482
                    }
2483
                }
2484
            }
2485
2486
            $form->addElement(
2487
                'textarea',
2488
                'file_comment',
2489
                get_lang('FileComment')
2490
            );
2491
        }
2492
2493
        if (empty($id)) {
2494
            $form->addElement(
2495
                'checkbox',
2496
                'add_announcement',
2497
                null,
2498
                get_lang('AddAnnouncement').'&nbsp('.get_lang('SendMail').')'
2499
            );
2500
        }
2501
2502
        if ($id) {
2503
            $form->addButtonUpdate(get_lang('ModifyEvent'));
2504
        } else {
2505
            $form->addButtonSave(get_lang('AgendaAdd'));
2506
        }
2507
2508
        $form->setDefaults($params);
2509
        $form->addRule(
2510
            'date_range',
2511
            get_lang('ThisFieldIsRequired'),
2512
            'required'
2513
        );
2514
        $form->addRule('title', get_lang('ThisFieldIsRequired'), 'required');
2515
2516
        return $form;
2517
    }
2518
2519
    /**
2520
     * @param FormValidator $form
2521
     * @param array         $sendTo               array('everyone' => false, 'users' => [1, 2], 'groups' => [3, 4])
2522
     * @param array         $attributes
2523
     * @param bool          $addOnlyItemsInSendTo
2524
     * @param bool          $required
2525
     *
2526
     * @return bool
2527
     */
2528
    public function showToForm(
2529
        $form,
2530
        $sendTo = [],
2531
        $attributes = [],
2532
        $addOnlyItemsInSendTo = false,
2533
        $required = false
2534
    ) {
2535
        if ($this->type != 'course') {
2536
            return false;
2537
        }
2538
2539
        $order = 'lastname';
2540
        if (api_is_western_name_order()) {
2541
            $order = 'firstname';
2542
        }
2543
2544
        $userList = CourseManager::get_user_list_from_course_code(
2545
            api_get_course_id(),
2546
            $this->sessionId,
2547
            null,
2548
            $order
2549
        );
2550
2551
        $groupList = CourseManager::get_group_list_of_course(
2552
            api_get_course_id(),
2553
            $this->sessionId
2554
        );
2555
2556
        $this->setSendToSelect(
2557
            $form,
2558
            $groupList,
2559
            $userList,
2560
            $sendTo,
2561
            $attributes,
2562
            $addOnlyItemsInSendTo,
2563
            $required
2564
        );
2565
2566
        return true;
2567
    }
2568
2569
    /**
2570
     * @param int   $id
2571
     * @param int   $visibility 0= invisible, 1 visible
2572
     * @param array $courseInfo
2573
     * @param int   $userId
2574
     */
2575
    public static function changeVisibility(
2576
        $id,
2577
        $visibility,
2578
        $courseInfo,
2579
        $userId = null
2580
    ) {
2581
        $id = intval($id);
2582
        if (empty($userId)) {
2583
            $userId = api_get_user_id();
2584
        } else {
2585
            $userId = intval($userId);
2586
        }
2587
2588
        if ($visibility == 0) {
2589
            api_item_property_update(
2590
                $courseInfo,
2591
                TOOL_CALENDAR_EVENT,
2592
                $id,
2593
                'invisible',
2594
                $userId
2595
            );
2596
        } else {
2597
            api_item_property_update(
2598
                $courseInfo,
2599
                TOOL_CALENDAR_EVENT,
2600
                $id,
2601
                'visible',
2602
                $userId
2603
            );
2604
        }
2605
    }
2606
2607
    /**
2608
     * Get repeat types.
2609
     *
2610
     * @return array
2611
     */
2612
    public static function getRepeatTypes()
2613
    {
2614
        return [
2615
            'daily' => get_lang('RepeatDaily'),
2616
            'weekly' => get_lang('RepeatWeekly'),
2617
            'monthlyByDate' => get_lang('RepeatMonthlyByDate'),
2618
            //monthlyByDay"> get_lang('RepeatMonthlyByDay');
2619
            //monthlyByDayR' => get_lang('RepeatMonthlyByDayR'),
2620
            'yearly' => get_lang('RepeatYearly'),
2621
        ];
2622
    }
2623
2624
    /**
2625
     * Show a list with all the attachments according to the post's id.
2626
     *
2627
     * @param int   $eventId
2628
     * @param array $courseInfo
2629
     *
2630
     * @return array with the post info
2631
     */
2632
    public function getAttachmentList($eventId, $courseInfo)
2633
    {
2634
        $tableAttachment = Database::get_course_table(TABLE_AGENDA_ATTACHMENT);
2635
        $courseId = (int) $courseInfo['real_id'];
2636
        $eventId = (int) $eventId;
2637
2638
        $sql = "SELECT id, path, filename, comment
2639
                FROM $tableAttachment
2640
                WHERE
2641
                    c_id = $courseId AND
2642
                    agenda_id = $eventId";
2643
        $result = Database::query($sql);
2644
        $list = [];
2645
        if (Database::num_rows($result) != 0) {
2646
            $list = Database::store_result($result, 'ASSOC');
2647
        }
2648
2649
        return $list;
2650
    }
2651
2652
    /**
2653
     * Show a list with all the attachments according to the post's id.
2654
     *
2655
     * @param int   $attachmentId
2656
     * @param int   $eventId
2657
     * @param array $courseInfo
2658
     *
2659
     * @return array with the post info
2660
     */
2661
    public function getAttachment($attachmentId, $eventId, $courseInfo)
2662
    {
2663
        $tableAttachment = Database::get_course_table(TABLE_AGENDA_ATTACHMENT);
2664
        $courseId = intval($courseInfo['real_id']);
2665
        $eventId = intval($eventId);
2666
        $attachmentId = intval($attachmentId);
2667
2668
        $row = [];
2669
        $sql = "SELECT id, path, filename, comment
2670
                FROM $tableAttachment
2671
                WHERE
2672
                    c_id = $courseId AND
2673
                    agenda_id = $eventId AND
2674
                    id = $attachmentId
2675
                ";
2676
        $result = Database::query($sql);
2677
        if (Database::num_rows($result) != 0) {
2678
            $row = Database::fetch_array($result, 'ASSOC');
2679
        }
2680
2681
        return $row;
2682
    }
2683
2684
    /**
2685
     * Add an attachment file into agenda.
2686
     *
2687
     * @param int    $eventId
2688
     * @param array  $fileUserUpload ($_FILES['user_upload'])
2689
     * @param string $comment        about file
2690
     * @param array  $courseInfo
2691
     *
2692
     * @return string
2693
     */
2694
    public function addAttachment(
2695
        $eventId,
2696
        $fileUserUpload,
2697
        $comment,
2698
        $courseInfo
2699
    ) {
2700
        $agenda_table_attachment = Database::get_course_table(TABLE_AGENDA_ATTACHMENT);
2701
        $eventId = intval($eventId);
2702
2703
        // Storing the attachments
2704
        $upload_ok = false;
2705
        if (!empty($fileUserUpload['name'])) {
2706
            $upload_ok = process_uploaded_file($fileUserUpload);
2707
        }
2708
2709
        if (!empty($upload_ok)) {
2710
            $courseDir = $courseInfo['directory'].'/upload/calendar';
2711
            $sys_course_path = api_get_path(SYS_COURSE_PATH);
2712
            $uploadDir = $sys_course_path.$courseDir;
2713
2714
            // Try to add an extension to the file if it hasn't one
2715
            $new_file_name = add_ext_on_mime(
2716
                stripslashes($fileUserUpload['name']),
2717
                $fileUserUpload['type']
2718
            );
2719
2720
            // user's file name
2721
            $file_name = $fileUserUpload['name'];
2722
2723
            if (!filter_extension($new_file_name)) {
2724
                return Display::return_message(
2725
                    get_lang('UplUnableToSaveFileFilteredExtension'),
2726
                    'error'
2727
                );
2728
            } else {
2729
                $new_file_name = uniqid('');
2730
                $new_path = $uploadDir.'/'.$new_file_name;
2731
                $result = @move_uploaded_file(
2732
                    $fileUserUpload['tmp_name'],
2733
                    $new_path
2734
                );
2735
                $course_id = api_get_course_int_id();
2736
                $size = intval($fileUserUpload['size']);
2737
                // Storing the attachments if any
2738
                if ($result) {
2739
                    $params = [
2740
                        'c_id' => $course_id,
2741
                        'filename' => $file_name,
2742
                        'comment' => $comment,
2743
                        'path' => $new_file_name,
2744
                        'agenda_id' => $eventId,
2745
                        'size' => $size,
2746
                    ];
2747
                    $id = Database::insert($agenda_table_attachment, $params);
2748
                    if ($id) {
2749
                        $sql = "UPDATE $agenda_table_attachment
2750
                                SET id = iid WHERE iid = $id";
2751
                        Database::query($sql);
2752
2753
                        api_item_property_update(
2754
                            $courseInfo,
2755
                            'calendar_event_attachment',
2756
                            $id,
2757
                            'AgendaAttachmentAdded',
2758
                            api_get_user_id()
2759
                        );
2760
                    }
2761
                }
2762
            }
2763
        }
2764
    }
2765
2766
    /**
2767
     * @param int    $attachmentId
2768
     * @param int    $eventId
2769
     * @param array  $fileUserUpload
2770
     * @param string $comment
2771
     * @param array  $courseInfo
2772
     */
2773
    public function updateAttachment(
2774
        $attachmentId,
2775
        $eventId,
2776
        $fileUserUpload,
2777
        $comment,
2778
        $courseInfo
2779
    ) {
2780
        $attachment = $this->getAttachment(
2781
            $attachmentId,
2782
            $eventId,
2783
            $courseInfo
2784
        );
2785
        if (!empty($attachment)) {
2786
            $this->deleteAttachmentFile($attachmentId, $courseInfo);
2787
        }
2788
        $this->addAttachment($eventId, $fileUserUpload, $comment, $courseInfo);
2789
    }
2790
2791
    /**
2792
     * This function delete a attachment file by id.
2793
     *
2794
     * @param int   $attachmentId
2795
     * @param array $courseInfo
2796
     *
2797
     * @return string
2798
     */
2799
    public function deleteAttachmentFile($attachmentId, $courseInfo)
2800
    {
2801
        $table = Database::get_course_table(TABLE_AGENDA_ATTACHMENT);
2802
        $attachmentId = (int) $attachmentId;
2803
        $courseId = $courseInfo['real_id'];
2804
2805
        if (empty($courseId) || empty($attachmentId)) {
2806
            return false;
2807
        }
2808
2809
        $sql = "DELETE FROM $table
2810
                WHERE c_id = $courseId AND id = ".$attachmentId;
2811
        $result = Database::query($sql);
2812
2813
        // update item_property
2814
        api_item_property_update(
2815
            $courseInfo,
2816
            'calendar_event_attachment',
2817
            $attachmentId,
2818
            'AgendaAttachmentDeleted',
2819
            api_get_user_id()
2820
        );
2821
2822
        if (!empty($result)) {
2823
            return Display::return_message(
2824
                get_lang("AttachmentFileDeleteSuccess"),
2825
                'confirmation'
2826
            );
2827
        }
2828
    }
2829
2830
    /**
2831
     * Adds x weeks to a UNIX timestamp.
2832
     *
2833
     * @param int $timestamp The timestamp
2834
     * @param int $num       The number of weeks to add
2835
     *
2836
     * @return int The new timestamp
2837
     */
2838
    public function addWeek($timestamp, $num = 1)
2839
    {
2840
        return $timestamp + $num * 604800;
2841
    }
2842
2843
    /**
2844
     * Adds x months to a UNIX timestamp.
2845
     *
2846
     * @param int $timestamp The timestamp
2847
     * @param int $num       The number of years to add
2848
     *
2849
     * @return int The new timestamp
2850
     */
2851
    public function addMonth($timestamp, $num = 1)
2852
    {
2853
        list($y, $m, $d, $h, $n, $s) = split(
2854
            '/',
2855
            date('Y/m/d/h/i/s', $timestamp)
2856
        );
2857
        if ($m + $num > 12) {
2858
            $y += floor($num / 12);
2859
            $m += $num % 12;
2860
        } else {
2861
            $m += $num;
2862
        }
2863
2864
        return mktime($h, $n, $s, $m, $d, $y);
2865
    }
2866
2867
    /**
2868
     * Adds x years to a UNIX timestamp.
2869
     *
2870
     * @param int $timestamp The timestamp
2871
     * @param int $num       The number of years to add
2872
     *
2873
     * @return int The new timestamp
2874
     */
2875
    public function addYear($timestamp, $num = 1)
2876
    {
2877
        list($y, $m, $d, $h, $n, $s) = split(
2878
            '/',
2879
            date('Y/m/d/h/i/s', $timestamp)
2880
        );
2881
2882
        return mktime($h, $n, $s, $m, $d, $y + $num);
2883
    }
2884
2885
    /**
2886
     * @param int $eventId
2887
     *
2888
     * @return array
2889
     */
2890
    public function getAllRepeatEvents($eventId)
2891
    {
2892
        $events = [];
2893
        switch ($this->type) {
2894
            case 'personal':
2895
                break;
2896
            case 'course':
2897
                if (!empty($this->course['real_id'])) {
2898
                    $sql = "SELECT * FROM ".$this->tbl_course_agenda."
2899
                            WHERE
2900
                                c_id = ".$this->course['real_id']." AND
2901
                                parent_event_id = ".$eventId;
2902
                    $result = Database::query($sql);
2903
                    if (Database::num_rows($result)) {
2904
                        while ($row = Database::fetch_array($result, 'ASSOC')) {
2905
                            $events[] = $row;
2906
                        }
2907
                    }
2908
                }
2909
                break;
2910
        }
2911
2912
        return $events;
2913
    }
2914
2915
    /**
2916
     * @param int $eventId
2917
     * @param int $courseId
2918
     *
2919
     * @return bool
2920
     */
2921
    public function hasChildren($eventId, $courseId)
2922
    {
2923
        $eventId = (int) $eventId;
2924
        $courseId = (int) $courseId;
2925
2926
        $sql = "SELECT count(DISTINCT(id)) as count
2927
                FROM ".$this->tbl_course_agenda."
2928
                WHERE
2929
                    c_id = $courseId AND
2930
                    parent_event_id = $eventId";
2931
        $result = Database::query($sql);
2932
        if (Database::num_rows($result)) {
2933
            $row = Database::fetch_array($result, 'ASSOC');
2934
2935
            return $row['count'] > 0;
2936
        }
2937
2938
        return false;
2939
    }
2940
2941
    /**
2942
     * @param int    $filter
2943
     * @param string $view
2944
     *
2945
     * @return string
2946
     */
2947
    public function displayActions($view, $filter = 0)
2948
    {
2949
        $courseInfo = api_get_course_info();
2950
        $groupInfo = GroupManager::get_group_properties(api_get_group_id());
2951
        $groupIid = isset($groupInfo['iid']) ? $groupInfo['iid'] : 0;
2952
2953
        $courseCondition = '';
2954
        if (!empty($courseInfo)) {
2955
            $courseCondition = api_get_cidreq();
2956
        }
2957
2958
        $actionsLeft = '';
2959
        $actionsLeft .= "<a href='".api_get_path(WEB_CODE_PATH)."calendar/agenda_js.php?type={$this->type}&".$courseCondition."'>".
2960
            Display::return_icon(
2961
                'calendar.png',
2962
                get_lang('Calendar'),
2963
                '',
2964
                ICON_SIZE_MEDIUM
2965
            )."</a>";
2966
2967
        $actionsLeft .= "<a href='".api_get_path(WEB_CODE_PATH)."calendar/agenda_list.php?type={$this->type}&".$courseCondition."'>".
2968
            Display::return_icon(
2969
                'week.png',
2970
                get_lang('AgendaList'),
2971
                '',
2972
                ICON_SIZE_MEDIUM
2973
            )."</a>";
2974
2975
        $form = '';
2976
        if (api_is_allowed_to_edit(false, true) ||
2977
            (api_get_course_setting('allow_user_edit_agenda') == '1' &&
2978
                !api_is_anonymous()) &&
2979
            api_is_allowed_to_session_edit(false, true) ||
2980
            (GroupManager::user_has_access(
2981
                api_get_user_id(),
2982
                $groupIid,
2983
                GroupManager::GROUP_TOOL_CALENDAR
2984
            ) &&
2985
            GroupManager::is_tutor_of_group(api_get_user_id(), $groupInfo))
2986
        ) {
2987
            $actionsLeft .= Display::url(
2988
                Display::return_icon(
2989
                    'new_event.png',
2990
                    get_lang('AgendaAdd'),
2991
                    '',
2992
                    ICON_SIZE_MEDIUM
2993
                ),
2994
                api_get_path(WEB_CODE_PATH)."calendar/agenda.php?".api_get_cidreq()."&action=add&type=".$this->type
2995
            );
2996
2997
            $actionsLeft .= Display::url(
2998
                Display::return_icon(
2999
                    'import_calendar.png',
3000
                    get_lang('ICalFileImport'),
3001
                    '',
3002
                    ICON_SIZE_MEDIUM
3003
                ),
3004
                api_get_path(WEB_CODE_PATH)."calendar/agenda.php?".api_get_cidreq()."&action=importical&type=".$this->type
3005
            );
3006
3007
            if ($this->type === 'course') {
3008
                if (!isset($_GET['action'])) {
3009
                    $form = new FormValidator(
3010
                        'form-search',
3011
                        'post',
3012
                        '',
3013
                        '',
3014
                        [],
3015
                        FormValidator::LAYOUT_INLINE
3016
                    );
3017
                    $attributes = [
3018
                        'multiple' => false,
3019
                        'id' => 'select_form_id_search',
3020
                    ];
3021
                    $selectedValues = $this->parseAgendaFilter($filter);
3022
                    $this->showToForm($form, $selectedValues, $attributes);
3023
                    $form = $form->returnForm();
3024
                }
3025
            }
3026
        }
3027
3028
        if (api_is_platform_admin() ||
3029
            api_is_teacher() ||
3030
            api_is_student_boss() ||
3031
            api_is_drh() ||
3032
            api_is_session_admin() ||
3033
            api_is_coach()
3034
        ) {
3035
            if ($this->type == 'personal') {
3036
                $form = null;
3037
                if (!isset($_GET['action'])) {
3038
                    $form = new FormValidator(
3039
                        'form-search',
3040
                        'get',
3041
                        api_get_self().'?type=personal&',
3042
                        '',
3043
                        [],
3044
                        FormValidator::LAYOUT_INLINE
3045
                    );
3046
3047
                    if (api_is_drh()) {
3048
                        $sessionList = SessionManager::get_sessions_followed_by_drh(
3049
                            api_get_user_id()
3050
                        );
3051
                        if (!empty($sessionList)) {
3052
                            $sessions = [];
3053
                            foreach ($sessionList as $sessionItem) {
3054
                                $sessions[$sessionItem['id']] = strip_tags($sessionItem['name']);
3055
                            }
3056
                        }
3057
                    } else {
3058
                        $sessions = SessionManager::get_sessions_by_user(
3059
                            api_get_user_id()
3060
                        );
3061
                        $sessions = array_column(
3062
                            $sessions,
3063
                            'session_name',
3064
                            'session_id'
3065
                        );
3066
                    }
3067
                    $form->addHidden('type', 'personal');
3068
                    $sessions = ['0' => get_lang('SelectAnOption')] + $sessions;
3069
3070
                    $form->addSelect(
3071
                        'session_id',
3072
                        get_lang('Session'),
3073
                        $sessions,
3074
                        ['id' => 'session_id', 'onchange' => 'submit();']
3075
                    );
3076
3077
                    $form->addButtonReset(get_lang('Reset'));
3078
                    $form = $form->returnForm();
3079
                }
3080
            }
3081
        }
3082
3083
        $actionsRight = '';
3084
        if ($view == 'calendar') {
3085
            $actionsRight .= $form;
3086
        }
3087
3088
        $toolbar = Display::toolbarAction(
3089
            'toolbar-agenda',
3090
            [$actionsLeft, $actionsRight]
3091
        );
3092
3093
        return $toolbar;
3094
    }
3095
3096
    /**
3097
     * @return FormValidator
3098
     */
3099
    public function getImportCalendarForm()
3100
    {
3101
        $form = new FormValidator(
3102
            'frm_import_ical',
3103
            'post',
3104
            api_get_self().'?action=importical&type='.$this->type,
3105
            ['enctype' => 'multipart/form-data']
3106
        );
3107
        $form->addElement('header', get_lang('ICalFileImport'));
3108
        $form->addElement('file', 'ical_import', get_lang('ICalFileImport'));
3109
        $form->addRule(
3110
            'ical_import',
3111
            get_lang('ThisFieldIsRequired'),
3112
            'required'
3113
        );
3114
        $form->addButtonImport(get_lang('Import'), 'ical_submit');
3115
3116
        return $form;
3117
    }
3118
3119
    /**
3120
     * @param array $courseInfo
3121
     * @param $file
3122
     *
3123
     * @return false|string
3124
     */
3125
    public function importEventFile($courseInfo, $file)
3126
    {
3127
        $charset = api_get_system_encoding();
3128
        $filepath = api_get_path(SYS_ARCHIVE_PATH).$file['name'];
3129
        $messages = [];
3130
3131
        if (!@move_uploaded_file($file['tmp_name'], $filepath)) {
3132
            error_log(
3133
                'Problem moving uploaded file: '.$file['error'].' in '.__FILE__.' line '.__LINE__
3134
            );
3135
3136
            return false;
3137
        }
3138
3139
        $data = file_get_contents($filepath);
3140
3141
        $trans = [
3142
            'DAILY' => 'daily',
3143
            'WEEKLY' => 'weekly',
3144
            'MONTHLY' => 'monthlyByDate',
3145
            'YEARLY' => 'yearly',
3146
        ];
3147
        $sentTo = ['everyone' => true];
3148
        $calendar = Sabre\VObject\Reader::read($data);
3149
        $currentTimeZone = api_get_timezone();
3150
        if (!empty($calendar->VEVENT)) {
3151
            foreach ($calendar->VEVENT as $event) {
3152
                $start = $event->DTSTART->getDateTime();
3153
                $end = $event->DTEND->getDateTime();
3154
                //Sabre\VObject\DateTimeParser::parseDateTime(string $dt, \Sabre\VObject\DateTimeZone $tz)
3155
3156
                $startDateTime = api_get_local_time(
3157
                    $start->format('Y-m-d H:i:s'),
3158
                    $currentTimeZone,
3159
                    $start->format('e')
3160
                );
3161
                $endDateTime = api_get_local_time(
3162
                    $end->format('Y-m-d H:i'),
3163
                    $currentTimeZone,
3164
                    $end->format('e')
3165
                );
3166
                $title = api_convert_encoding(
3167
                    (string) $event->summary,
3168
                    $charset,
3169
                    'UTF-8'
3170
                );
3171
                $description = api_convert_encoding(
3172
                    (string) $event->description,
3173
                    $charset,
3174
                    'UTF-8'
3175
                );
3176
3177
                $id = $this->addEvent(
3178
                    $startDateTime,
3179
                    $endDateTime,
3180
                    'false',
3181
                    $title,
3182
                    $description,
3183
                    $sentTo
3184
                );
3185
3186
                $messages[] = " $title - ".$startDateTime." - ".$endDateTime;
3187
3188
                //$attendee = (string)$event->attendee;
3189
                /** @var Sabre\VObject\Property\ICalendar\Recur $repeat */
3190
                $repeat = $event->RRULE;
3191
                if ($id && !empty($repeat)) {
3192
                    $repeat = $repeat->getParts();
3193
                    $freq = $trans[$repeat['FREQ']];
3194
3195
                    if (isset($repeat['UNTIL']) && !empty($repeat['UNTIL'])) {
3196
                        // Check if datetime or just date (strlen == 8)
3197
                        if (strlen($repeat['UNTIL']) == 8) {
3198
                            // Fix the datetime format to avoid exception in the next step
3199
                            $repeat['UNTIL'] .= 'T000000';
3200
                        }
3201
                        $until = Sabre\VObject\DateTimeParser::parseDateTime(
3202
                            $repeat['UNTIL'],
3203
                            new DateTimeZone($currentTimeZone)
3204
                        );
3205
                        $until = $until->format('Y-m-d H:i');
3206
                        //$res = agenda_add_repeat_item($courseInfo, $id, $freq, $until, $attendee);
3207
                        $this->addRepeatedItem(
3208
                            $id,
3209
                            $freq,
3210
                            $until,
3211
                            $sentTo
3212
                        );
3213
                    }
3214
3215
                    if (!empty($repeat['COUNT'])) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
3216
                        /*$count = $repeat['COUNT'];
3217
                        $interval = $repeat['INTERVAL'];
3218
                        $endDate = null;
3219
                        switch($freq) {
3220
                            case 'daily':
3221
                                $start = api_strtotime($startDateTime);
3222
                                $date = new DateTime($startDateTime);
3223
                                $days = $count * $interval;
3224
                                var_dump($days);
3225
                                $date->add(new DateInterval("P".$days."D"));
3226
                                $endDate = $date->format('Y-m-d H:i');
3227
                                //$endDate = $count *
3228
                                for ($i = 0; $i < $count; $i++) {
3229
                                    $days = 86400 * 7
3230
                                }
3231
                            }
3232
                        }*/
3233
                        //$res = agenda_add_repeat_item($courseInfo, $id, $freq, $count, $attendee);
3234
                        /*$this->addRepeatedItem(
3235
                            $id,
3236
                            $freq,
3237
                            $endDate,
3238
                            $sentTo
3239
                        );*/
3240
                    }
3241
                }
3242
            }
3243
        }
3244
3245
        if (!empty($messages)) {
3246
            $messages = implode('<br /> ', $messages);
3247
        } else {
3248
            $messages = get_lang('NoAgendaItems');
3249
        }
3250
3251
        return $messages;
3252
    }
3253
3254
    /**
3255
     * Parse filter turns USER:12 to ['users' => [12])] or G:1 ['groups' => [1]].
3256
     *
3257
     * @param int $filter
3258
     *
3259
     * @return array
3260
     */
3261
    public function parseAgendaFilter($filter)
3262
    {
3263
        $everyone = false;
3264
        $groupId = null;
3265
        $userId = null;
3266
3267
        if ($filter == 'everyone') {
3268
            $everyone = true;
3269
        } else {
3270
            if (substr($filter, 0, 1) == 'G') {
3271
                $groupId = str_replace('GROUP:', '', $filter);
3272
            } else {
3273
                $userId = str_replace('USER:', '', $filter);
3274
            }
3275
        }
3276
        if (empty($userId) && empty($groupId)) {
3277
            $everyone = true;
3278
        }
3279
3280
        return [
3281
            'everyone' => $everyone,
3282
            'users' => [$userId],
3283
            'groups' => [$groupId],
3284
        ];
3285
    }
3286
3287
    /**
3288
     *    This function retrieves all the agenda items of all the courses the user is subscribed to.
3289
     */
3290
    public static function get_myagendaitems(
3291
        $user_id,
3292
        $courses_dbs,
3293
        $month,
3294
        $year
3295
    ) {
3296
        $user_id = intval($user_id);
3297
3298
        $items = [];
3299
        $my_list = [];
3300
3301
        // get agenda-items for every course
3302
        foreach ($courses_dbs as $key => $array_course_info) {
3303
            //databases of the courses
3304
            $TABLEAGENDA = Database::get_course_table(TABLE_AGENDA);
3305
            $TABLE_ITEMPROPERTY = Database::get_course_table(
3306
                TABLE_ITEM_PROPERTY
3307
            );
3308
3309
            $group_memberships = GroupManager::get_group_ids(
3310
                $array_course_info['real_id'],
3311
                $user_id
3312
            );
3313
            $course_user_status = CourseManager::getUserInCourseStatus(
3314
                $user_id,
3315
                $array_course_info['real_id']
3316
            );
3317
            // if the user is administrator of that course we show all the agenda items
3318
            if ($course_user_status == '1') {
3319
                //echo "course admin";
3320
                $sqlquery = "SELECT DISTINCT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref
3321
							FROM ".$TABLEAGENDA." agenda,
3322
								 ".$TABLE_ITEMPROPERTY." ip
3323
							WHERE agenda.id = ip.ref
3324
							AND MONTH(agenda.start_date)='".$month."'
3325
							AND YEAR(agenda.start_date)='".$year."'
3326
							AND ip.tool='".TOOL_CALENDAR_EVENT."'
3327
							AND ip.visibility='1'
3328
							GROUP BY agenda.id
3329
							ORDER BY start_date ";
3330
            } else {
3331
                // if the user is not an administrator of that course
3332
                if (is_array($group_memberships) && count(
3333
                        $group_memberships
3334
                    ) > 0
3335
                ) {
3336
                    $sqlquery = "SELECT	agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref
3337
								FROM ".$TABLEAGENDA." agenda,
3338
									".$TABLE_ITEMPROPERTY." ip
3339
								WHERE agenda.id = ip.ref
3340
								AND MONTH(agenda.start_date)='".$month."'
3341
								AND YEAR(agenda.start_date)='".$year."'
3342
								AND ip.tool='".TOOL_CALENDAR_EVENT."'
3343
								AND	( ip.to_user_id='".$user_id."' OR (ip.to_group_id IS NULL OR ip.to_group_id IN (0, ".implode(
3344
                            ", ",
3345
                            $group_memberships
3346
                        ).")) )
3347
								AND ip.visibility='1'
3348
								ORDER BY start_date ";
3349
                } else {
3350
                    $sqlquery = "SELECT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref
3351
								FROM ".$TABLEAGENDA." agenda,
3352
									".$TABLE_ITEMPROPERTY." ip
3353
								WHERE agenda.id = ip.ref
3354
								AND MONTH(agenda.start_date)='".$month."'
3355
								AND YEAR(agenda.start_date)='".$year."'
3356
								AND ip.tool='".TOOL_CALENDAR_EVENT."'
3357
								AND ( ip.to_user_id='".$user_id."' OR ip.to_group_id='0' OR ip.to_group_id IS NULL)
3358
								AND ip.visibility='1'
3359
								ORDER BY start_date ";
3360
                }
3361
            }
3362
            $result = Database::query($sqlquery);
3363
3364
            while ($item = Database::fetch_array($result, 'ASSOC')) {
3365
                $agendaday = -1;
3366
                if (!empty($item['start_date'])) {
3367
                    $item['start_date'] = api_get_local_time(
3368
                        $item['start_date']
3369
                    );
3370
                    $item['start_date_tms'] = api_strtotime(
3371
                        $item['start_date']
3372
                    );
3373
                    $agendaday = date("j", $item['start_date_tms']);
3374
                }
3375
                if (!empty($item['end_date'])) {
3376
                    $item['end_date'] = api_get_local_time($item['end_date']);
3377
                }
3378
3379
                $url = api_get_path(
3380
                        WEB_CODE_PATH
3381
                    )."calendar/agenda.php?cidReq=".urlencode(
3382
                        $array_course_info["code"]
3383
                    )."&day=$agendaday&month=$month&year=$year#$agendaday";
3384
3385
                $item['url'] = $url;
3386
                $item['course_name'] = $array_course_info['title'];
3387
                $item['calendar_type'] = 'course';
3388
                $item['course_id'] = $array_course_info['course_id'];
3389
3390
                $my_list[$agendaday][] = $item;
3391
            }
3392
        }
3393
3394
        // sorting by hour for every day
3395
        $agendaitems = [];
3396
        while (list($agendaday, $tmpitems) = each($items)) {
3397
            if (!isset($agendaitems[$agendaday])) {
3398
                $agendaitems[$agendaday] = '';
3399
            }
3400
            sort($tmpitems);
3401
            while (list($key, $val) = each($tmpitems)) {
3402
                $agendaitems[$agendaday] .= $val;
3403
            }
3404
        }
3405
3406
        return $my_list;
3407
    }
3408
3409
    /**
3410
     * This function retrieves one personal agenda item returns it.
3411
     *
3412
     * @param    array    The array containing existing events. We add to this array.
3413
     * @param    int        Day
3414
     * @param    int        Month
3415
     * @param    int        Year (4 digits)
3416
     * @param    int        Week number
3417
     * @param    string    Type of view (month_view, week_view, day_view)
3418
     *
3419
     * @return array The results of the database query, or null if not found
3420
     */
3421
    public static function get_global_agenda_items(
3422
        $agendaitems,
3423
        $day = "",
3424
        $month = "",
3425
        $year = "",
3426
        $week = "",
3427
        $type
3428
    ) {
3429
        $tbl_global_agenda = Database::get_main_table(
3430
            TABLE_MAIN_SYSTEM_CALENDAR
3431
        );
3432
        $month = intval($month);
3433
        $year = intval($year);
3434
        $week = intval($week);
3435
        $day = intval($day);
3436
        // 1. creating the SQL statement for getting the personal agenda items in MONTH view
3437
3438
        $current_access_url_id = api_get_current_access_url_id();
3439
3440
        if ($type == "month_view" or $type == "") {
3441
            // We are in month view
3442
            $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";
3443
        }
3444
        // 2. creating the SQL statement for getting the personal agenda items in WEEK view
3445
        if ($type == "week_view") { // we are in week view
3446
            $start_end_day_of_week = self::calculate_start_end_of_week(
3447
                $week,
3448
                $year
3449
            );
3450
            $start_day = $start_end_day_of_week['start']['day'];
3451
            $start_month = $start_end_day_of_week['start']['month'];
3452
            $start_year = $start_end_day_of_week['start']['year'];
3453
            $end_day = $start_end_day_of_week['end']['day'];
3454
            $end_month = $start_end_day_of_week['end']['month'];
3455
            $end_year = $start_end_day_of_week['end']['year'];
3456
            // in sql statements you have to use year-month-day for date calculations
3457
            $start_filter = $start_year."-".$start_month."-".$start_day." 00:00:00";
3458
            $start_filter = api_get_utc_datetime($start_filter);
3459
3460
            $end_filter = $end_year."-".$end_month."-".$end_day." 23:59:59";
3461
            $end_filter = api_get_utc_datetime($end_filter);
3462
            $sql = " SELECT * FROM ".$tbl_global_agenda." WHERE start_date>='".$start_filter."' AND start_date<='".$end_filter."' AND  access_url_id = $current_access_url_id ";
3463
        }
3464
        // 3. creating the SQL statement for getting the personal agenda items in DAY view
3465
        if ($type == "day_view") { // we are in day view
3466
            // we could use mysql date() function but this is only available from 4.1 and higher
3467
            $start_filter = $year."-".$month."-".$day." 00:00:00";
3468
            $start_filter = api_get_utc_datetime($start_filter);
3469
3470
            $end_filter = $year."-".$month."-".$day." 23:59:59";
3471
            $end_filter = api_get_utc_datetime($end_filter);
3472
            $sql = " SELECT * FROM ".$tbl_global_agenda." WHERE start_date>='".$start_filter."' AND start_date<='".$end_filter."'  AND  access_url_id = $current_access_url_id";
3473
        }
3474
3475
        $result = Database::query($sql);
3476
3477
        while ($item = Database::fetch_array($result)) {
3478
            if (!empty($item['start_date'])) {
3479
                $item['start_date'] = api_get_local_time($item['start_date']);
3480
                $item['start_date_tms'] = api_strtotime($item['start_date']);
3481
            }
3482
            if (!empty($item['end_date'])) {
3483
                $item['end_date'] = api_get_local_time($item['end_date']);
3484
            }
3485
3486
            // we break the date field in the database into a date and a time part
3487
            $agenda_db_date = explode(" ", $item['start_date']);
3488
            $date = $agenda_db_date[0];
3489
            $time = $agenda_db_date[1];
3490
            // we divide the date part into a day, a month and a year
3491
            $agendadate = explode("-", $date);
3492
            $year = intval($agendadate[0]);
3493
            $month = intval($agendadate[1]);
3494
            $day = intval($agendadate[2]);
3495
            // we divide the time part into hour, minutes, seconds
3496
            $agendatime = explode(":", $time);
3497
            $hour = $agendatime[0];
3498
            $minute = $agendatime[1];
3499
            $second = $agendatime[2];
3500
3501
            if ($type == 'month_view') {
3502
                $item['calendar_type'] = 'global';
3503
                $agendaitems[$day][] = $item;
3504
                continue;
3505
            }
3506
3507
            $start_time = api_format_date(
3508
                $item['start_date'],
3509
                TIME_NO_SEC_FORMAT
3510
            );
3511
            $end_time = '';
3512
            if (!empty($item['end_date'])) {
3513
                $end_time = ' - '.api_format_date(
3514
                        $item['end_date'],
3515
                        DATE_TIME_FORMAT_LONG
3516
                    );
3517
            }
3518
3519
            // if the student has specified a course we a add a link to that course
3520
            if ($item['course'] != "") {
3521
                $url = api_get_path(
3522
                        WEB_CODE_PATH
3523
                    )."admin/agenda.php?cidReq=".urlencode(
3524
                        $item['course']
3525
                    )."&day=$day&month=$month&year=$year#$day"; // RH  //Patrick Cool: to highlight the relevant agenda item
3526
                $course_link = "<a href=\"$url\" title=\"".$item['course']."\">".$item['course']."</a>";
3527
            } else {
3528
                $course_link = "";
3529
            }
3530
            // Creating the array that will be returned. If we have week or month view we have an array with the date as the key
3531
            // if we have a day_view we use a half hour as index => key 33 = 16h30
3532
            if ($type !== "day_view") {
3533
                // This is the array construction for the WEEK or MONTH view
3534
                //Display the Agenda global in the tab agenda (administrator)
3535
                $agendaitems[$day] .= "<i>$start_time $end_time</i>&nbsp;-&nbsp;";
3536
                $agendaitems[$day] .= "<b>".get_lang('GlobalEvent')."</b>";
3537
                $agendaitems[$day] .= "<div>".$item['title']."</div><br>";
3538
            } else {
3539
                // this is the array construction for the DAY view
3540
                $halfhour = 2 * $agendatime['0'];
3541
                if ($agendatime['1'] >= '30') {
3542
                    $halfhour = $halfhour + 1;
3543
                }
3544
                if (!is_array($agendaitems[$halfhour])) {
3545
                    $content = $agendaitems[$halfhour];
3546
                }
3547
                $agendaitems[$halfhour] = $content."<div><i>$hour:$minute</i> <b>".get_lang(
3548
                        'GlobalEvent'
3549
                    ).":  </b>".$item['title']."</div>";
3550
            }
3551
        }
3552
3553
        return $agendaitems;
3554
    }
3555
3556
    /**
3557
     * This function retrieves all the personal agenda items and add them to the agenda items found by the other functions.
3558
     */
3559
    public static function get_personal_agenda_items(
3560
        $user_id,
3561
        $agendaitems,
3562
        $day = "",
3563
        $month = "",
3564
        $year = "",
3565
        $week = "",
3566
        $type
3567
    ) {
3568
        $tbl_personal_agenda = Database::get_main_table(TABLE_PERSONAL_AGENDA);
3569
        $user_id = intval($user_id);
3570
3571
        // 1. creating the SQL statement for getting the personal agenda items in MONTH view
3572
        if ($type == "month_view" or $type == "") {
3573
            // we are in month view
3574
            $sql = "SELECT * FROM ".$tbl_personal_agenda." WHERE user='".$user_id."' and MONTH(date)='".$month."' AND YEAR(date) = '".$year."'  ORDER BY date ASC";
3575
        }
3576
3577
        // 2. creating the SQL statement for getting the personal agenda items in WEEK view
3578
        // we are in week view
3579
        if ($type == "week_view") {
3580
            $start_end_day_of_week = self::calculate_start_end_of_week(
3581
                $week,
3582
                $year
3583
            );
3584
            $start_day = $start_end_day_of_week['start']['day'];
3585
            $start_month = $start_end_day_of_week['start']['month'];
3586
            $start_year = $start_end_day_of_week['start']['year'];
3587
            $end_day = $start_end_day_of_week['end']['day'];
3588
            $end_month = $start_end_day_of_week['end']['month'];
3589
            $end_year = $start_end_day_of_week['end']['year'];
3590
            // in sql statements you have to use year-month-day for date calculations
3591
            $start_filter = $start_year."-".$start_month."-".$start_day." 00:00:00";
3592
            $start_filter = api_get_utc_datetime($start_filter);
3593
            $end_filter = $end_year."-".$end_month."-".$end_day." 23:59:59";
3594
            $end_filter = api_get_utc_datetime($end_filter);
3595
            $sql = " SELECT * FROM ".$tbl_personal_agenda." WHERE user='".$user_id."' AND date>='".$start_filter."' AND date<='".$end_filter."'";
3596
        }
3597
        // 3. creating the SQL statement for getting the personal agenda items in DAY view
3598
        if ($type == "day_view") {
3599
            // we are in day view
3600
            // we could use mysql date() function but this is only available from 4.1 and higher
3601
            $start_filter = $year."-".$month."-".$day." 00:00:00";
3602
            $start_filter = api_get_utc_datetime($start_filter);
3603
            $end_filter = $year."-".$month."-".$day." 23:59:59";
3604
            $end_filter = api_get_utc_datetime($end_filter);
3605
            $sql = " SELECT * FROM ".$tbl_personal_agenda." WHERE user='".$user_id."' AND date>='".$start_filter."' AND date<='".$end_filter."'";
3606
        }
3607
3608
        $result = Database::query($sql);
3609
        while ($item = Database::fetch_array($result, 'ASSOC')) {
3610
            $time_minute = api_convert_and_format_date(
3611
                $item['date'],
3612
                TIME_NO_SEC_FORMAT
3613
            );
3614
            $item['date'] = api_get_local_time($item['date']);
3615
            $item['start_date_tms'] = api_strtotime($item['date']);
3616
            $item['content'] = $item['text'];
3617
3618
            // we break the date field in the database into a date and a time part
3619
            $agenda_db_date = explode(" ", $item['date']);
3620
            $date = $agenda_db_date[0];
3621
            $time = $agenda_db_date[1];
3622
            // we divide the date part into a day, a month and a year
3623
            $agendadate = explode("-", $item['date']);
3624
            $year = intval($agendadate[0]);
3625
            $month = intval($agendadate[1]);
3626
            $day = intval($agendadate[2]);
3627
            // we divide the time part into hour, minutes, seconds
3628
            $agendatime = explode(":", $time);
3629
3630
            $hour = $agendatime[0];
3631
            $minute = $agendatime[1];
3632
            $second = $agendatime[2];
3633
3634
            if ($type == 'month_view') {
3635
                $item['calendar_type'] = 'personal';
3636
                $item['start_date'] = $item['date'];
3637
                $agendaitems[$day][] = $item;
3638
                continue;
3639
            }
3640
3641
            // if the student has specified a course we a add a link to that course
3642
            if ($item['course'] != "") {
3643
                $url = api_get_path(
3644
                        WEB_CODE_PATH
3645
                    )."calendar/agenda.php?cidReq=".urlencode(
3646
                        $item['course']
3647
                    )."&day=$day&month=$month&year=$year#$day"; // RH  //Patrick Cool: to highlight the relevant agenda item
3648
                $course_link = "<a href=\"$url\" title=\"".$item['course']."\">".$item['course']."</a>";
3649
            } else {
3650
                $course_link = "";
3651
            }
3652
            // Creating the array that will be returned. If we have week or month view we have an array with the date as the key
3653
            // if we have a day_view we use a half hour as index => key 33 = 16h30
3654
            if ($type !== "day_view") {
3655
                // This is the array construction for the WEEK or MONTH view
3656
3657
                //Display events in agenda
3658
                $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 />";
3659
            } else {
3660
                // this is the array construction for the DAY view
3661
                $halfhour = 2 * $agendatime['0'];
3662
                if ($agendatime['1'] >= '30') {
3663
                    $halfhour = $halfhour + 1;
3664
                }
3665
3666
                //Display events by list
3667
                $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>";
3668
            }
3669
        }
3670
3671
        return $agendaitems;
3672
    }
3673
3674
    /**
3675
     * Show the monthcalender of the given month.
3676
     *
3677
     * @param    array    Agendaitems
3678
     * @param    int    Month number
3679
     * @param    int    Year number
3680
     * @param    array    Array of strings containing long week day names (deprecated, you can send an empty array instead)
3681
     * @param    string    The month name
3682
     */
3683
    public static function display_mymonthcalendar(
3684
        $user_id,
3685
        $agendaitems,
3686
        $month,
3687
        $year,
3688
        $weekdaynames = [],
3689
        $monthName,
3690
        $show_content = true
3691
    ) {
3692
        global $DaysShort, $course_path;
3693
        //Handle leap year
3694
        $numberofdays = [
3695
            0,
3696
            31,
3697
            28,
3698
            31,
3699
            30,
3700
            31,
3701
            30,
3702
            31,
3703
            31,
3704
            30,
3705
            31,
3706
            30,
3707
            31,
3708
        ];
3709
        if (($year % 400 == 0) or ($year % 4 == 0 and $year % 100 != 0)) {
3710
            $numberofdays[2] = 29;
3711
        }
3712
        //Get the first day of the month
3713
        $dayone = getdate(mktime(0, 0, 0, $month, 1, $year));
3714
        //Start the week on monday
3715
        $startdayofweek = $dayone['wday'] != 0 ? ($dayone['wday'] - 1) : 6;
3716
        $g_cc = (isset($_GET['courseCode']) ? $_GET['courseCode'] : '');
3717
3718
        $next_month = ($month == 1 ? 12 : $month - 1);
3719
        $prev_month = ($month == 12 ? 1 : $month + 1);
3720
3721
        $next_year = ($month == 1 ? $year - 1 : $year);
3722
        $prev_year = ($month == 12 ? $year + 1 : $year);
3723
3724
        if ($show_content) {
3725
            $back_url = Display::url(
3726
                get_lang('Previous'),
3727
                api_get_self()."?coursePath=".urlencode(
3728
                    $course_path
3729
                )."&courseCode=".Security::remove_XSS(
3730
                    $g_cc
3731
                )."&action=view&view=month&month=".$next_month."&year=".$next_year
3732
            );
3733
            $next_url = Display::url(
3734
                get_lang('Next'),
3735
                api_get_self()."?coursePath=".urlencode(
3736
                    $course_path
3737
                )."&courseCode=".Security::remove_XSS(
3738
                    $g_cc
3739
                )."&action=view&view=month&month=".$prev_month."&year=".$prev_year
3740
            );
3741
        } else {
3742
            $back_url = Display::url(
3743
                get_lang('Previous'),
3744
                '',
3745
                [
3746
                    'onclick' => "load_calendar('".$user_id."','".$next_month."', '".$next_year."'); ",
3747
                    'class' => 'btn ui-button ui-widget ui-state-default',
3748
                ]
3749
            );
3750
            $next_url = Display::url(
3751
                get_lang('Next'),
3752
                '',
3753
                [
3754
                    'onclick' => "load_calendar('".$user_id."','".$prev_month."', '".$prev_year."'); ",
3755
                    'class' => 'pull-right btn ui-button ui-widget ui-state-default',
3756
                ]
3757
            );
3758
        }
3759
        $html = '';
3760
        $html .= '<div class="actions">';
3761
        $html .= '<div class="row">';
3762
        $html .= '<div class="col-md-4">'.$back_url.'</div>';
3763
        $html .= '<div class="col-md-4"><p class="agenda-title text-center">'.$monthName." ".$year.'</p></div>';
3764
        $html .= '<div class="col-md-4">'.$next_url.'</div>';
3765
        $html .= '</div>';
3766
        $html .= '</div>';
3767
        $html .= '<table id="agenda_list2" class="table table-bordered">';
3768
        $html .= '<tr>';
3769
        for ($ii = 1; $ii < 8; $ii++) {
3770
            $html .= '<td class="weekdays">'.$DaysShort[$ii % 7].'</td>';
3771
        }
3772
        $html .= '</tr>';
3773
3774
        $curday = -1;
3775
        $today = getdate();
3776
        while ($curday <= $numberofdays[$month]) {
3777
            $html .= "<tr>";
3778
            for ($ii = 0; $ii < 7; $ii++) {
3779
                if (($curday == -1) && ($ii == $startdayofweek)) {
3780
                    $curday = 1;
3781
                }
3782
                if (($curday > 0) && ($curday <= $numberofdays[$month])) {
3783
                    $bgcolor = $class = 'class="days_week"';
3784
                    $dayheader = Display::div(
3785
                        $curday,
3786
                        ['class' => 'agenda_day']
3787
                    );
3788
                    if (($curday == $today['mday']) && ($year == $today['year']) && ($month == $today['mon'])) {
3789
                        $class = "class=\"days_today\" style=\"width:10%;\"";
3790
                    }
3791
3792
                    $html .= "<td ".$class.">".$dayheader;
3793
3794
                    if (!empty($agendaitems[$curday])) {
3795
                        $items = $agendaitems[$curday];
3796
                        $items = msort($items, 'start_date_tms');
3797
3798
                        foreach ($items as $value) {
3799
                            $value['title'] = Security::remove_XSS(
3800
                                $value['title']
3801
                            );
3802
                            $start_time = api_format_date(
3803
                                $value['start_date'],
3804
                                TIME_NO_SEC_FORMAT
3805
                            );
3806
                            $end_time = '';
3807
3808
                            if (!empty($value['end_date'])) {
3809
                                $end_time = '-&nbsp;<i>'.api_format_date(
3810
                                        $value['end_date'],
3811
                                        DATE_TIME_FORMAT_LONG
3812
                                    ).'</i>';
3813
                            }
3814
                            $complete_time = '<i>'.api_format_date(
3815
                                    $value['start_date'],
3816
                                    DATE_TIME_FORMAT_LONG
3817
                                ).'</i>&nbsp;'.$end_time;
3818
                            $time = '<i>'.$start_time.'</i>';
3819
3820
                            switch ($value['calendar_type']) {
3821
                                case 'personal':
3822
                                    $bg_color = '#D0E7F4';
3823
                                    $icon = Display::return_icon(
3824
                                        'user.png',
3825
                                        get_lang('MyAgenda'),
3826
                                        [],
3827
                                        ICON_SIZE_SMALL
3828
                                    );
3829
                                    break;
3830
                                case 'global':
3831
                                    $bg_color = '#FFBC89';
3832
                                    $icon = Display::return_icon(
3833
                                        'view_remove.png',
3834
                                        get_lang('GlobalEvent'),
3835
                                        [],
3836
                                        ICON_SIZE_SMALL
3837
                                    );
3838
                                    break;
3839
                                case 'course':
3840
                                    $bg_color = '#CAFFAA';
3841
                                    $icon_name = 'course.png';
3842
                                    if (!empty($value['session_id'])) {
3843
                                        $icon_name = 'session.png';
3844
                                    }
3845
                                    if ($show_content) {
3846
                                        $icon = Display::url(
3847
                                            Display::return_icon(
3848
                                                $icon_name,
3849
                                                $value['course_name'].' '.get_lang(
3850
                                                    'Course'
3851
                                                ),
3852
                                                [],
3853
                                                ICON_SIZE_SMALL
3854
                                            ),
3855
                                            $value['url']
3856
                                        );
3857
                                    } else {
3858
                                        $icon = Display::return_icon(
3859
                                            $icon_name,
3860
                                            $value['course_name'].' '.get_lang(
3861
                                                'Course'
3862
                                            ),
3863
                                            [],
3864
                                            ICON_SIZE_SMALL
3865
                                        );
3866
                                    }
3867
                                    break;
3868
                                default:
3869
                                    break;
3870
                            }
3871
3872
                            $result = '<div class="rounded_div_agenda" style="background-color:'.$bg_color.';">';
3873
3874
                            if ($show_content) {
3875
                                //Setting a personal event to green
3876
                                $icon = Display::div(
3877
                                    $icon,
3878
                                    ['style' => 'float:right']
3879
                                );
3880
3881
                                $link = $value['calendar_type'].'_'.$value['id'].'_'.$value['course_id'].'_'.$value['session_id'];
3882
3883
                                //Link to bubble
3884
                                $url = Display::url(
3885
                                    cut($value['title'], 40),
3886
                                    '#',
3887
                                    ['id' => $link, 'class' => 'opener']
3888
                                );
3889
                                $result .= $time.' '.$icon.' '.Display::div(
3890
                                        $url
3891
                                    );
3892
3893
                                //Hidden content
3894
                                $content = Display::div(
3895
                                    $icon.Display::tag(
3896
                                        'h2',
3897
                                        $value['course_name']
3898
                                    ).'<hr />'.Display::tag(
3899
                                        'h3',
3900
                                        $value['title']
3901
                                    ).$complete_time.'<hr />'.Security::remove_XSS(
3902
                                        $value['content']
3903
                                    )
3904
                                );
3905
3906
                                //Main div
3907
                                $result .= Display::div(
3908
                                    $content,
3909
                                    [
3910
                                        'id' => 'main_'.$link,
3911
                                        'class' => 'dialog',
3912
                                        'style' => 'display:none',
3913
                                    ]
3914
                                );
3915
                                $result .= '</div>';
3916
                                $html .= $result;
3917
                            } else {
3918
                                $html .= $result .= $icon.'</div>';
3919
                            }
3920
                        }
3921
                    }
3922
                    $html .= "</td>";
3923
                    $curday++;
3924
                } else {
3925
                    $html .= "<td></td>";
3926
                }
3927
            }
3928
            $html .= "</tr>";
3929
        }
3930
        $html .= "</table>";
3931
        echo $html;
3932
    }
3933
3934
    /**
3935
     * Get personal agenda items between two dates (=all events from all registered courses).
3936
     *
3937
     * @param int $user_id user ID of the user
3938
     * @param    string    Optional start date in datetime format (if no start date is given, uses today)
3939
     * @param    string    Optional end date in datetime format (if no date is given, uses one year from now)
3940
     *
3941
     * @return array array of events ordered by start date, in
3942
     *               [0]('datestart','dateend','title'),[1]('datestart','dateend','title','link','coursetitle') format,
3943
     *               where datestart and dateend are in yyyyMMddhhmmss format
3944
     *
3945
     * @deprecated use agenda events
3946
     */
3947
    public static function get_personal_agenda_items_between_dates(
3948
        $user_id,
3949
        $date_start = '',
3950
        $date_end = ''
3951
    ) {
3952
        $items = [];
3953
        if ($user_id != strval(intval($user_id))) {
3954
            return $items;
3955
        }
3956
        if (empty($date_start)) {
3957
            $date_start = date('Y-m-d H:i:s');
3958
        }
3959
        if (empty($date_end)) {
3960
            $date_end = date(
3961
                'Y-m-d H:i:s',
3962
                mktime(0, 0, 0, date("m"), date("d"), date("Y") + 1)
3963
            );
3964
        }
3965
        $expr = '/\d{4}-\d{2}-\d{2}\ \d{2}:\d{2}:\d{2}/';
3966
        if (!preg_match($expr, $date_start)) {
3967
            return $items;
3968
        }
3969
        if (!preg_match($expr, $date_end)) {
3970
            return $items;
3971
        }
3972
3973
        // get agenda-items for every course
3974
        $courses = api_get_user_courses($user_id, false);
3975
        foreach ($courses as $id => $course) {
3976
            $c = api_get_course_info_by_id($course['real_id']);
3977
            //databases of the courses
3978
            $t_a = Database::get_course_table(TABLE_AGENDA, $course['db']);
3979
            $t_ip = Database::get_course_table(
3980
                TABLE_ITEM_PROPERTY,
3981
                $course['db']
3982
            );
3983
            // get the groups to which the user belong
3984
            $group_memberships = GroupManager:: get_group_ids(
3985
                $course['db'],
3986
                $user_id
3987
            );
3988
            // if the user is administrator of that course we show all the agenda items
3989
            if ($course['status'] == '1') {
3990
                //echo "course admin";
3991
                $sqlquery = "SELECT ".
3992
                    " DISTINCT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref ".
3993
                    " FROM ".$t_a." agenda, ".
3994
                    $t_ip." ip ".
3995
                    " WHERE agenda.id = ip.ref ".
3996
                    " AND agenda.start_date>='$date_start' ".
3997
                    " AND agenda.end_date<='$date_end' ".
3998
                    " AND ip.tool='".TOOL_CALENDAR_EVENT."' ".
3999
                    " AND ip.visibility='1' ".
4000
                    " GROUP BY agenda.id ".
4001
                    " ORDER BY start_date ";
4002
            } else {
4003
                // if the user is not an administrator of that course, then...
4004
                if (is_array($group_memberships) && count(
4005
                        $group_memberships
4006
                    ) > 0
4007
                ) {
4008
                    $sqlquery = "SELECT ".
4009
                        "DISTINCT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref ".
4010
                        " FROM ".$t_a." agenda, ".
4011
                        $t_ip." ip ".
4012
                        " WHERE agenda.id = ip.ref ".
4013
                        " AND agenda.start_date>='$date_start' ".
4014
                        " AND agenda.end_date<='$date_end' ".
4015
                        " AND ip.tool='".TOOL_CALENDAR_EVENT."' ".
4016
                        " AND	( ip.to_user_id='".$user_id."' OR (ip.to_group_id IS NULL OR ip.to_group_id IN (0, ".implode(
4017
                            ", ",
4018
                            $group_memberships
4019
                        ).")) ) ".
4020
                        " AND ip.visibility='1' ".
4021
                        " ORDER BY start_date ";
4022
                } else {
4023
                    $sqlquery = "SELECT ".
4024
                        "DISTINCT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref ".
4025
                        " FROM ".$t_a." agenda, ".
4026
                        $t_ip." ip ".
4027
                        " WHERE agenda.id = ip.ref ".
4028
                        " AND agenda.start_date>='$date_start' ".
4029
                        " AND agenda.end_date<='$date_end' ".
4030
                        " AND ip.tool='".TOOL_CALENDAR_EVENT."' ".
4031
                        " AND ( ip.to_user_id='".$user_id."' OR ip.to_group_id='0' OR ip.to_group_id IS NULL) ".
4032
                        " AND ip.visibility='1' ".
4033
                        " ORDER BY start_date ";
4034
                }
4035
            }
4036
4037
            $result = Database::query($sqlquery);
4038
            while ($item = Database::fetch_array($result)) {
4039
                $agendaday = date("j", strtotime($item['start_date']));
4040
                $month = date("n", strtotime($item['start_date']));
4041
                $year = date("Y", strtotime($item['start_date']));
4042
                $URL = api_get_path(
4043
                        WEB_PATH
4044
                    )."main/calendar/agenda.php?cidReq=".urlencode(
4045
                        $course["code"]
4046
                    )."&day=$agendaday&month=$month&year=$year#$agendaday";
4047
                list($year, $month, $day, $hour, $min, $sec) = split(
4048
                    '[-: ]',
4049
                    $item['start_date']
4050
                );
4051
                $start_date = $year.$month.$day.$hour.$min;
4052
                list($year, $month, $day, $hour, $min, $sec) = split(
4053
                    '[-: ]',
4054
                    $item['end_date']
4055
                );
4056
                $end_date = $year.$month.$day.$hour.$min;
4057
4058
                $items[] = [
4059
                    'datestart' => $start_date,
4060
                    'dateend' => $end_date,
4061
                    'title' => $item['title'],
4062
                    'link' => $URL,
4063
                    'coursetitle' => $c['name'],
4064
                ];
4065
            }
4066
        }
4067
4068
        return $items;
4069
    }
4070
4071
    /**
4072
     * This function retrieves one personal agenda item returns it.
4073
     *
4074
     * @param int $id The agenda item ID
4075
     *
4076
     * @return array The results of the database query, or null if not found
4077
     */
4078
    public static function get_personal_agenda_item($id)
4079
    {
4080
        $tbl_personal_agenda = Database::get_main_table(TABLE_PERSONAL_AGENDA);
4081
        $id = intval($id);
4082
        // make sure events of the personal agenda can only be seen by the user himself
4083
        $user = api_get_user_id();
4084
        $sql = " SELECT * FROM ".$tbl_personal_agenda." WHERE id=".$id." AND user = ".$user;
4085
        $result = Database::query($sql);
4086
        if (Database::num_rows($result) == 1) {
4087
            $item = Database::fetch_array($result);
4088
        } else {
4089
            $item = null;
4090
        }
4091
4092
        return $item;
4093
    }
4094
4095
    /**
4096
     * This function calculates the startdate of the week (monday)
4097
     * and the enddate of the week (sunday)
4098
     * and returns it as an array.
4099
     */
4100
    public static function calculate_start_end_of_week($week_number, $year)
4101
    {
4102
        // determine the start and end date
4103
        // step 1: we calculate a timestamp for a day in this week
4104
        $random_day_in_week = mktime(
4105
                0,
4106
                0,
4107
                0,
4108
                1,
4109
                1,
4110
                $year
4111
            ) + ($week_number) * (7 * 24 * 60 * 60); // we calculate a random day in this week
4112
        // step 2: we which day this is (0=sunday, 1=monday, ...)
4113
        $number_day_in_week = date('w', $random_day_in_week);
4114
        // step 3: we calculate the timestamp of the monday of the week we are in
4115
        $start_timestamp = $random_day_in_week - (($number_day_in_week - 1) * 24 * 60 * 60);
4116
        // step 4: we calculate the timestamp of the sunday of the week we are in
4117
        $end_timestamp = $random_day_in_week + ((7 - $number_day_in_week + 1) * 24 * 60 * 60) - 3600;
4118
        // step 5: calculating the start_day, end_day, start_month, end_month, start_year, end_year
4119
        $start_day = date('j', $start_timestamp);
4120
        $start_month = date('n', $start_timestamp);
4121
        $start_year = date('Y', $start_timestamp);
4122
        $end_day = date('j', $end_timestamp);
4123
        $end_month = date('n', $end_timestamp);
4124
        $end_year = date('Y', $end_timestamp);
4125
        $start_end_array['start']['day'] = $start_day;
4126
        $start_end_array['start']['month'] = $start_month;
4127
        $start_end_array['start']['year'] = $start_year;
4128
        $start_end_array['end']['day'] = $end_day;
4129
        $start_end_array['end']['month'] = $end_month;
4130
        $start_end_array['end']['year'] = $end_year;
4131
4132
        return $start_end_array;
4133
    }
4134
4135
    /**
4136
     * @return bool
4137
     */
4138
    public function getIsAllowedToEdit()
4139
    {
4140
        return $this->isAllowedToEdit;
4141
    }
4142
4143
    /**
4144
     * @param bool $isAllowedToEdit
4145
     */
4146
    public function setIsAllowedToEdit($isAllowedToEdit)
4147
    {
4148
        $this->isAllowedToEdit = $isAllowedToEdit;
4149
    }
4150
4151
    /**
4152
     * Format needed for the Fullcalendar js lib.
4153
     *
4154
     * @param string $utcTime
4155
     *
4156
     * @return bool|string
4157
     */
4158
    private function formatEventDate($utcTime)
4159
    {
4160
        $utcTimeZone = new DateTimeZone('UTC');
4161
        $platformTimeZone = new DateTimeZone(api_get_timezone());
4162
4163
        $eventDate = new DateTime($utcTime, $utcTimeZone);
4164
        $eventDate->setTimezone($platformTimeZone);
4165
4166
        return $eventDate->format(DateTime::ISO8601);
4167
    }
4168
}
4169