Completed
Push — master ( b5a1ce...792ce7 )
by Yannick
17:49 queued 11s
created

Agenda::get_personal_agenda_items()   B

Complexity

Conditions 9

Size

Total Lines 102
Code Lines 57

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 57
c 0
b 0
f 0
nop 7
dl 0
loc 102
rs 7.3826

How to fix   Long Method   

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:

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('Login: %s'),
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('Add event to agenda');
2356
        if (!empty($id)) {
2357
            $form_Title = get_lang('Edit event');
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('Editing this event will remove it from the serie of events it is currently part of'),
2388
                    'warning'
2389
                )
2390
            );
2391
        }
2392
2393
        $form->addElement('text', 'title', get_lang('Event name'));
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('Date range'),
2412
            false,
2413
            ['id' => 'date_range']
2414
        );
2415
        $form->addElement('checkbox', 'all_day', null, get_lang('All day'));
2416
2417
        if ($this->type == 'course') {
2418
            $repeat = $form->addElement(
2419
                'checkbox',
2420
                'repeat',
2421
                null,
2422
                get_lang('Repeat event'),
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('Repeat type'),
2433
                self::getRepeatTypes()
2434
            );
2435
            $form->addElement(
2436
                'date_picker',
2437
                'repeat_end_day',
2438
                get_lang('Repeat end date'),
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('Files attachments'),
2493
                '<div id="filepaths" class="file-upload-event">
2494
                        
2495
                        <div id="filepath_1">
2496
                            <input type="file" name="attach_1"/>
2497
                            
2498
                            <label>'.get_lang('Description').'</label>
2499
                            <input class="form-control" type="text" name="legend[]" />
2500
                        </div>
2501
                        
2502
                    </div>'
2503
            );
2504
2505
            $form->addLabel(
2506
                '',
2507
                '<span id="link-more-attach">
2508
                    <a href="javascript://" onclick="return add_image_form()">'.
2509
                get_lang('Add one more file').'</a>
2510
                 </span>&nbsp;('.sprintf(
2511
                    get_lang('Maximun file size: %s'),
2512
                    format_file_size(
2513
                        api_get_setting('message_max_upload_filesize')
2514
                    )
2515
                ).')'
2516
            );
2517
2518
            if (isset($params['attachment']) && !empty($params['attachment'])) {
2519
                $attachmentList = $params['attachment'];
2520
                foreach ($attachmentList as $attachment) {
2521
                    $params['file_comment'] = $attachment['comment'];
2522
                    if (!empty($attachment['path'])) {
2523
                        $form->addElement(
2524
                            'checkbox',
2525
                            'delete_attachment['.$attachment['id'].']',
2526
                            null,
2527
                            get_lang(
2528
                                'DeleteAttachment'
2529
                            ).': '.$attachment['filename']
2530
                        );
2531
                    }
2532
                }
2533
            }
2534
2535
            $form->addElement(
2536
                'textarea',
2537
                'file_comment',
2538
                get_lang('File comment')
2539
            );
2540
        }
2541
2542
        if (empty($id)) {
2543
            $form->addElement(
2544
                'checkbox',
2545
                'add_announcement',
2546
                null,
2547
                get_lang('Add an announcement').'&nbsp('.get_lang('Send mail').')'
2548
            );
2549
        }
2550
2551
        if ($id) {
2552
            $form->addButtonUpdate(get_lang('Edit event'));
2553
        } else {
2554
            $form->addButtonSave(get_lang('Add event'));
2555
        }
2556
2557
        $form->setDefaults($params);
2558
        $form->addRule(
2559
            'date_range',
2560
            get_lang('Required field'),
2561
            'required'
2562
        );
2563
        $form->addRule('title', get_lang('Required field'), 'required');
2564
2565
        return $form;
2566
    }
2567
2568
    /**
2569
     * @param FormValidator $form
2570
     * @param array         $sendTo               array('everyone' => false, 'users' => [1, 2], 'groups' => [3, 4])
2571
     * @param array         $attributes
2572
     * @param bool          $addOnlyItemsInSendTo
2573
     * @param bool          $required
2574
     *
2575
     * @return bool
2576
     */
2577
    public function showToForm(
2578
        $form,
2579
        $sendTo = [],
2580
        $attributes = [],
2581
        $addOnlyItemsInSendTo = false,
2582
        $required = false
2583
    ) {
2584
        if ($this->type != 'course') {
2585
            return false;
2586
        }
2587
2588
        $order = 'lastname';
2589
        if (api_is_western_name_order()) {
2590
            $order = 'firstname';
2591
        }
2592
2593
        $userList = CourseManager::get_user_list_from_course_code(
2594
            api_get_course_id(),
2595
            $this->sessionId,
2596
            null,
2597
            $order
2598
        );
2599
2600
        $groupList = CourseManager::get_group_list_of_course(
2601
            api_get_course_id(),
2602
            $this->sessionId
2603
        );
2604
2605
        $this->setSendToSelect(
2606
            $form,
2607
            $groupList,
2608
            $userList,
2609
            $sendTo,
2610
            $attributes,
2611
            $addOnlyItemsInSendTo,
2612
            $required
2613
        );
2614
2615
        return true;
2616
    }
2617
2618
    /**
2619
     * @param int   $id
2620
     * @param int   $visibility 0= invisible, 1 visible
2621
     * @param array $courseInfo
2622
     * @param int   $userId
2623
     */
2624
    public static function changeVisibility(
2625
        $id,
2626
        $visibility,
2627
        $courseInfo,
2628
        $userId = null
2629
    ) {
2630
        $id = intval($id);
2631
        if (empty($userId)) {
2632
            $userId = api_get_user_id();
2633
        } else {
2634
            $userId = intval($userId);
2635
        }
2636
2637
        if ($visibility == 0) {
2638
            api_item_property_update(
2639
                $courseInfo,
2640
                TOOL_CALENDAR_EVENT,
2641
                $id,
2642
                'invisible',
2643
                $userId
2644
            );
2645
        } else {
2646
            api_item_property_update(
2647
                $courseInfo,
2648
                TOOL_CALENDAR_EVENT,
2649
                $id,
2650
                'visible',
2651
                $userId
2652
            );
2653
        }
2654
    }
2655
2656
    /**
2657
     * Get repeat types.
2658
     *
2659
     * @return array
2660
     */
2661
    public static function getRepeatTypes()
2662
    {
2663
        return [
2664
            'daily' => get_lang('Daily'),
2665
            'weekly' => get_lang('Weekly'),
2666
            'monthlyByDate' => get_lang('Monthly, by date'),
2667
            //monthlyByDay"> get_lang('Monthly, by day');
2668
            //monthlyByDayR' => get_lang('Monthly, by dayR'),
2669
            'yearly' => get_lang('Yearly'),
2670
        ];
2671
    }
2672
2673
    /**
2674
     * Show a list with all the attachments according to the post's id.
2675
     *
2676
     * @param int   $eventId
2677
     * @param array $courseInfo
2678
     *
2679
     * @return array with the post info
2680
     */
2681
    public function getAttachmentList($eventId, $courseInfo)
2682
    {
2683
        $tableAttachment = Database::get_course_table(TABLE_AGENDA_ATTACHMENT);
2684
        $courseId = (int) $courseInfo['real_id'];
2685
        $eventId = (int) $eventId;
2686
2687
        $sql = "SELECT id, path, filename, comment
2688
                FROM $tableAttachment
2689
                WHERE
2690
                    c_id = $courseId AND
2691
                    agenda_id = $eventId";
2692
        $result = Database::query($sql);
2693
        $list = [];
2694
        if (Database::num_rows($result) != 0) {
2695
            $list = Database::store_result($result, 'ASSOC');
2696
        }
2697
2698
        return $list;
2699
    }
2700
2701
    /**
2702
     * Show a list with all the attachments according to the post's id.
2703
     *
2704
     * @param int   $attachmentId
2705
     * @param int   $eventId
2706
     * @param array $courseInfo
2707
     *
2708
     * @return array with the post info
2709
     */
