Passed
Push — master ( d0b226...f5358a )
by Julito
10:41
created

Agenda::editEvent()   F

Complexity

Conditions 46
Paths 8216

Size

Total Lines 320
Code Lines 198

Duplication

Lines 0
Ratio 0 %

Importance

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