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

Agenda::addEvent()   F

Complexity

Conditions 21
Paths 408

Size

Total Lines 211
Code Lines 145

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 21
eloc 145
nc 408
nop 12
dl 0
loc 211
rs 0.6576
c 0
b 0
f 0

How to fix   Long Method    Complexity    Many Parameters   

Long Method

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

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

Commonly applied refactorings include:

Many Parameters

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

There are several approaches to avoid long parameter lists:

1
<?php
2
/* For licensing terms, see /license.txt */
3
4
/**
5
 * Class Agenda.
6
 *
7
 * @author: Julio Montoya <[email protected]>
8
 */
9
class Agenda
10
{
11
    public $events = [];
12
    /** @var string Current type */
13
    public $type = 'personal';
14
    public $types = ['personal', 'admin', 'course'];
15
    public $sessionId = 0;
16
    public $senderId;
17
    /** @var array */
18
    public $course;
19
    /** @var string */
20
    public $comment;
21
    public $eventStudentPublicationColor;
22
    /** @var array */
23
    private $sessionInfo;
24
    /** @var bool */
25
    private $isAllowedToEdit;
26
27
    /**
28
     * Constructor.
29
     *
30
     * @param string $type
31
     * @param int    $senderId  Optional The user sender ID
32
     * @param int    $courseId  Optional. The course ID
33
     * @param int    $sessionId Optional The session ID
34
     */
35
    public function __construct(
36
        $type,
37
        $senderId = 0,
38
        $courseId = 0,
39
        $sessionId = 0
40
    ) {
41
        // Table definitions
42
        $this->tbl_global_agenda = Database::get_main_table(TABLE_MAIN_SYSTEM_CALENDAR);
43
        $this->tbl_personal_agenda = Database::get_main_table(TABLE_PERSONAL_AGENDA);
44
        $this->tbl_course_agenda = Database::get_course_table(TABLE_AGENDA);
45
        $this->table_repeat = Database::get_course_table(TABLE_AGENDA_REPEAT);
46
47
        $this->setType($type);
48
        $this->setSenderId($senderId ?: api_get_user_id());
49
        $isAllowToEdit = false;
50
51
        switch ($type) {
52
            case 'course':
53
                $sessionId = $sessionId ?: api_get_session_id();
54
                $sessionInfo = api_get_session_info($sessionId);
55
                $this->setSessionId($sessionId);
56
                $this->setSessionInfo($sessionInfo);
57
58
                // Setting the course object if we are in a course
59
                $courseInfo = api_get_course_info_by_id($courseId);
60
                if (!empty($courseInfo)) {
61
                    $this->set_course($courseInfo);
62
                }
63
64
                // Check if teacher/admin rights.
65
                $isAllowToEdit = api_is_allowed_to_edit(false, true);
66
                // Check course setting.
67
                if (api_get_course_setting('allow_user_edit_agenda') === '1'
68
                    && api_is_allowed_in_course()
69
                ) {
70
                    $isAllowToEdit = true;
71
                }
72
73
                $groupId = api_get_group_id();
74
                if (!empty($groupId)) {
75
                    $groupInfo = GroupManager::get_group_properties($groupId);
76
                    $userHasAccess = GroupManager::user_has_access(
77
                        api_get_user_id(),
78
                        $groupInfo['iid'],
79
                        GroupManager::GROUP_TOOL_CALENDAR
80
                    );
81
                    $isTutor = GroupManager::is_tutor_of_group(
82
                        api_get_user_id(),
83
                        $groupInfo
84
                    );
85
86
                    $isGroupAccess = $userHasAccess || $isTutor;
87
                    $isAllowToEdit = false;
88
                    if ($isGroupAccess) {
89
                        $isAllowToEdit = true;
90
                    }
91
                }
92
93
                if (!empty($sessionId)) {
94
                    $allowDhrToEdit = api_get_configuration_value('allow_agenda_edit_for_hrm');
95
                    if ($allowDhrToEdit) {
96
                        $isHrm = SessionManager::isUserSubscribedAsHRM($sessionId, api_get_user_id());
97
                        if ($isHrm) {
98
                            $isAllowToEdit = true;
99
                        }
100
                    }
101
                }
102
                break;
103
            case 'admin':
104
                $isAllowToEdit = api_is_platform_admin();
105
                break;
106
            case 'personal':
107
                $isAllowToEdit = !api_is_anonymous();
108
                break;
109
        }
110
111
        $this->setIsAllowedToEdit($isAllowToEdit);
112
        $this->events = [];
113
        $agendaColors = array_merge(
114
            [
115
                'platform' => 'red', //red
116
                'course' => '#458B00', //green
117
                'group' => '#A0522D', //siena
118
                'session' => '#00496D', // kind of green
119
                'other_session' => '#999', // kind of green
120
                'personal' => 'steel blue', //steel blue
121
                'student_publication' => '#FF8C00', //DarkOrange
122
            ],
123
            api_get_configuration_value('agenda_colors') ?: []
124
        );
125
126
        // Event colors
127
        $this->event_platform_color = $agendaColors['platform'];
128
        $this->event_course_color = $agendaColors['course'];
129
        $this->event_group_color = $agendaColors['group'];
130
        $this->event_session_color = $agendaColors['session'];
131
        $this->eventOtherSessionColor = $agendaColors['other_session'];
132
        $this->event_personal_color = $agendaColors['personal'];
133
        $this->eventStudentPublicationColor = $agendaColors['student_publication'];
134
    }
135
136
    /**
137
     * @param int $senderId
138
     */
139
    public function setSenderId($senderId)
140
    {
141
        $this->senderId = (int) $senderId;
142
    }
143
144
    /**
145
     * @return int
146
     */
147
    public function getSenderId()
148
    {
149
        return $this->senderId;
150
    }
151
152
    /**
153
     * @param string $type can be 'personal', 'admin'  or  'course'
154
     */
155
    public function setType($type)
156
    {
157
        $typeList = $this->getTypes();
158
        if (in_array($type, $typeList)) {
159
            $this->type = $type;
160
        }
161
    }
162
163
    /**
164
     * @param int $id
165
     */
166
    public function setSessionId($id)
167
    {
168
        $this->sessionId = (int) $id;
169
    }
170
171
    /**
172
     * @param array $sessionInfo
173
     */
174
    public function setSessionInfo($sessionInfo)
175
    {
176
        $this->sessionInfo = $sessionInfo;
177
    }
178
179
    /**
180
     * @return int $id
181
     */
182
    public function getSessionId()
183
    {
184
        return $this->sessionId;
185
    }
186
187
    /**
188
     * @param array $courseInfo
189
     */
190
    public function set_course($courseInfo)
191
    {
192
        $this->course = $courseInfo;
193
    }
194
195
    /**
196
     * @return array
197
     */
198
    public function getTypes()
199
    {
200
        return $this->types;
201
    }
202
203
    /**
204
     * Adds an event to the calendar.
205
     *
206
     * @param string $start                 datetime format: 2012-06-14 09:00:00 in local time
207
     * @param string $end                   datetime format: 2012-06-14 09:00:00 in local time
208
     * @param string $allDay                (true, false)
209
     * @param string $title
210
     * @param string $content
211
     * @param array  $usersToSend           array('everyone') or a list of user/group ids
212
     * @param bool   $addAsAnnouncement     event as a *course* announcement
213
     * @param int    $parentEventId
214
     * @param array  $attachmentArray       array of $_FILES['']
215
     * @param array  $attachmentCommentList
216
     * @param string $eventComment
217
     * @param string $color
218
     *
219
     * @return int
220
     */
221
    public function addEvent(
222
        $start,
223
        $end,
224
        $allDay,
225
        $title,
226
        $content,
227
        $usersToSend = [],
228
        $addAsAnnouncement = false,
229
        $parentEventId = null,
230
        $attachmentArray = [],
231
        $attachmentCommentList = [],
232
        $eventComment = null,
233
        $color = ''
234
    ) {
235
        $start = api_get_utc_datetime($start);
236
        $end = api_get_utc_datetime($end);
237
        $allDay = isset($allDay) && $allDay === 'true' ? 1 : 0;
238
        $id = null;
239
240
        switch ($this->type) {
241
            case 'personal':
242
                $attributes = [
243
                    'user' => api_get_user_id(),
244
                    'title' => $title,
245
                    'text' => $content,
246
                    'date' => $start,
247
                    'enddate' => $end,
248
                    'all_day' => $allDay,
249
                    'color' => $color,
250
                ];
251
252
                $id = Database::insert(
253
                    $this->tbl_personal_agenda,
254
                    $attributes
255
                );
256
                break;
257
            case 'course':
258
                $attributes = [
259
                    'title' => $title,
260
                    'content' => $content,
261
                    'start_date' => $start,
262
                    'end_date' => $end,
263
                    'all_day' => $allDay,
264
                    'session_id' => $this->getSessionId(),
265
                    'c_id' => $this->course['real_id'],
266
                    'comment' => $eventComment,
267
                    'color' => $color,
268
                ];
269
270
                if (!empty($parentEventId)) {
271
                    $attributes['parent_event_id'] = $parentEventId;
272
                }
273
274
                $senderId = $this->getSenderId();
275
                $sessionId = $this->getSessionId();
276
277
                // Simple course event.
278
                $id = Database::insert($this->tbl_course_agenda, $attributes);
279
280
                if ($id) {
281
                    $sql = "UPDATE ".$this->tbl_course_agenda." SET id = iid WHERE iid = $id";
282
                    Database::query($sql);
283
284
                    $groupId = api_get_group_id();
285
                    $groupInfo = [];
286
                    if ($groupId) {
287
                        $groupInfo = GroupManager::get_group_properties(
288
                            $groupId
289
                        );
290
                    }
291
292
                    if (!empty($usersToSend)) {
293
                        $sendTo = $this->parseSendToArray($usersToSend);
294
                        if ($sendTo['everyone']) {
295
                            api_item_property_update(
296
                                $this->course,
297
                                TOOL_CALENDAR_EVENT,
298
                                $id,
299
                                'AgendaAdded',
300
                                $senderId,
301
                                $groupInfo,
302
                                '',
303
                                $start,
304
                                $end,
305
                                $sessionId
306
                            );
307
                            api_item_property_update(
308
                                $this->course,
309
                                TOOL_CALENDAR_EVENT,
310
                                $id,
311
                                'visible',
312
                                $senderId,
313
                                $groupInfo,
314
                                '',
315
                                $start,
316
                                $end,
317
                                $sessionId
318
                            );
319
                        } else {
320
                            // Storing the selected groups
321
                            if (!empty($sendTo['groups'])) {
322
                                foreach ($sendTo['groups'] as $group) {
323
                                    $groupInfoItem = [];
324
                                    if ($group) {
325
                                        $groupInfoItem = GroupManager::get_group_properties($group);
326
                                    }
327
328
                                    api_item_property_update(
329
                                        $this->course,
330
                                        TOOL_CALENDAR_EVENT,
331
                                        $id,
332
                                        'AgendaAdded',
333
                                        $senderId,
334
                                        $groupInfoItem,
335
                                        0,
336
                                        $start,
337
                                        $end,
338
                                        $sessionId
339
                                    );
340
341
                                    api_item_property_update(
342
                                        $this->course,
343
                                        TOOL_CALENDAR_EVENT,
344
                                        $id,
345
                                        'visible',
346
                                        $senderId,
347
                                        $groupInfoItem,
348
                                        0,
349
                                        $start,
350
                                        $end,
351
                                        $sessionId
352
                                    );
353
                                }
354
                            }
355
356
                            // storing the selected users
357
                            if (!empty($sendTo['users'])) {
358
                                foreach ($sendTo['users'] as $userId) {
359
                                    api_item_property_update(
360
                                        $this->course,
361
                                        TOOL_CALENDAR_EVENT,
362
                                        $id,
363
                                        'AgendaAdded',
364
                                        $senderId,
365
                                        $groupInfo,
366
                                        $userId,
367
                                        $start,
368
                                        $end,
369
                                        $sessionId
370
                                    );
371
372
                                    api_item_property_update(
373
                                        $this->course,
374
                                        TOOL_CALENDAR_EVENT,
375
                                        $id,
376
                                        'visible',
377
                                        $senderId,
378
                                        $groupInfo,
379
                                        $userId,
380
                                        $start,
381
                                        $end,
382
                                        $sessionId
383
                                    );
384
                                }
385
                            }
386
                        }
387
                    }
388
389
                    // Add announcement.
390
                    if ($addAsAnnouncement) {
391
                        $this->storeAgendaEventAsAnnouncement(
392
                            $id,
393
                            $usersToSend
394
                        );
395
                    }
396
397
                    // Add attachment.
398
                    if (isset($attachmentArray) && !empty($attachmentArray)) {
399
                        $counter = 0;
400
                        foreach ($attachmentArray as $attachmentItem) {
401
                            $this->addAttachment(
402
                                $id,
403
                                $attachmentItem,
404
                                $attachmentCommentList[$counter],
405
                                $this->course
406
                            );
407
                            $counter++;
408
                        }
409
                    }
410
                }
411
                break;
412
            case 'admin':
413
                if (api_is_platform_admin()) {
414
                    $attributes = [
415
                        'title' => $title,
416
                        'content' => $content,
417
                        'start_date' => $start,
418
                        'end_date' => $end,
419
                        'all_day' => $allDay,
420
                        'access_url_id' => api_get_current_access_url_id(),
421
                    ];
422
423
                    $id = Database::insert(
424
                        $this->tbl_global_agenda,
425
                        $attributes
426
                    );
427
                }
428
                break;
429
        }
430
431
        return $id;
432
    }
433
434
    /**
435
     * @param int $eventId
436
     * @param int $courseId
437
     *
438
     * @return array
439
     */
440
    public function getRepeatedInfoByEvent($eventId, $courseId)
441
    {
442
        $repeatTable = Database::get_course_table(TABLE_AGENDA_REPEAT);
443
        $eventId = (int) $eventId;
444
        $courseId = (int) $courseId;
445
        $sql = "SELECT * FROM $repeatTable
446
                WHERE c_id = $courseId AND cal_id = $eventId";
447
        $res = Database::query($sql);
448
        $repeatInfo = [];
449
        if (Database::num_rows($res) > 0) {
450
            $repeatInfo = Database::fetch_array($res, 'ASSOC');
451
        }
452
453
        return $repeatInfo;
454
    }
455
456
    /**
457
     * @param string $type
458
     * @param string $startEvent      in UTC
459
     * @param string $endEvent        in UTC
460
     * @param string $repeatUntilDate in UTC
461
     *
462
     * @throws Exception
463
     *
464
     * @return array
465
     */
466
    public function generateDatesByType($type, $startEvent, $endEvent, $repeatUntilDate)
467
    {
468
        $continue = true;
469
        $repeatUntilDate = new DateTime($repeatUntilDate, new DateTimeZone('UTC'));
470
        $loopMax = 365;
471
        $counter = 0;
472
        $list = [];
473
474
        switch ($type) {
475
            case 'daily':
476
                $interval = 'P1D';
477
                break;
478
            case 'weekly':
479
                $interval = 'P1W';
480
                break;
481
            case 'monthlyByDate':
482
                $interval = 'P1M';
483
                break;
484
            case 'monthlyByDay':
485
                // not yet implemented
486
                break;
487
            case 'monthlyByDayR':
488
                // not yet implemented
489
                break;
490
            case 'yearly':
491
                $interval = 'P1Y';
492
                break;
493
        }
494
495
        if (empty($interval)) {
496
            return [];
497
        }
498
        $timeZone = api_get_timezone();
499
500
        while ($continue) {
501
            $startDate = new DateTime($startEvent, new DateTimeZone('UTC'));
502
            $endDate = new DateTime($endEvent, new DateTimeZone('UTC'));
503
504
            $startDate->add(new DateInterval($interval));
505
            $endDate->add(new DateInterval($interval));
506
507
            $newStartDate = $startDate->format('Y-m-d H:i:s');
508
            $newEndDate = $endDate->format('Y-m-d H:i:s');
509
510
            $startEvent = $newStartDate;
511
            $endEvent = $newEndDate;
512
513
            if ($endDate > $repeatUntilDate) {
514
                break;
515
            }
516
517
            // @todo remove comment code
518
            $startDateInLocal = new DateTime($newStartDate, new DateTimeZone($timeZone));
519
            //$originalOffset = $startDate->getOffset();
520
            if ($startDateInLocal->format('I') == 0) {
521
                // Is saving time? Then fix UTC time to add time
522
                $seconds = $startDateInLocal->getOffset();
523
                $startDate->add(new DateInterval("PT".$seconds."S"));
524
                $startDateFixed = $startDate->format('Y-m-d H:i:s');
525
                $startDateInLocalFixed = new DateTime($startDateFixed, new DateTimeZone($timeZone));
526
                $newStartDate = $startDateInLocalFixed->format('Y-m-d H:i:s');
527
            } else {
528
                /*$seconds = $startDateInLocal->getOffset();
529
                $startDate->add(new DateInterval("PT".$seconds."S"));
530
                $startDateFixed = $startDate->format('Y-m-d H:i:s');
531
                $startDateInLocalFixed = new DateTime($startDateFixed, new DateTimeZone($timeZone));
532
                $newStartDate = $startDateInLocalFixed->format('Y-m-d H:i:s');*/
533
            }
534
            //var_dump($newStartDate.' - '.$startDateInLocal->format('I'));
535
            $endDateInLocal = new DateTime($newEndDate, new DateTimeZone($timeZone));
536
537
            if ($endDateInLocal->format('I') == 0) {
538
                // Is saving time? Then fix UTC time to add time
539
                $seconds = $endDateInLocal->getOffset();
540
                $endDate->add(new DateInterval("PT".$seconds."S"));
541
                $endDateFixed = $endDate->format('Y-m-d H:i:s');
542
                $endDateInLocalFixed = new DateTime($endDateFixed, new DateTimeZone($timeZone));
543
                $newEndDate = $endDateInLocalFixed->format('Y-m-d H:i:s');
544
            }
545
            $list[] = ['start' => $newStartDate, 'end' => $newEndDate, 'i' => $startDateInLocal->format('I')];
546
            $counter++;
547
548
            // just in case stop if more than $loopMax
549
            if ($counter > $loopMax) {
550
                break;
551
            }
552
        }
553
554
        return $list;
555
    }
556
557
    /**
558
     * @param int    $eventId
559
     * @param string $type
560
     * @param string $end     in UTC
561
     * @param array  $sentTo
562
     *
563
     * @return bool
564
     */
565
    public function addRepeatedItem($eventId, $type, $end, $sentTo = [])
566
    {
567
        $t_agenda = Database::get_course_table(TABLE_AGENDA);
568
        $t_agenda_r = Database::get_course_table(TABLE_AGENDA_REPEAT);
569
570
        if (empty($this->course)) {
571
            return false;
572
        }
573
574
        $courseId = $this->course['real_id'];
575
        $eventId = (int) $eventId;
576
577
        $sql = "SELECT title, content, start_date, end_date, all_day
578
                FROM $t_agenda
579
                WHERE c_id = $courseId AND id = $eventId";
580
        $res = Database::query($sql);
581
582
        if (Database::num_rows($res) !== 1) {
583
            return false;
584
        }
585
586
        $typeList = [
587
            'daily',
588
            'weekly',
589
            'monthlyByDate',
590
            'monthlyByDay',
591
            'monthlyByDayR',
592
            'yearly',
593
        ];
594
595
        if (!in_array($type, $typeList)) {
596
            return false;
597
        }
598
599
        $now = time();
600
601
        // The event has to repeat *in the future*. We don't allow repeated
602
        // events in the past
603
        if ($end > $now) {
604
            return false;
605
        }
606
607
        $row = Database::fetch_array($res);
608
609
        $title = $row['title'];
610
        $content = $row['content'];
611
        $allDay = $row['all_day'];
612
613
        $type = Database::escape_string($type);
614
        $end = Database::escape_string($end);
615
        $endTimeStamp = api_strtotime($end, 'UTC');
616
        $sql = "INSERT INTO $t_agenda_r (c_id, cal_id, cal_type, cal_end)
617
                VALUES ($courseId, '$eventId', '$type', '$endTimeStamp')";
618
        Database::query($sql);
619
620
        $generatedDates = $this->generateDatesByType($type, $row['start_date'], $row['end_date'], $end);
621
622
        if (empty($generatedDates)) {
623
            return false;
624
        }
625
626
        foreach ($generatedDates as $dateInfo) {
627
            $start = api_get_local_time($dateInfo['start']);
628
            $end = api_get_local_time($dateInfo['end']);
629
            $this->addEvent(
630
                $start,
631
                $end,
632
                $allDay,
633
                $title,
634
                $content,
635
                $sentTo,
636
                false,
637
                $eventId
638
            );
639
        }
640
641
        return true;
642
    }
643
644
    /**
645
     * @param int   $item_id
646
     * @param array $sentTo
647
     *
648
     * @return int
649
     */
650
    public function storeAgendaEventAsAnnouncement($item_id, $sentTo = [])
651
    {
652
        $table_agenda = Database::get_course_table(TABLE_AGENDA);
653
        $courseId = api_get_course_int_id();
654
655
        // Check params
656
        if (empty($item_id) || $item_id != strval(intval($item_id))) {
657
            return -1;
658
        }
659
660
        // Get the agenda item.
661
        $item_id = intval($item_id);
662
        $sql = "SELECT * FROM $table_agenda
663
                WHERE c_id = $courseId AND id = ".$item_id;
664
        $res = Database::query($sql);
665
666
        if (Database::num_rows($res) > 0) {
667
            $row = Database::fetch_array($res, 'ASSOC');
668
669
            // Sending announcement
670
            if (!empty($sentTo)) {
671
                $id = AnnouncementManager::add_announcement(
672
                    api_get_course_info(),
673
                    api_get_session_id(),
674
                    $row['title'],
675
                    $row['content'],
676
                    $sentTo,
677
                    null,
678
                    null,
679
                    $row['end_date']
680
                );
681
682
                AnnouncementManager::sendEmail(
683
                    api_get_course_info(),
684
                    api_get_session_id(),
685
                    $id
686
                );
687
688
                return $id;
689
            }
690
        }
691
692
        return -1;
693
    }
694
695
    /**
696
     * Edits an event.
697
     *
698
     * @param int    $id
699
     * @param string $start                 datetime format: 2012-06-14 09:00:00
700
     * @param string $end                   datetime format: 2012-06-14 09:00:00
701
     * @param int    $allDay                is all day 'true' or 'false'
702
     * @param string $title
703
     * @param string $content
704
     * @param array  $usersToSend
705
     * @param array  $attachmentArray
706
     * @param array  $attachmentCommentList
707
     * @param string $comment
708
     * @param string $color
709
     * @param bool   $addAnnouncement
710
     * @param bool   $updateContent
711
     * @param int    $authorId
712
     *
713
     * @return bool
714
     */
715
    public function editEvent(
716
        $id,
717
        $start,
718
        $end,
719
        $allDay,
720
        $title,
721
        $content,
722
        $usersToSend = [],
723
        $attachmentArray = [],
724
        $attachmentCommentList = [],
725
        $comment = null,
726
        $color = '',
727
        $addAnnouncement = false,
728
        $updateContent = true,
729
        $authorId = 0
730
    ) {
731
        $start = api_get_utc_datetime($start);
732
        $end = api_get_utc_datetime($end);
733
        $allDay = isset($allDay) && $allDay == 'true' ? 1 : 0;
734
        $authorId = empty($authorId) ? api_get_user_id() : (int) $authorId;
735
736
        switch ($this->type) {
737
            case 'personal':
738
                $eventInfo = $this->get_event($id);
739
                if ($eventInfo['user'] != api_get_user_id()) {
740
                    break;
741
                }
742
                $attributes = [
743
                    'title' => $title,
744
                    'date' => $start,
745
                    'enddate' => $end,
746
                    'all_day' => $allDay,
747
                ];
748
749
                if ($updateContent) {
750
                    $attributes['text'] = $content;
751
                }
752
753
                if (!empty($color)) {
754
                    $attributes['color'] = $color;
755
                }
756
757
                Database::update(
758
                    $this->tbl_personal_agenda,
759
                    $attributes,
760
                    ['id = ?' => $id]
761
                );
762
                break;
763
            case 'course':
764
                $eventInfo = $this->get_event($id);
765
766
                if (empty($eventInfo)) {
767
                    return false;
768
                }
769
770
                $groupId = api_get_group_id();
771
                $groupIid = 0;
772
                $groupInfo = [];
773
                if ($groupId) {
774
                    $groupInfo = GroupManager::get_group_properties($groupId);
775
                    if ($groupInfo) {
776
                        $groupIid = $groupInfo['iid'];
777
                    }
778
                }
779
780
                $courseId = $this->course['real_id'];
781
782
                if (empty($courseId)) {
783
                    return false;
784
                }
785
786
                if ($this->getIsAllowedToEdit()) {
787
                    $attributes = [
788
                        'title' => $title,
789
                        'start_date' => $start,
790
                        'end_date' => $end,
791
                        'all_day' => $allDay,
792
                        'comment' => $comment,
793
                    ];
794
795
                    if ($updateContent) {
796
                        $attributes['content'] = $content;
797
                    }
798
799
                    if (!empty($color)) {
800
                        $attributes['color'] = $color;
801
                    }
802
803
                    Database::update(
804
                        $this->tbl_course_agenda,
805
                        $attributes,
806
                        [
807
                            'id = ? AND c_id = ? AND session_id = ? ' => [
808
                                $id,
809
                                $courseId,
810
                                $this->sessionId,
811
                            ],
812
                        ]
813
                    );
814
815
                    if (!empty($usersToSend)) {
816
                        $sendTo = $this->parseSendToArray($usersToSend);
817
818
                        $usersToDelete = array_diff(
819
                            $eventInfo['send_to']['users'],
820
                            $sendTo['users']
821
                        );
822
                        $usersToAdd = array_diff(
823
                            $sendTo['users'],
824
                            $eventInfo['send_to']['users']
825
                        );
826
827
                        $groupsToDelete = array_diff(
828
                            $eventInfo['send_to']['groups'],
829
                            $sendTo['groups']
830
                        );
831
                        $groupToAdd = array_diff(
832
                            $sendTo['groups'],
833
                            $eventInfo['send_to']['groups']
834
                        );
835
836
                        if ($sendTo['everyone']) {
837
                            // Delete all from group
838
                            if (isset($eventInfo['send_to']['groups']) &&
839
                                !empty($eventInfo['send_to']['groups'])
840
                            ) {
841
                                foreach ($eventInfo['send_to']['groups'] as $group) {
842
                                    $groupIidItem = 0;
843
                                    if ($group) {
844
                                        $groupInfoItem = GroupManager::get_group_properties(
845
                                            $group
846
                                        );
847
                                        if ($groupInfoItem) {
848
                                            $groupIidItem = $groupInfoItem['iid'];
849
                                        }
850
                                    }
851
852
                                    api_item_property_delete(
853
                                        $this->course,
854
                                        TOOL_CALENDAR_EVENT,
855
                                        $id,
856
                                        0,
857
                                        $groupIidItem,
858
                                        $this->sessionId
859
                                    );
860
                                }
861
                            }
862
863
                            // Storing the selected users.
864
                            if (isset($eventInfo['send_to']['users']) &&
865
                                !empty($eventInfo['send_to']['users'])
866
                            ) {
867
                                foreach ($eventInfo['send_to']['users'] as $userId) {
868
                                    api_item_property_delete(
869
                                        $this->course,
870
                                        TOOL_CALENDAR_EVENT,
871
                                        $id,
872
                                        $userId,
873
                                        $groupIid,
874
                                        $this->sessionId
875
                                    );
876
                                }
877
                            }
878
879
                            // Add to everyone only.
880
                            api_item_property_update(
881
                                $this->course,
882
                                TOOL_CALENDAR_EVENT,
883
                                $id,
884
                                'visible',
885
                                $authorId,
886
                                $groupInfo,
887
                                null,
888
                                $start,
889
                                $end,
890
                                $this->sessionId
891
                            );
892
                        } else {
893
                            // Delete "everyone".
894
                            api_item_property_delete(
895
                                $this->course,
896
                                TOOL_CALENDAR_EVENT,
897
                                $id,
898
                                0,
899
                                0,
900
                                $this->sessionId
901
                            );
902
903
                            // Add groups
904
                            if (!empty($groupToAdd)) {
905
                                foreach ($groupToAdd as $group) {
906
                                    $groupInfoItem = [];
907
                                    if ($group) {
908
                                        $groupInfoItem = GroupManager::get_group_properties(
909
                                            $group
910
                                        );
911
                                    }
912
913
                                    api_item_property_update(
914
                                        $this->course,
915
                                        TOOL_CALENDAR_EVENT,
916
                                        $id,
917
                                        'visible',
918
                                        $authorId,
919
                                        $groupInfoItem,
920
                                        0,
921
                                        $start,
922
                                        $end,
923
                                        $this->sessionId
924
                                    );
925
                                }
926
                            }
927
928
                            // Delete groups.
929
                            if (!empty($groupsToDelete)) {
930
                                foreach ($groupsToDelete as $group) {
931
                                    $groupIidItem = 0;
932
                                    $groupInfoItem = [];
933
                                    if ($group) {
934
                                        $groupInfoItem = GroupManager::get_group_properties(
935
                                            $group
936
                                        );
937
                                        if ($groupInfoItem) {
938
                                            $groupIidItem = $groupInfoItem['iid'];
939
                                        }
940
                                    }
941
942
                                    api_item_property_delete(
943
                                        $this->course,
944
                                        TOOL_CALENDAR_EVENT,
945
                                        $id,
946
                                        0,
947
                                        $groupIidItem,
948
                                        $this->sessionId
949
                                    );
950
                                }
951
                            }
952
953
                            // Add users.
954
                            if (!empty($usersToAdd)) {
955
                                foreach ($usersToAdd as $userId) {
956
                                    api_item_property_update(
957
                                        $this->course,
958
                                        TOOL_CALENDAR_EVENT,
959
                                        $id,
960
                                        'visible',
961
                                        $authorId,
962
                                        $groupInfo,
963
                                        $userId,
964
                                        $start,
965
                                        $end,
966
                                        $this->sessionId
967
                                    );
968
                                }
969
                            }
970
971
                            // Delete users.
972
                            if (!empty($usersToDelete)) {
973
                                foreach ($usersToDelete as $userId) {
974
                                    api_item_property_delete(
975
                                        $this->course,
976
                                        TOOL_CALENDAR_EVENT,
977
                                        $id,
978
                                        $userId,
979
                                        $groupInfo,
980
                                        $this->sessionId
981
                                    );
982
                                }
983
                            }
984
                        }
985
                    }
986
987
                    // Add announcement.
988
                    if (isset($addAnnouncement) && !empty($addAnnouncement)) {
989
                        $this->storeAgendaEventAsAnnouncement(
990
                            $id,
991
                            $usersToSend
992
                        );
993
                    }
994
995
                    // Add attachment.
996
                    if (isset($attachmentArray) && !empty($attachmentArray)) {
997
                        $counter = 0;
998
                        foreach ($attachmentArray as $attachmentItem) {
999
                            $this->updateAttachment(
1000
                                $attachmentItem['id'],
1001
                                $id,
1002
                                $attachmentItem,
1003
                                $attachmentCommentList[$counter],
1004
                                $this->course
1005
                            );
1006
                            $counter++;
1007
                        }
1008
                    }
1009
1010
                    return true;
1011
                } else {
1012
                    return false;
1013
                }
1014
                break;
1015
            case 'admin':
1016
            case 'platform':
1017
                if (api_is_platform_admin()) {
1018
                    $attributes = [
1019
                        'title' => $title,
1020
                        'start_date' => $start,
1021
                        'end_date' => $end,
1022
                        'all_day' => $allDay,
1023
                    ];
1024
1025
                    if ($updateContent) {
1026
                        $attributes['content'] = $content;
1027
                    }
1028
                    Database::update(
1029
                        $this->tbl_global_agenda,
1030
                        $attributes,
1031
                        ['id = ?' => $id]
1032
                    );
1033
                }
1034
                break;
1035
        }
1036
    }
1037
1038
    /**
1039
     * @param int  $id
1040
     * @param bool $deleteAllItemsFromSerie
1041
     */
1042
    public function deleteEvent($id, $deleteAllItemsFromSerie = false)
1043
    {
1044
        switch ($this->type) {
1045
            case 'personal':
1046
                $eventInfo = $this->get_event($id);
1047
                if ($eventInfo['user'] == api_get_user_id()) {
1048
                    Database::delete(
1049
                        $this->tbl_personal_agenda,
1050
                        ['id = ?' => $id]
1051
                    );
1052
                }
1053
                break;
1054
            case 'course':
1055
                $courseId = api_get_course_int_id();
1056
                $sessionId = api_get_session_id();
1057
                $isAllowToEdit = api_is_allowed_to_edit(null, true);
1058
1059
                if ($isAllowToEdit == false && !empty($sessionId)) {
1060
                    $allowDhrToEdit = api_get_configuration_value('allow_agenda_edit_for_hrm');
1061
                    if ($allowDhrToEdit) {
1062
                        $isHrm = SessionManager::isUserSubscribedAsHRM(
1063
                            $sessionId,
1064
                            api_get_user_id()
1065
                        );
1066
                        if ($isHrm) {
1067
                            $isAllowToEdit = true;
1068
                        }
1069
                    }
1070
                }
1071
1072
                if (!empty($courseId) && $isAllowToEdit) {
1073
                    // Delete
1074
                    $eventInfo = $this->get_event($id);
1075
                    if ($deleteAllItemsFromSerie) {
1076
                        /* This is one of the children.
1077
                           Getting siblings and delete 'Em all + the father! */
1078
                        if (isset($eventInfo['parent_event_id']) && !empty($eventInfo['parent_event_id'])) {
1079
                            // Removing items.
1080
                            $events = $this->getAllRepeatEvents(
1081
                                $eventInfo['parent_event_id']
1082
                            );
1083
                            if (!empty($events)) {
1084
                                foreach ($events as $event) {
1085
                                    $this->deleteEvent($event['id']);
1086
                                }
1087
                            }
1088
                            // Removing parent.
1089
                            $this->deleteEvent($eventInfo['parent_event_id']);
1090
                        } else {
1091
                            // This is the father looking for the children.
1092
                            $events = $this->getAllRepeatEvents($id);
1093
                            if (!empty($events)) {
1094
                                foreach ($events as $event) {
1095
                                    $this->deleteEvent($event['id']);
1096
                                }
1097
                            }
1098
                        }
1099
                    }
1100
1101
                    // Removing from events.
1102
                    Database::delete(
1103
                        $this->tbl_course_agenda,
1104
                        ['id = ? AND c_id = ?' => [$id, $courseId]]
1105
                    );
1106
1107
                    api_item_property_update(
1108
                        $this->course,
1109
                        TOOL_CALENDAR_EVENT,
1110
                        $id,
1111
                        'delete',
1112
                        api_get_user_id()
1113
                    );
1114
1115
                    // Removing from series.
1116
                    Database::delete(
1117
                        $this->table_repeat,
1118
                        [
1119
                            'cal_id = ? AND c_id = ?' => [
1120
                                $id,
1121
                                $courseId,
1122
                            ],
1123
                        ]
1124
                    );
1125
1126
                    if (isset($eventInfo['attachment']) && !empty($eventInfo['attachment'])) {
1127
                        foreach ($eventInfo['attachment'] as $attachment) {
1128
                            self::deleteAttachmentFile(
1129
                                $attachment['id'],
1130
                                $this->course
1131
                            );
1132
                        }
1133
                    }
1134
                }
1135
                break;
1136
            case 'admin':
1137
                if (api_is_platform_admin()) {
1138
                    Database::delete(
1139
                        $this->tbl_global_agenda,
1140
                        ['id = ?' => $id]
1141
                    );
1142
                }
1143
                break;
1144
        }
1145
    }
1146
1147
    /**
1148
     * Get agenda events.
1149
     *
1150
     * @param int    $start
1151
     * @param int    $end
1152
     * @param int    $courseId
1153
     * @param int    $groupId
1154
     * @param int    $user_id
1155
     * @param string $format
1156
     *
1157
     * @return array|string
1158
     */
1159
    public function getEvents(
1160
        $start,
1161
        $end,
1162
        $courseId = null,
1163
        $groupId = null,
1164
        $user_id = 0,
1165
        $format = 'json'
1166
    ) {
1167
        switch ($this->type) {
1168
            case 'admin':
1169
                $this->getPlatformEvents($start, $end);
1170
                break;
1171
            case 'course':
1172
                $courseInfo = api_get_course_info_by_id($courseId);
1173
1174
                // Session coach can see all events inside a session.
1175
                if (api_is_coach()) {
1176
                    // Own course
1177
                    $this->getCourseEvents(
1178
                        $start,
1179
                        $end,
1180
                        $courseInfo,
1181
                        $groupId,
1182
                        $this->sessionId,
1183
                        $user_id
1184
                    );
1185
1186
                    // Others
1187
                    $this->getSessionEvents(
1188
                        $start,
1189
                        $end,
1190
                        $this->sessionId,
1191
                        $user_id,
1192
                        $this->eventOtherSessionColor
1193
                    );
1194
                } else {
1195
                    $this->getCourseEvents(
1196
                        $start,
1197
                        $end,
1198
                        $courseInfo,
1199
                        $groupId,
1200
                        $this->sessionId,
1201
                        $user_id
1202
                    );
1203
                }
1204
                break;
1205
            case 'personal':
1206
            default:
1207
                $sessionFilterActive = false;
1208
                if (!empty($this->sessionId)) {
1209
                    $sessionFilterActive = true;
1210
                }
1211
1212
                if ($sessionFilterActive == false) {
1213
                    // Getting personal events
1214
                    $this->getPersonalEvents($start, $end);
1215
1216
                    // Getting platform/admin events
1217
                    $this->getPlatformEvents($start, $end);
1218
                }
1219
1220
                $ignoreVisibility = api_get_configuration_value('personal_agenda_show_all_session_events');
1221
1222
                // Getting course events
1223
                $my_course_list = [];
1224
                if (!api_is_anonymous()) {
1225
                    $session_list = SessionManager::get_sessions_by_user(
1226
                        api_get_user_id(),
1227
                        $ignoreVisibility
1228
                    );
1229
                    $my_course_list = CourseManager::get_courses_list_by_user_id(
1230
                        api_get_user_id(),
1231
                        false
1232
                    );
1233
                }
1234
1235
                if (api_is_drh()) {
1236
                    if (api_drh_can_access_all_session_content()) {
1237
                        $session_list = [];
1238
                        $sessionList = SessionManager::get_sessions_followed_by_drh(
1239
                            api_get_user_id(),
1240
                            null,
1241
                            null,
1242
                            null,
1243
                            true,
1244
                            false
1245
                        );
1246
1247
                        if (!empty($sessionList)) {
1248
                            foreach ($sessionList as $sessionItem) {
1249
                                $sessionId = $sessionItem['id'];
1250
                                $courses = SessionManager::get_course_list_by_session_id(
1251
                                    $sessionId
1252
                                );
1253
                                $sessionInfo = [
1254
                                    'session_id' => $sessionId,
1255
                                    'courses' => $courses,
1256
                                ];
1257
                                $session_list[] = $sessionInfo;
1258
                            }
1259
                        }
1260
                    }
1261
                }
1262
1263
                if (!empty($session_list)) {
1264
                    foreach ($session_list as $session_item) {
1265
                        if ($sessionFilterActive) {
1266
                            if ($this->sessionId != $session_item['session_id']) {
1267
                                continue;
1268
                            }
1269
                        }
1270
1271
                        $my_courses = $session_item['courses'];
1272
                        $my_session_id = $session_item['session_id'];
1273
1274
                        if (!empty($my_courses)) {
1275
                            foreach ($my_courses as $course_item) {
1276
                                $courseInfo = api_get_course_info_by_id(
1277
                                    $course_item['real_id']
1278
                                );
1279
                                $this->getCourseEvents(
1280
                                    $start,
1281
                                    $end,
1282
                                    $courseInfo,
1283
                                    0,
1284
                                    $my_session_id
1285
                                );
1286
                            }
1287
                        }
1288
                    }
1289
                }
1290
1291
                if (!empty($my_course_list) && $sessionFilterActive == false) {
1292
                    foreach ($my_course_list as $courseInfoItem) {
1293
                        $courseInfo = api_get_course_info_by_id(
1294
                            $courseInfoItem['real_id']
1295
                        );
1296
                        if (isset($courseId) && !empty($courseId)) {
1297
                            if ($courseInfo['real_id'] == $courseId) {
1298
                                $this->getCourseEvents(
1299
                                    $start,
1300
                                    $end,
1301
                                    $courseInfo,
1302
                                    0,
1303
                                    0,
1304
                                    $user_id
1305
                                );
1306
                            }
1307
                        } else {
1308
                            $this->getCourseEvents(
1309
                                $start,
1310
                                $end,
1311
                                $courseInfo,
1312
                                0,
1313
                                0,
1314
                                $user_id
1315
                            );
1316
                        }
1317
                    }
1318
                }
1319
                break;
1320
        }
1321
1322
        $this->cleanEvents();
1323
1324
        switch ($format) {
1325
            case 'json':
1326
                if (empty($this->events)) {
1327
                    return '[]';
1328
                }
1329
1330
                return json_encode($this->events);
1331
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

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