2710
    public function getAttachment($attachmentId, $eventId, $courseInfo)
2711
    {
2712
        if (empty($courseInfo) || empty($attachmentId) || empty($eventId)) {
2713
            return [];
2714
        }
2715
2716
        $tableAttachment = Database::get_course_table(TABLE_AGENDA_ATTACHMENT);
2717
        $courseId = (int) $courseInfo['real_id'];
2718
        $eventId = (int) $eventId;
2719
        $attachmentId = (int) $attachmentId;
2720
2721
        $row = [];
2722
        $sql = "SELECT id, path, filename, comment
2723
                FROM $tableAttachment
2724
                WHERE
2725
                    c_id = $courseId AND
2726
                    agenda_id = $eventId AND
2727
                    id = $attachmentId
2728
                ";
2729
        $result = Database::query($sql);
2730
        if (Database::num_rows($result) != 0) {
2731
            $row = Database::fetch_array($result, 'ASSOC');
2732
        }
2733
2734
        return $row;
2735
    }
2736
2737
    /**
2738
     * Add an attachment file into agenda.
2739
     *
2740
     * @param int    $eventId
2741
     * @param array  $fileUserUpload ($_FILES['user_upload'])
2742
     * @param string $comment        about file
2743
     * @param array  $courseInfo
2744
     *
2745
     * @return string
2746
     */
2747
    public function addAttachment(
2748
        $eventId,
2749
        $fileUserUpload,
2750
        $comment,
2751
        $courseInfo
2752
    ) {
2753
        $agenda_table_attachment = Database::get_course_table(TABLE_AGENDA_ATTACHMENT);
2754
        $eventId = (int) $eventId;
2755
2756
        // Storing the attachments
2757
        $upload_ok = false;
2758
        if (!empty($fileUserUpload['name'])) {
2759
            $upload_ok = process_uploaded_file($fileUserUpload);
2760
        }
2761
2762
        if (!empty($upload_ok)) {
2763
            $courseDir = $courseInfo['directory'].'/upload/calendar';
2764
            $sys_course_path = api_get_path(SYS_COURSE_PATH);
2765
            $uploadDir = $sys_course_path.$courseDir;
2766
2767
            // Try to add an extension to the file if it hasn't one
2768
            $new_file_name = add_ext_on_mime(
2769
                stripslashes($fileUserUpload['name']),
2770
                $fileUserUpload['type']
2771
            );
2772
2773
            // user's file name
2774
            $file_name = $fileUserUpload['name'];
2775
2776
            if (!filter_extension($new_file_name)) {
2777
                return Display::return_message(
2778
                    get_lang('File upload failed: this file extension or file type is prohibited'),
2779
                    'error'
2780
                );
2781
            } else {
2782
                $new_file_name = uniqid('');
2783
                $new_path = $uploadDir.'/'.$new_file_name;
2784
                $result = @move_uploaded_file(
2785
                    $fileUserUpload['tmp_name'],
2786
                    $new_path
2787
                );
2788
                $courseId = api_get_course_int_id();
2789
                $size = intval($fileUserUpload['size']);
2790
                // Storing the attachments if any
2791
                if ($result) {
2792
                    $params = [
2793
                        'c_id' => $courseId,
2794
                        'filename' => $file_name,
2795
                        'comment' => $comment,
2796
                        'path' => $new_file_name,
2797
                        'agenda_id' => $eventId,
2798
                        'size' => $size,
2799
                    ];
2800
                    $id = Database::insert($agenda_table_attachment, $params);
2801
                    if ($id) {
2802
                        $sql = "UPDATE $agenda_table_attachment
2803
                                SET id = iid WHERE iid = $id";
2804
                        Database::query($sql);
2805
2806
                        api_item_property_update(
2807
                            $courseInfo,
2808
                            'calendar_event_attachment',
2809
                            $id,
2810
                            'AgendaAttachmentAdded',
2811
                            api_get_user_id()
2812
                        );
2813
                    }
2814
                }
2815
            }
2816
        }
2817
    }
2818
2819
    /**
2820
     * @param int    $attachmentId
2821
     * @param int    $eventId
2822
     * @param array  $fileUserUpload
2823
     * @param string $comment
2824
     * @param array  $courseInfo
2825
     */
2826
    public function updateAttachment(
2827
        $attachmentId,
2828
        $eventId,
2829
        $fileUserUpload,
2830
        $comment,
2831
        $courseInfo
2832
    ) {
2833
        $attachment = $this->getAttachment(
2834
            $attachmentId,
2835
            $eventId,
2836
            $courseInfo
2837
        );
2838
        if (!empty($attachment)) {
2839
            $this->deleteAttachmentFile($attachmentId, $courseInfo);
2840
        }
2841
        $this->addAttachment($eventId, $fileUserUpload, $comment, $courseInfo);
2842
    }
2843
2844
    /**
2845
     * This function delete a attachment file by id.
2846
     *
2847
     * @param int   $attachmentId
2848
     * @param array $courseInfo
2849
     *
2850
     * @return string
2851
     */
2852
    public function deleteAttachmentFile($attachmentId, $courseInfo)
2853
    {
2854
        $table = Database::get_course_table(TABLE_AGENDA_ATTACHMENT);
2855
        $attachmentId = (int) $attachmentId;
2856
        $courseId = $courseInfo['real_id'];
2857
2858
        if (empty($courseId) || empty($attachmentId)) {
2859
            return false;
2860
        }
2861
2862
        $sql = "DELETE FROM $table
2863
                WHERE c_id = $courseId AND id = ".$attachmentId;
2864
        $result = Database::query($sql);
2865
2866
        // update item_property
2867
        api_item_property_update(
2868
            $courseInfo,
2869
            'calendar_event_attachment',
2870
            $attachmentId,
2871
            'AgendaAttachmentDeleted',
2872
            api_get_user_id()
2873
        );
2874
2875
        if (!empty($result)) {
2876
            return Display::return_message(
2877
                get_lang("The attached file has been deleted"),
2878
                'confirmation'
2879
            );
2880
        }
2881
    }
2882
2883
    /**
2884
     * @param int $eventId
2885
     *
2886
     * @return array
2887
     */
2888
    public function getAllRepeatEvents($eventId)
2889
    {
2890
        $events = [];
2891
        $eventId = (int) $eventId;
2892
2893
        switch ($this->type) {
2894
            case 'personal':
2895
                break;
2896
            case 'course':
2897
                if (!empty($this->course['real_id'])) {
2898
                    $sql = "SELECT * FROM ".$this->tbl_course_agenda."
2899
                            WHERE
2900
                                c_id = ".$this->course['real_id']." AND
2901
                                parent_event_id = ".$eventId;
2902
                    $result = Database::query($sql);
2903
                    if (Database::num_rows($result)) {
2904
                        while ($row = Database::fetch_array($result, 'ASSOC')) {
2905
                            $events[] = $row;
2906
                        }
2907
                    }
2908
                }
2909
                break;
2910
        }
2911
2912
        return $events;
2913
    }
2914
2915
    /**
2916
     * @param int $eventId
2917
     * @param int $courseId
2918
     *
2919
     * @return bool
2920
     */
2921
    public function hasChildren($eventId, $courseId)
2922
    {
2923
        $eventId = (int) $eventId;
2924
        $courseId = (int) $courseId;
2925
2926
        $sql = "SELECT count(DISTINCT(id)) as count
2927
                FROM ".$this->tbl_course_agenda."
2928
                WHERE
2929
                    c_id = $courseId AND
2930
                    parent_event_id = $eventId";
2931
        $result = Database::query($sql);
2932
        if (Database::num_rows($result)) {
2933
            $row = Database::fetch_array($result, 'ASSOC');
2934
2935
            return $row['count'] > 0;
2936
        }
2937
2938
        return false;
2939
    }
2940
2941
    /**
2942
     * @param int    $filter
2943
     * @param string $view
2944
     *
2945
     * @return string
2946
     */
2947
    public function displayActions($view, $filter = 0)
2948
    {
2949
        $groupInfo = GroupManager::get_group_properties(api_get_group_id());
2950
        $groupIid = isset($groupInfo['iid']) ? $groupInfo['iid'] : 0;
2951
2952
        $codePath = api_get_path(WEB_CODE_PATH);
2953
2954
        $currentUserId = api_get_user_id();
2955
        $cidReq = api_get_cidreq();
2956
2957
        $actionsLeft = '';
2958
        $actionsLeft .= Display::url(
2959
            Display::return_icon('calendar.png', get_lang('Calendar'), [], ICON_SIZE_MEDIUM),
2960
            $codePath."calendar/agenda_js.php?type={$this->type}&$cidReq"
2961
        );
2962
        $actionsLeft .= Display::url(
2963
            Display::return_icon('week.png', get_lang('Agenda list'), [], ICON_SIZE_MEDIUM),
2964
            $codePath."calendar/agenda_list.php?type={$this->type}&$cidReq"
2965
        );
2966
2967
        $form = '';
2968
        if (api_is_allowed_to_edit(false, true) ||
2969
            (api_get_course_setting('allow_user_edit_agenda') == '1' && !api_is_anonymous()) &&
2970
            api_is_allowed_to_session_edit(false, true)
2971
            || (
2972
                GroupManager::user_has_access($currentUserId, $groupIid, GroupManager::GROUP_TOOL_CALENDAR)
2973
                && GroupManager::is_tutor_of_group($currentUserId, $groupInfo)
2974
            )
2975
        ) {
2976
            $actionsLeft .= Display::url(
2977
                Display::return_icon('new_event.png', get_lang('Add event'), [], ICON_SIZE_MEDIUM),
2978
                $codePath."calendar/agenda.php?action=add&type={$this->type}&$cidReq"
2979
            );
2980
2981
            $actionsLeft .= Display::url(
2982
                Display::return_icon('import_calendar.png', get_lang('Outlook import'), [], ICON_SIZE_MEDIUM),
2983
                $codePath."calendar/agenda.php?action=importical&type={$this->type}&$cidReq"
2984
            );
2985
2986
            if ($this->type === 'course') {
2987
                if (!isset($_GET['action'])) {
2988
                    $form = new FormValidator(
2989
                        'form-search',
2990
                        'post',
2991
                        '',
2992
                        '',
2993
                        [],
2994
                        FormValidator::LAYOUT_INLINE
2995
                    );
2996
                    $attributes = [
2997
                        'multiple' => false,
2998
                        'id' => 'select_form_id_search',
2999
                    ];
3000
                    $selectedValues = $this->parseAgendaFilter($filter);
3001
                    $this->showToForm($form, $selectedValues, $attributes);
3002
                    $form = $form->returnForm();
3003
                }
3004
            }
3005
        }
3006
3007
        if ($this->type == 'personal' && !api_is_anonymous()) {
3008
            $actionsLeft .= Display::url(
3009
                Display::return_icon('1day.png', get_lang('Sessions plan calendar'), [], ICON_SIZE_MEDIUM),
3010
                $codePath."calendar/planification.php"
3011
            );
3012
        }
3013
3014
        if (api_is_platform_admin() ||
3015
            api_is_teacher() ||
3016
            api_is_student_boss() ||
3017
            api_is_drh() ||
3018
            api_is_session_admin() ||
3019
            api_is_coach()
3020
        ) {
3021
            if ($this->type == 'personal') {
3022
                $form = null;
3023
                if (!isset($_GET['action'])) {
3024
                    $form = new FormValidator(
3025
                        'form-search',
3026
                        'get',
3027
                        api_get_self().'?type=personal&',
3028
                        '',
3029
                        [],
3030
                        FormValidator::LAYOUT_INLINE
3031
                    );
3032
3033
                    $sessions = [];
3034
3035
                    if (api_is_drh()) {
3036
                        $sessionList = SessionManager::get_sessions_followed_by_drh($currentUserId);
3037
                        if (!empty($sessionList)) {
3038
                            foreach ($sessionList as $sessionItem) {
3039
                                $sessions[$sessionItem['id']] = strip_tags($sessionItem['name']);
3040
                            }
3041
                        }
3042
                    } else {
3043
                        $sessions = SessionManager::get_sessions_by_user($currentUserId);
3044
                        $sessions = array_column($sessions, 'session_name', 'session_id');
3045
                    }
3046
3047
                    $form->addHidden('type', 'personal');
3048
                    $sessions = ['0' => get_lang('Please select an option')] + $sessions;
3049
3050
                    $form->addSelect(
3051
                        'session_id',
3052
                        get_lang('Session'),
3053
                        $sessions,
3054
                        ['id' => 'session_id', 'onchange' => 'submit();']
3055
                    );
3056
3057
                    $form->addButtonReset(get_lang('Reset'));
3058
                    $form = $form->returnForm();
3059
                }
3060
            }
3061
        }
3062
3063
        $actionsRight = '';
3064
        if ($view == 'calendar') {
3065
            $actionsRight .= $form;
3066
        }
3067
3068
        $toolbar = Display::toolbarAction(
3069
            'toolbar-agenda',
3070
            [$actionsLeft, $actionsRight]
3071
        );
3072
3073
        return $toolbar;
3074
    }
3075
3076
    /**
3077
     * @return FormValidator
3078
     */
3079
    public function getImportCalendarForm()
3080
    {
3081
        $form = new FormValidator(
3082
            'frm_import_ical',
3083
            'post',
3084
            api_get_self().'?action=importical&type='.$this->type,
3085
            ['enctype' => 'multipart/form-data']
3086
        );
3087
        $form->addHeader(get_lang('Outlook import'));
3088
        $form->addElement('file', 'ical_import', get_lang('Outlook import'));
3089
        $form->addRule(
3090
            'ical_import',
3091
            get_lang('Required field'),
3092
            'required'
3093
        );
3094
        $form->addButtonImport(get_lang('Import'), 'ical_submit');
3095
3096
        return $form;
3097
    }
3098
3099
    /**
3100
     * @param array $courseInfo
3101
     * @param $file
3102
     *
3103
     * @return false|string
3104
     */
3105
    public function importEventFile($courseInfo, $file)
3106
    {
3107
        $charset = api_get_system_encoding();
3108
        $filepath = api_get_path(SYS_ARCHIVE_PATH).$file['name'];
3109
        $messages = [];
3110
3111
        if (!@move_uploaded_file($file['tmp_name'], $filepath)) {
3112
            error_log(
3113
                'Problem moving uploaded file: '.$file['error'].' in '.__FILE__.' line '.__LINE__
3114
            );
3115
3116
            return false;
3117
        }
3118
3119
        $data = file_get_contents($filepath);
3120
3121
        $trans = [
3122
            'DAILY' => 'daily',
3123
            'WEEKLY' => 'weekly',
3124
            'MONTHLY' => 'monthlyByDate',
3125
            'YEARLY' => 'yearly',
3126
        ];
3127
        $sentTo = ['everyone' => true];
3128
        $calendar = Sabre\VObject\Reader::read($data);
3129
        $currentTimeZone = api_get_timezone();
3130
        if (!empty($calendar->VEVENT)) {
3131
            foreach ($calendar->VEVENT as $event) {
3132
                $start = $event->DTSTART->getDateTime();
3133
                $end = $event->DTEND->getDateTime();
3134
                //Sabre\VObject\DateTimeParser::parseDateTime(string $dt, \Sabre\VObject\DateTimeZone $tz)
3135
3136
                $startDateTime = api_get_local_time(
3137
                    $start->format('Y-m-d H:i:s'),
3138
                    $currentTimeZone,
3139
                    $start->format('e')
3140
                );
3141
                $endDateTime = api_get_local_time(
3142
                    $end->format('Y-m-d H:i'),
3143
                    $currentTimeZone,
3144
                    $end->format('e')
3145
                );
3146
                $title = api_convert_encoding(
3147
                    (string) $event->summary,
3148
                    $charset,
3149
                    'UTF-8'
3150
                );
3151
                $description = api_convert_encoding(
3152
                    (string) $event->description,
3153
                    $charset,
3154
                    'UTF-8'
3155
                );
3156
3157
                $id = $this->addEvent(
3158
                    $startDateTime,
3159
                    $endDateTime,
3160
                    'false',
3161
                    $title,
3162
                    $description,
3163
                    $sentTo
3164
                );
3165
3166
                $messages[] = " $title - ".$startDateTime." - ".$endDateTime;
3167
3168
                //$attendee = (string)$event->attendee;
3169
                /** @var Sabre\VObject\Property\ICalendar\Recur $repeat */
3170
                $repeat = $event->RRULE;
3171
                if ($id && !empty($repeat)) {
3172
                    $repeat = $repeat->getParts();
3173
                    $freq = $trans[$repeat['FREQ']];
3174
3175
                    if (isset($repeat['UNTIL']) && !empty($repeat['UNTIL'])) {
3176
                        // Check if datetime or just date (strlen == 8)
3177
                        if (strlen($repeat['UNTIL']) == 8) {
3178
                            // Fix the datetime format to avoid exception in the next step
3179
                            $repeat['UNTIL'] .= 'T000000';
3180
                        }
3181
                        $until = Sabre\VObject\DateTimeParser::parseDateTime(
3182
                            $repeat['UNTIL'],
3183
                            new DateTimeZone($currentTimeZone)
3184
                        );
3185
                        $until = $until->format('Y-m-d H:i:s');
3186
                        $this->addRepeatedItem(
3187
                            $id,
3188
                            $freq,
3189
                            $until,
3190
                            $sentTo
3191
                        );
3192
                    }
3193
3194
                    if (!empty($repeat['COUNT'])) {
3195
                        /*$count = $repeat['COUNT'];
3196
                        $interval = $repeat['INTERVAL'];
3197
                        $endDate = null;
3198
                        switch($freq) {
3199
                            case 'daily':
3200
                                $start = api_strtotime($startDateTime);
3201
                                $date = new DateTime($startDateTime);
3202
                                $days = $count * $interval;
3203
                                var_dump($days);
3204
                                $date->add(new DateInterval("P".$days."D"));
3205
                                $endDate = $date->format('Y-m-d H:i');
3206
                                //$endDate = $count *
3207
                                for ($i = 0; $i < $count; $i++) {
3208
                                    $days = 86400 * 7
3209
                                }
3210
                            }
3211
                        }*/
3212
                        //$res = agenda_add_repeat_item($courseInfo, $id, $freq, $count, $attendee);
3213
                        /*$this->addRepeatedItem(
3214
                            $id,
3215
                            $freq,
3216
                            $endDate,
3217
                            $sentTo
3218
                        );*/
3219
                    }
3220
                }
3221
            }
3222
        }
3223
3224
        if (!empty($messages)) {
3225
            $messages = implode('<br /> ', $messages);
3226
        } else {
3227
            $messages = get_lang('There are no events');
3228
        }
3229
3230
        return $messages;
3231
    }
3232
3233
    /**
3234
     * Parse filter turns USER:12 to ['users' => [12])] or G:1 ['groups' => [1]].
3235
     *
3236
     * @param int $filter
3237
     *
3238
     * @return array
3239
     */
3240
    public function parseAgendaFilter($filter)
3241
    {
3242
        $everyone = false;
3243
        $groupId = null;
3244
        $userId = null;
3245
3246
        if ($filter == 'everyone') {
3247
            $everyone = true;
3248
        } else {
3249
            if (substr($filter, 0, 1) == 'G') {
3250
                $groupId = str_replace('GROUP:', '', $filter);
3251
            } else {
3252
                $userId = str_replace('USER:', '', $filter);
3253
            }
3254
        }
3255
        if (empty($userId) && empty($groupId)) {
3256
            $everyone = true;
3257
        }
3258
3259
        return [
3260
            'everyone' => $everyone,
3261
            'users' => [$userId],
3262
            'groups' => [$groupId],
3263
        ];
3264
    }
3265
3266
    /**
3267
     *    This function retrieves all the agenda items of all the courses the user is subscribed to.
3268
     */
3269
    public static function get_myagendaitems(
3270
        $user_id,
3271
        $courses_dbs,
3272
        $month,
3273
        $year
3274
    ) {
3275
        $user_id = intval($user_id);
3276
3277
        $items = [];
3278
        $my_list = [];
3279
3280
        // get agenda-items for every course
3281
        foreach ($courses_dbs as $key => $array_course_info) {
3282
            //databases of the courses
3283
            $TABLEAGENDA = Database::get_course_table(TABLE_AGENDA);
3284
            $TABLE_ITEMPROPERTY = Database::get_course_table(
3285
                TABLE_ITEM_PROPERTY
3286
            );
3287
3288
            $group_memberships = GroupManager::get_group_ids(
3289
                $array_course_info['real_id'],
3290
                $user_id
3291
            );
3292
            $course_user_status = CourseManager::getUserInCourseStatus(
3293
                $user_id,
3294
                $array_course_info['real_id']
3295
            );
3296
            // if the user is administrator of that course we show all the agenda items
3297
            if ($course_user_status == '1') {
3298
                //echo "course admin";
3299
                $sqlquery = "SELECT DISTINCT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref
3300
							FROM ".$TABLEAGENDA." agenda,
3301
								 ".$TABLE_ITEMPROPERTY." ip
3302
							WHERE agenda.id = ip.ref
3303
							AND MONTH(agenda.start_date)='".$month."'
3304
							AND YEAR(agenda.start_date)='".$year."'
3305
							AND ip.tool='".TOOL_CALENDAR_EVENT."'
3306
							AND ip.visibility='1'
3307
							GROUP BY agenda.id
3308
							ORDER BY start_date ";
3309
            } else {
3310
                // if the user is not an administrator of that course
3311
                if (is_array($group_memberships) && count(
3312
                        $group_memberships
3313
                    ) > 0
3314
                ) {
3315
                    $sqlquery = "SELECT	agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref
3316
								FROM ".$TABLEAGENDA." agenda,
3317
									".$TABLE_ITEMPROPERTY." ip
3318
								WHERE agenda.id = ip.ref
3319
								AND MONTH(agenda.start_date)='".$month."'
3320
								AND YEAR(agenda.start_date)='".$year."'
3321
								AND ip.tool='".TOOL_CALENDAR_EVENT."'
3322
								AND	( ip.to_user_id='".$user_id."' OR (ip.to_group_id IS NULL OR ip.to_group_id IN (0, ".implode(
3323
                            ", ",
3324
                            $group_memberships
3325
                        ).")) )
3326
								AND ip.visibility='1'
3327
								ORDER BY start_date ";
3328
                } else {
3329
                    $sqlquery = "SELECT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref
3330
								FROM ".$TABLEAGENDA." agenda,
3331
									".$TABLE_ITEMPROPERTY." ip
3332
								WHERE agenda.id = ip.ref
3333
								AND MONTH(agenda.start_date)='".$month."'
3334
								AND YEAR(agenda.start_date)='".$year."'
3335
								AND ip.tool='".TOOL_CALENDAR_EVENT."'
3336
								AND ( ip.to_user_id='".$user_id."' OR ip.to_group_id='0' OR ip.to_group_id IS NULL)
3337
								AND ip.visibility='1'
3338
								ORDER BY start_date ";
3339
                }
3340
            }
3341
            $result = Database::query($sqlquery);
3342
3343
            while ($item = Database::fetch_array($result, 'ASSOC')) {
3344
                $agendaday = -1;
3345
                if (!empty($item['start_date'])) {
3346
                    $item['start_date'] = api_get_local_time(
3347
                        $item['start_date']
3348
                    );
3349
                    $item['start_date_tms'] = api_strtotime(
3350
                        $item['start_date']
3351
                    );
3352
                    $agendaday = date("j", $item['start_date_tms']);
3353
                }
3354
                if (!empty($item['end_date'])) {
3355
                    $item['end_date'] = api_get_local_time($item['end_date']);
3356
                }
3357
3358
                $url = api_get_path(
3359
                        WEB_CODE_PATH
3360
                    )."calendar/agenda.php?cidReq=".urlencode(
3361
                        $array_course_info["code"]
3362
                    )."&day=$agendaday&month=$month&year=$year#$agendaday";
3363
3364
                $item['url'] = $url;
3365
                $item['course_name'] = $array_course_info['title'];
3366
                $item['calendar_type'] = 'course';
3367
                $item['course_id'] = $array_course_info['course_id'];
3368
3369
                $my_list[$agendaday][] = $item;
3370
            }
3371
        }
3372
3373
        // sorting by hour for every day
3374
        $agendaitems = [];
3375
        foreach ($items as $agendaday => $tmpitems) {
3376
            if (!isset($agendaitems[$agendaday])) {
3377
                $agendaitems[$agendaday] = '';
3378
            }
3379
            sort($tmpitems);
3380
            foreach ($tmpitems as $val) {
3381
                $agendaitems[$agendaday] .= $val;
3382
            }
3383
        }
3384
3385
        return $my_list;
3386
    }
3387
3388
    /**
3389
     * This function retrieves one personal agenda item returns it.
3390
     *
3391
     * @param    array    The array containing existing events. We add to this array.
3392
     * @param    int        Day
3393
     * @param    int        Month
3394
     * @param    int        Year (4 digits)
3395
     * @param    int        Week number
3396
     * @param    string    Type of view (month_view, week_view, day_view)
3397
     *
3398
     * @return array The results of the database query, or null if not found
3399
     */
3400
    public static function get_global_agenda_items(
3401
        $agendaitems,
3402
        $day = "",
3403
        $month = "",
3404
        $year = "",
3405
        $week = "",
3406
        $type
3407
    ) {
3408
        $tbl_global_agenda = Database::get_main_table(
3409
            TABLE_MAIN_SYSTEM_CALENDAR
3410
        );
3411
        $month = intval($month);
3412
        $year = intval($year);
3413
        $week = intval($week);
3414
        $day = intval($day);
3415
        // 1. creating the SQL statement for getting the personal agenda items in MONTH view
3416
3417
        $current_access_url_id = api_get_current_access_url_id();
3418
3419
        if ($type == "month_view" or $type == "") {
3420
            // We are in month view
3421
            $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";
3422
        }
3423
        // 2. creating the SQL statement for getting the personal agenda items in WEEK view
3424
        if ($type == "week_view") { // we are in week view
3425
            $start_end_day_of_week = self::calculate_start_end_of_week(
3426
                $week,
3427
                $year
3428
            );
3429
            $start_day = $start_end_day_of_week['start']['day'];
3430
            $start_month = $start_end_day_of_week['start']['month'];
3431
            $start_year = $start_end_day_of_week['start']['year'];
3432
            $end_day = $start_end_day_of_week['end']['day'];
3433
            $end_month = $start_end_day_of_week['end']['month'];
3434
            $end_year = $start_end_day_of_week['end']['year'];
3435
            // in sql statements you have to use year-month-day for date calculations
3436
            $start_filter = $start_year."-".$start_month."-".$start_day." 00:00:00";
3437
            $start_filter = api_get_utc_datetime($start_filter);
3438
3439
            $end_filter = $end_year."-".$end_month."-".$end_day." 23:59:59";
3440
            $end_filter = api_get_utc_datetime($end_filter);
3441
            $sql = " SELECT * FROM ".$tbl_global_agenda." WHERE start_date>='".$start_filter."' AND start_date<='".$end_filter."' AND  access_url_id = $current_access_url_id ";
3442
        }
3443
        // 3. creating the SQL statement for getting the personal agenda items in DAY view
3444
        if ($type == "day_view") { // we are in day view
3445
            // we could use mysql date() function but this is only available from 4.1 and higher
3446
            $start_filter = $year."-".$month."-".$day." 00:00:00";
3447
            $start_filter = api_get_utc_datetime($start_filter);
3448
3449
            $end_filter = $year."-".$month."-".$day." 23:59:59";
3450
            $end_filter = api_get_utc_datetime($end_filter);
3451
            $sql = " SELECT * FROM ".$tbl_global_agenda." WHERE start_date>='".$start_filter."' AND start_date<='".$end_filter."'  AND  access_url_id = $current_access_url_id";
3452
        }
3453
3454
        $result = Database::query($sql);
3455
3456
        while ($item = Database::fetch_array($result)) {
3457
            if (!empty($item['start_date'])) {
3458
                $item['start_date'] = api_get_local_time($item['start_date']);
3459
                $item['start_date_tms'] = api_strtotime($item['start_date']);
3460
            }
3461
            if (!empty($item['end_date'])) {
3462
                $item['end_date'] = api_get_local_time($item['end_date']);
3463
            }
3464
3465
            // we break the date field in the database into a date and a time part
3466
            $agenda_db_date = explode(" ", $item['start_date']);
3467
            $date = $agenda_db_date[0];
3468
            $time = $agenda_db_date[1];
3469
            // we divide the date part into a day, a month and a year
3470
            $agendadate = explode("-", $date);
3471
            $year = intval($agendadate[0]);
3472
            $month = intval($agendadate[1]);
3473
            $day = intval($agendadate[2]);
3474
            // we divide the time part into hour, minutes, seconds
3475
            $agendatime = explode(":", $time);
3476
            $hour = $agendatime[0];
3477
            $minute = $agendatime[1];
3478
            $second = $agendatime[2];
3479
3480
            if ($type == 'month_view') {
3481
                $item['calendar_type'] = 'global';
3482
                $agendaitems[$day][] = $item;
3483
                continue;
3484
            }
3485
3486
            $start_time = api_format_date(
3487
                $item['start_date'],
3488
                TIME_NO_SEC_FORMAT
3489
            );
3490
            $end_time = '';
3491
            if (!empty($item['end_date'])) {
3492
                $end_time = ' - '.api_format_date(
3493
                        $item['end_date'],
3494
                        DATE_TIME_FORMAT_LONG
3495
                    );
3496
            }
3497
3498
            // Creating the array that will be returned. If we have week or month view we have an array with the date as the key
3499
            // if we have a day_view we use a half hour as index => key 33 = 16h30
3500
            if ($type !== "day_view") {
3501
                // This is the array construction for the WEEK or MONTH view
3502
                //Display the Agenda global in the tab agenda (administrator)
3503
                $agendaitems[$day] .= "<i>$start_time $end_time</i>&nbsp;-&nbsp;";
3504
                $agendaitems[$day] .= "<b>".get_lang('Platform event')."</b>";
3505
                $agendaitems[$day] .= "<div>".$item['title']."</div><br>";
3506
            } else {
3507
                // this is the array construction for the DAY view
3508
                $halfhour = 2 * $agendatime['0'];
3509
                if ($agendatime['1'] >= '30') {
3510
                    $halfhour = $halfhour + 1;
3511
                }
3512
                if (!is_array($agendaitems[$halfhour])) {
3513
                    $content = $agendaitems[$halfhour];
3514
                }
3515
                $agendaitems[$halfhour] = $content."<div><i>$hour:$minute</i> <b>".get_lang(
3516
                        'Platform event'
3517
                    ).":  </b>".$item['title']."</div>";
3518
            }
3519
        }
3520
3521
        return $agendaitems;
3522
    }
3523
3524
    /**
3525
     * This function retrieves all the personal agenda items and add them to the agenda items found by the other
3526
     * functions.
3527
     */
3528
    public static function get_personal_agenda_items(
3529
        $user_id,
3530
        $agendaitems,
3531
        $day = "",
3532
        $month = "",
3533
        $year = "",
3534
        $week = "",
3535
        $type
3536
    ) {
3537
        $tbl_personal_agenda = Database::get_main_table(TABLE_PERSONAL_AGENDA);
3538
        $user_id = intval($user_id);
3539
3540
        // 1. creating the SQL statement for getting the personal agenda items in MONTH view
3541
        if ($type == "month_view" or $type == "") {
3542
            // we are in month view
3543
            $sql = "SELECT * FROM ".$tbl_personal_agenda." WHERE user='".$user_id."' and MONTH(date)='".$month."' AND YEAR(date) = '".$year."'  ORDER BY date ASC";
3544
        }
3545
3546
        // 2. creating the SQL statement for getting the personal agenda items in WEEK view
3547
        // we are in week view
3548
        if ($type == "week_view") {
3549
            $start_end_day_of_week = self::calculate_start_end_of_week(
3550
                $week,
3551
                $year
3552
            );
3553
            $start_day = $start_end_day_of_week['start']['day'];
3554
            $start_month = $start_end_day_of_week['start']['month'];
3555
            $start_year = $start_end_day_of_week['start']['year'];
3556
            $end_day = $start_end_day_of_week['end']['day'];
3557
            $end_month = $start_end_day_of_week['end']['month'];
3558
            $end_year = $start_end_day_of_week['end']['year'];
3559
            // in sql statements you have to use year-month-day for date calculations
3560
            $start_filter = $start_year."-".$start_month."-".$start_day." 00:00:00";
3561
            $start_filter = api_get_utc_datetime($start_filter);
3562
            $end_filter = $end_year."-".$end_month."-".$end_day." 23:59:59";
3563
            $end_filter = api_get_utc_datetime($end_filter);
3564
            $sql = " SELECT * FROM ".$tbl_personal_agenda." WHERE user='".$user_id."' AND date>='".$start_filter."' AND date<='".$end_filter."'";
3565
        }
3566
        // 3. creating the SQL statement for getting the personal agenda items in DAY view
3567
        if ($type == "day_view") {
3568
            // we are in day view
3569
            // we could use mysql date() function but this is only available from 4.1 and higher
3570
            $start_filter = $year."-".$month."-".$day." 00:00:00";
3571
            $start_filter = api_get_utc_datetime($start_filter);
3572
            $end_filter = $year."-".$month."-".$day." 23:59:59";
3573
            $end_filter = api_get_utc_datetime($end_filter);
3574
            $sql = " SELECT * FROM ".$tbl_personal_agenda." WHERE user='".$user_id."' AND date>='".$start_filter."' AND date<='".$end_filter."'";
3575
        }
3576
3577
        $result = Database::query($sql);
3578
        while ($item = Database::fetch_array($result, 'ASSOC')) {
3579
            $time_minute = api_convert_and_format_date(
3580
                $item['date'],
3581
                TIME_NO_SEC_FORMAT
3582
            );
3583
            $item['date'] = api_get_local_time($item['date']);
3584
            $item['start_date_tms'] = api_strtotime($item['date']);
3585
            $item['content'] = $item['text'];
3586
3587
            // we break the date field in the database into a date and a time part
3588
            $agenda_db_date = explode(" ", $item['date']);
3589
            $date = $agenda_db_date[0];
3590
            $time = $agenda_db_date[1];
3591
            // we divide the date part into a day, a month and a year
3592
            $agendadate = explode("-", $item['date']);
3593
            $year = intval($agendadate[0]);
3594
            $month = intval($agendadate[1]);
3595
            $day = intval($agendadate[2]);
3596
            // we divide the time part into hour, minutes, seconds
3597
            $agendatime = explode(":", $time);
3598
3599
            $hour = $agendatime[0];
3600
            $minute = $agendatime[1];
3601
            $second = $agendatime[2];
3602
3603
            if ($type == 'month_view') {
3604
                $item['calendar_type'] = 'personal';
3605
                $item['start_date'] = $item['date'];
3606
                $agendaitems[$day][] = $item;
3607
                continue;
3608
            }
3609
3610
            // Creating the array that will be returned. If we have week or month view we have an array with the date as the key
3611
            // if we have a day_view we use a half hour as index => key 33 = 16h30
3612
            if ($type !== "day_view") {
3613
                // This is the array construction for the WEEK or MONTH view
3614
3615
                //Display events in agenda
3616
                $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 />";
3617
            } else {
3618
                // this is the array construction for the DAY view
3619
                $halfhour = 2 * $agendatime['0'];
3620
                if ($agendatime['1'] >= '30') {
3621
                    $halfhour = $halfhour + 1;
3622
                }
3623
3624
                //Display events by list
3625
                $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>";
3626
            }
3627
        }
3628
3629
        return $agendaitems;
3630
    }
3631
3632
    /**
3633
     * Show the monthcalender of the given month.
3634
     *
3635
     * @param    array    Agendaitems
3636
     * @param    int    Month number
3637
     * @param    int    Year number
3638
     * @param    array    Array of strings containing long week day names (deprecated, you can send an empty array
3639
     *                          instead)
3640
     * @param    string    The month name
3641
     */
3642
    public static function display_mymonthcalendar(
3643
        $user_id,
3644
        $agendaitems,
3645
        $month,
3646
        $year,
3647
        $weekdaynames = [],
3648
        $monthName,
3649
        $show_content = true
3650
    ) {
3651
        global $DaysShort, $course_path;
3652
        //Handle leap year
3653
        $numberofdays = [
3654
            0,
3655
            31,
3656
            28,
3657
            31,
3658
            30,
3659
            31,
3660
            30,
3661
            31,
3662
            31,
3663
            30,
3664
            31,
3665
            30,
3666
            31,
3667
        ];
3668
        if (($year % 400 == 0) or ($year % 4 == 0 and $year % 100 != 0)) {
3669
            $numberofdays[2] = 29;
3670
        }
3671
        //Get the first day of the month
3672
        $dayone = getdate(mktime(0, 0, 0, $month, 1, $year));
3673
        //Start the week on monday
3674
        $startdayofweek = $dayone['wday'] != 0 ? ($dayone['wday'] - 1) : 6;
3675
        $g_cc = (isset($_GET['courseCode']) ? $_GET['courseCode'] : '');
3676
3677
        $next_month = ($month == 1 ? 12 : $month - 1);
3678
        $prev_month = ($month == 12 ? 1 : $month + 1);
3679
3680
        $next_year = ($month == 1 ? $year - 1 : $year);
3681
        $prev_year = ($month == 12 ? $year + 1 : $year);
3682
3683
        if ($show_content) {
3684
            $back_url = Display::url(
3685
                get_lang('Previous'),
3686
                api_get_self()."?coursePath=".urlencode(
3687
                    $course_path
3688
                )."&courseCode=".Security::remove_XSS(
3689
                    $g_cc
3690
                )."&action=view&view=month&month=".$next_month."&year=".$next_year
3691
            );
3692
            $next_url = Display::url(
3693
                get_lang('Next'),
3694
                api_get_self()."?coursePath=".urlencode(
3695
                    $course_path
3696
                )."&courseCode=".Security::remove_XSS(
3697
                    $g_cc
3698
                )."&action=view&view=month&month=".$prev_month."&year=".$prev_year
3699
            );
3700
        } else {
3701
            $back_url = Display::url(
3702
                get_lang('Previous'),
3703
                '',
3704
                [
3705
                    'onclick' => "load_calendar('".$user_id."','".$next_month."', '".$next_year."'); ",
3706
                    'class' => 'btn ui-button ui-widget ui-state-default',
3707
                ]
3708
            );
3709
            $next_url = Display::url(
3710
                get_lang('Next'),
3711
                '',
3712
                [
3713
                    'onclick' => "load_calendar('".$user_id."','".$prev_month."', '".$prev_year."'); ",
3714
                    'class' => 'pull-right btn ui-button ui-widget ui-state-default',
3715
                ]
3716
            );
3717
        }
3718
        $html = '';
3719
        $html .= '<div class="actions">';
3720
        $html .= '<div class="row">';
3721
        $html .= '<div class="col-md-4">'.$back_url.'</div>';
3722
        $html .= '<div class="col-md-4"><p class="agenda-title text-center">'.$monthName." ".$year.'</p></div>';
3723
        $html .= '<div class="col-md-4">'.$next_url.'</div>';
3724
        $html .= '</div>';
3725
        $html .= '</div>';
3726
        $html .= '<table id="agenda_list2" class="table table-bordered">';
3727
        $html .= '<tr>';
3728
        for ($ii = 1; $ii < 8; $ii++) {
3729
            $html .= '<td class="weekdays">'.$DaysShort[$ii % 7].'</td>';
3730
        }
3731
        $html .= '</tr>';
3732
3733
        $curday = -1;
3734
        $today = getdate();
3735
        while ($curday <= $numberofdays[$month]) {
3736
            $html .= "<tr>";
3737
            for ($ii = 0; $ii < 7; $ii++) {
3738
                if (($curday == -1) && ($ii == $startdayofweek)) {
3739
                    $curday = 1;
3740
                }
3741
                if (($curday > 0) && ($curday <= $numberofdays[$month])) {
3742
                    $bgcolor = $class = 'class="days_week"';
3743
                    $dayheader = Display::div(
3744
                        $curday,
3745
                        ['class' => 'agenda_day']
3746
                    );
3747
                    if (($curday == $today['mday']) && ($year == $today['year']) && ($month == $today['mon'])) {
3748
                        $class = "class=\"days_today\" style=\"width:10%;\"";
3749
                    }
3750
3751
                    $html .= "<td ".$class.">".$dayheader;
3752
3753
                    if (!empty($agendaitems[$curday])) {
3754
                        $items = $agendaitems[$curday];
3755
                        $items = msort($items, 'start_date_tms');
3756
3757
                        foreach ($items as $value) {
3758
                            $value['title'] = Security::remove_XSS(
3759
                                $value['title']
3760
                            );
3761
                            $start_time = api_format_date(
3762
                                $value['start_date'],
3763
                                TIME_NO_SEC_FORMAT
3764
                            );
3765
                            $end_time = '';
3766
3767
                            if (!empty($value['end_date'])) {
3768
                                $end_time = '-&nbsp;<i>'.api_format_date(
3769
                                        $value['end_date'],
3770
                                        DATE_TIME_FORMAT_LONG
3771
                                    ).'</i>';
3772
                            }
3773
                            $complete_time = '<i>'.api_format_date(
3774
                                    $value['start_date'],
3775
                                    DATE_TIME_FORMAT_LONG
3776
                                ).'</i>&nbsp;'.$end_time;
3777
                            $time = '<i>'.$start_time.'</i>';
3778
3779
                            switch ($value['calendar_type']) {
3780
                                case 'personal':
3781
                                    $bg_color = '#D0E7F4';
3782
                                    $icon = Display::return_icon(
3783
                                        'user.png',
3784
                                        get_lang('Personal agenda'),
3785
                                        [],
3786
                                        ICON_SIZE_SMALL
3787
                                    );
3788
                                    break;
3789
                                case 'global':
3790
                                    $bg_color = '#FFBC89';
3791
                                    $icon = Display::return_icon(
3792
                                        'view_remove.png',
3793
                                        get_lang('Platform event'),
3794
                                        [],
3795
                                        ICON_SIZE_SMALL
3796
                                    );
3797
                                    break;
3798
                                case 'course':
3799
                                    $bg_color = '#CAFFAA';
3800
                                    $icon_name = 'course.png';
3801
                                    if (!empty($value['session_id'])) {
3802
                                        $icon_name = 'session.png';
3803
                                    }
3804
                                    if ($show_content) {
3805
                                        $icon = Display::url(
3806
                                            Display::return_icon(
3807
                                                $icon_name,
3808
                                                $value['course_name'].' '.get_lang(
3809
                                                    'Course'
3810
                                                ),
3811
                                                [],
3812
                                                ICON_SIZE_SMALL
3813
                                            ),
3814
                                            $value['url']
3815
                                        );
3816
                                    } else {
3817
                                        $icon = Display::return_icon(
3818
                                            $icon_name,
3819
                                            $value['course_name'].' '.get_lang(
3820
                                                'Course'
3821
                                            ),
3822
                                            [],
3823
                                            ICON_SIZE_SMALL
3824
                                        );
3825
                                    }
3826
                                    break;
3827
                                default:
3828
                                    break;
3829
                            }
3830
3831
                            $result = '<div class="rounded_div_agenda" style="background-color:'.$bg_color.';">';
3832
3833
                            if ($show_content) {
3834
                                //Setting a personal event to green
3835
                                $icon = Display::div(
3836
                                    $icon,
3837
                                    ['style' => 'float:right']
3838
                                );
3839
3840
                                $link = $value['calendar_type'].'_'.$value['id'].'_'.$value['course_id'].'_'.$value['session_id'];
3841
3842
                                //Link to bubble
3843
                                $url = Display::url(
3844
                                    cut($value['title'], 40),
3845
                                    '#',
3846
                                    ['id' => $link, 'class' => 'opener']
3847
                                );
3848
                                $result .= $time.' '.$icon.' '.Display::div(
3849
                                        $url
3850
                                    );
3851
3852
                                //Hidden content
3853
                                $content = Display::div(
3854
                                    $icon.Display::tag(
3855
                                        'h2',
3856
                                        $value['course_name']
3857
                                    ).'<hr />'.Display::tag(
3858
                                        'h3',
3859
                                        $value['title']
3860
                                    ).$complete_time.'<hr />'.Security::remove_XSS(
3861
                                        $value['content']
3862
                                    )
3863
                                );
3864
3865
                                //Main div
3866
                                $result .= Display::div(
3867
                                    $content,
3868
                                    [
3869
                                        'id' => 'main_'.$link,
3870
                                        'class' => 'dialog',
3871
                                        'style' => 'display:none',
3872
                                    ]
3873
                                );
3874
                                $result .= '</div>';
3875
                                $html .= $result;
3876
                            } else {
3877
                                $html .= $result .= $icon.'</div>';
3878
                            }
3879
                        }
3880
                    }
3881
                    $html .= "</td>";
3882
                    $curday++;
3883
                } else {
3884
                    $html .= "<td></td>";
3885
                }
3886
            }
3887
            $html .= "</tr>";
3888
        }
3889
        $html .= "</table>";
3890
        echo $html;
3891
    }
3892
3893
    /**
3894
     * Get personal agenda items between two dates (=all events from all registered courses).
3895
     *
3896
     * @param int $user_id user ID of the user
3897
     * @param    string    Optional start date in datetime format (if no start date is given, uses today)
3898
     * @param    string    Optional end date in datetime format (if no date is given, uses one year from now)
3899
     *
3900
     * @return array array of events ordered by start date, in
3901
     *               [0]('datestart','dateend','title'),[1]('datestart','dateend','title','link','coursetitle') format,
3902
     *               where datestart and dateend are in yyyyMMddhhmmss format
3903
     *
3904
     * @deprecated use agenda events
3905
     */
3906
    public static function get_personal_agenda_items_between_dates(
3907
        $user_id,
3908
        $date_start = '',
3909
        $date_end = ''
3910
    ) {
3911
        $items = [];
3912
        if ($user_id != strval(intval($user_id))) {
3913
            return $items;
3914
        }
3915
        if (empty($date_start)) {
3916
            $date_start = date('Y-m-d H:i:s');
3917
        }
3918
        if (empty($date_end)) {
3919
            $date_end = date(
3920
                'Y-m-d H:i:s',
3921
                mktime(0, 0, 0, date("m"), date("d"), date("Y") + 1)
3922
            );
3923
        }
3924
        $expr = '/\d{4}-\d{2}-\d{2}\ \d{2}:\d{2}:\d{2}/';
3925
        if (!preg_match($expr, $date_start)) {
3926
            return $items;
3927
        }
3928
        if (!preg_match($expr, $date_end)) {
3929
            return $items;
3930
        }
3931
3932
        // get agenda-items for every course
3933
        $courses = api_get_user_courses($user_id, false);
3934
        foreach ($courses as $id => $course) {
3935
            $c = api_get_course_info_by_id($course['real_id']);
3936
            //databases of the courses
3937
            $t_a = Database::get_course_table(TABLE_AGENDA, $course['db']);
3938
            $t_ip = Database::get_course_table(
3939
                TABLE_ITEM_PROPERTY,
3940
                $course['db']
3941
            );
3942
            // get the groups to which the user belong
3943
            $group_memberships = GroupManager:: get_group_ids(
3944
                $course['db'],
3945
                $user_id
3946
            );
3947
            // if the user is administrator of that course we show all the agenda items
3948
            if ($course['status'] == '1') {
3949
                //echo "course admin";
3950
                $sqlquery = "SELECT ".
3951
                    " DISTINCT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref ".
3952
                    " FROM ".$t_a." agenda, ".
3953
                    $t_ip." ip ".
3954
                    " WHERE agenda.id = ip.ref ".
3955
                    " AND agenda.start_date>='$date_start' ".
3956
                    " AND agenda.end_date<='$date_end' ".
3957
                    " AND ip.tool='".TOOL_CALENDAR_EVENT."' ".
3958
                    " AND ip.visibility='1' ".
3959
                    " GROUP BY agenda.id ".
3960
                    " ORDER BY start_date ";
3961
            } else {
3962
                // if the user is not an administrator of that course, then...
3963
                if (is_array($group_memberships) && count(
3964
                        $group_memberships
3965
                    ) > 0
3966
                ) {
3967
                    $sqlquery = "SELECT ".
3968
                        "DISTINCT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref ".
3969
                        " FROM ".$t_a." agenda, ".
3970
                        $t_ip." ip ".
3971
                        " WHERE agenda.id = ip.ref ".
3972
                        " AND agenda.start_date>='$date_start' ".
3973
                        " AND agenda.end_date<='$date_end' ".
3974
                        " AND ip.tool='".TOOL_CALENDAR_EVENT."' ".
3975
                        " AND	( ip.to_user_id='".$user_id."' OR (ip.to_group_id IS NULL OR ip.to_group_id IN (0, ".implode(
3976
                            ", ",
3977
                            $group_memberships
3978
                        ).")) ) ".
3979
                        " AND ip.visibility='1' ".
3980
                        " ORDER BY start_date ";
3981
                } else {
3982
                    $sqlquery = "SELECT ".
3983
                        "DISTINCT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref ".
3984
                        " FROM ".$t_a." agenda, ".
3985
                        $t_ip." ip ".
3986
                        " WHERE agenda.id = ip.ref ".
3987
                        " AND agenda.start_date>='$date_start' ".
3988
                        " AND agenda.end_date<='$date_end' ".
3989
                        " AND ip.tool='".TOOL_CALENDAR_EVENT."' ".
3990
                        " AND ( ip.to_user_id='".$user_id."' OR ip.to_group_id='0' OR ip.to_group_id IS NULL) ".
3991
                        " AND ip.visibility='1' ".
3992
                        " ORDER BY start_date ";
3993
                }
3994
            }
3995
3996
            $result = Database::query($sqlquery);
3997
            while ($item = Database::fetch_array($result)) {
3998
                $agendaday = date("j", strtotime($item['start_date']));
3999
                $month = date("n", strtotime($item['start_date']));
4000
                $year = date("Y", strtotime($item['start_date']));
4001
                $URL = api_get_path(
4002
                        WEB_PATH
4003
                    )."main/calendar/agenda.php?cidReq=".urlencode(
4004
                        $course["code"]
4005
                    )."&day=$agendaday&month=$month&year=$year#$agendaday";
4006
                list($year, $month, $day, $hour, $min, $sec) = explode(
4007
                    '[-: ]',
4008
                    $item['start_date']
4009
                );
4010
                $start_date = $year.$month.$day.$hour.$min;
4011
                list($year, $month, $day, $hour, $min, $sec) = explode(
4012
                    '[-: ]',
4013
                    $item['end_date']
4014
                );
4015
                $end_date = $year.$month.$day.$hour.$min;
4016
4017
                $items[] = [
4018
                    'datestart' => $start_date,
4019
                    'dateend' => $end_date,
4020
                    'title' => $item['title'],
4021
                    'link' => $URL,
4022
                    'coursetitle' => $c['name'],
4023
                ];
4024
            }
4025
        }
4026
4027
        return $items;
4028
    }
4029
4030
    /**
4031
     * This function calculates the startdate of the week (monday)
4032
     * and the enddate of the week (sunday)
4033
     * and returns it as an array.
4034
     */
4035
    public static function calculate_start_end_of_week($week_number, $year)
4036
    {
4037
        // determine the start and end date
4038
        // step 1: we calculate a timestamp for a day in this week
4039
        $random_day_in_week = mktime(
4040
                0,
4041
                0,
4042
                0,
4043
                1,
4044
                1,
4045
                $year
4046
            ) + ($week_number) * (7 * 24 * 60 * 60); // we calculate a random day in this week
4047
        // step 2: we which day this is (0=sunday, 1=monday, ...)
4048
        $number_day_in_week = date('w', $random_day_in_week);
4049
        // step 3: we calculate the timestamp of the monday of the week we are in
4050
        $start_timestamp = $random_day_in_week - (($number_day_in_week - 1) * 24 * 60 * 60);
4051
        // step 4: we calculate the timestamp of the sunday of the week we are in
4052
        $end_timestamp = $random_day_in_week + ((7 - $number_day_in_week + 1) * 24 * 60 * 60) - 3600;
4053
        // step 5: calculating the start_day, end_day, start_month, end_month, start_year, end_year
4054
        $start_day = date('j', $start_timestamp);
4055
        $start_month = date('n', $start_timestamp);
4056
        $start_year = date('Y', $start_timestamp);
4057
        $end_day = date('j', $end_timestamp);
4058
        $end_month = date('n', $end_timestamp);
4059
        $end_year = date('Y', $end_timestamp);
4060
        $start_end_array['start']['day'] = $start_day;
4061
        $start_end_array['start']['month'] = $start_month;
4062
        $start_end_array['start']['year'] = $start_year;
4063
        $start_end_array['end']['day'] = $end_day;
4064
        $start_end_array['end']['month'] = $end_month;
4065
        $start_end_array['end']['year'] = $end_year;
4066
4067
        return $start_end_array;
4068
    }
4069
4070
    /**
4071
     * @return bool
4072
     */
4073
    public function getIsAllowedToEdit()
4074
    {
4075
        return $this->isAllowedToEdit;
4076
    }
4077
4078
    /**
4079
     * @param bool $isAllowedToEdit
4080
     */
4081
    public function setIsAllowedToEdit($isAllowedToEdit)
4082
    {
4083
        $this->isAllowedToEdit = $isAllowedToEdit;
4084
    }
4085
4086
    /**
4087
     * Format needed for the Fullcalendar js lib.
4088
     *
4089
     * @param string $utcTime
4090
     *
4091
     * @return bool|string
4092
     */
4093
    public function formatEventDate($utcTime)
4094
    {
4095
        $utcTimeZone = new DateTimeZone('UTC');
4096
        $platformTimeZone = new DateTimeZone(api_get_timezone());
4097
4098
        $eventDate = new DateTime($utcTime, $utcTimeZone);
4099
        $eventDate->setTimezone($platformTimeZone);
4100
4101
        return $eventDate->format(DateTime::ISO8601);
4102
    }
4103
}
4104