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

Agenda::addEvent()   F

Complexity

Conditions 21
Paths 408

Size

Total Lines 211
Code Lines 145

Duplication

Lines 0
Ratio 0 %

Importance

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

How to fix   Long Method    Complexity    Many Parameters   

Long Method

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

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

Commonly applied refactorings include:

Many Parameters

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

There are several approaches to avoid long parameter lists:

1
<?php
2
/* For licensing terms, see /license.txt */
3
4
/**
5
 * Class Agenda.
6
 *
7
 * @author: Julio Montoya <[email protected]>
8
 */
9
class Agenda
10
{
11
    public $events = [];
12
    /** @var string Current type */
13
    public $type = 'personal';
14
    public $types = ['personal', 'admin', 'course'];
15
    public $sessionId = 0;
16
    public $senderId;
17
    /** @var array */
18
    public $course;
19
    /** @var string */
20
    public $comment;
21
    public $eventStudentPublicationColor;
22
    /** @var array */
23
    private $sessionInfo;
24
    /** @var bool */
25
    private $isAllowedToEdit;
26
27
    /**
28
     * Constructor.
29
     *
30
     * @param string $type
31
     * @param int    $senderId  Optional The user sender ID
32
     * @param int    $courseId  Optional. The course ID
33
     * @param int    $sessionId Optional The session ID
34
     */
35
    public function __construct(
36
        $type,
37
        $senderId = 0,
38
        $courseId = 0,
39
        $sessionId = 0
40
    ) {
41
        // Table definitions
42
        $this->tbl_global_agenda = Database::get_main_table(TABLE_MAIN_SYSTEM_CALENDAR);
43
        $this->tbl_personal_agenda = Database::get_main_table(TABLE_PERSONAL_AGENDA);
44
        $this->tbl_course_agenda = Database::get_course_table(TABLE_AGENDA);
45
        $this->table_repeat = Database::get_course_table(TABLE_AGENDA_REPEAT);
46
47
        $this->setType($type);
48
        $this->setSenderId($senderId ?: api_get_user_id());
49
        $isAllowToEdit = false;
50
51
        switch ($type) {
52
            case 'course':
53
                $sessionId = $sessionId ?: api_get_session_id();
54
                $sessionInfo = api_get_session_info($sessionId);
55
                $this->setSessionId($sessionId);
56
                $this->setSessionInfo($sessionInfo);
57
58
                // Setting the course object if we are in a course
59
                $courseInfo = api_get_course_info_by_id($courseId);
60
                if (!empty($courseInfo)) {
61
                    $this->set_course($courseInfo);
62
                }
63
64
                // Check if teacher/admin rights.
65
                $isAllowToEdit = api_is_allowed_to_edit(false, true);
66
                // Check course setting.
67
                if (api_get_course_setting('allow_user_edit_agenda') === '1'
68
                    && api_is_allowed_in_course()
69
                ) {
70
                    $isAllowToEdit = true;
71
                }
72
73
                $groupId = api_get_group_id();
74
                if (!empty($groupId)) {
75
                    $groupInfo = GroupManager::get_group_properties($groupId);
76
                    $userHasAccess = GroupManager::user_has_access(
77
                        api_get_user_id(),
78
                        $groupInfo['iid'],
79
                        GroupManager::GROUP_TOOL_CALENDAR
80
                    );
81
                    $isTutor = GroupManager::is_tutor_of_group(
82
                        api_get_user_id(),
83
                        $groupInfo
84
                    );
85
86
                    $isGroupAccess = $userHasAccess || $isTutor;
87
                    $isAllowToEdit = false;
88
                    if ($isGroupAccess) {
89
                        $isAllowToEdit = true;
90
                    }
91
                }
92
93
                if (!empty($sessionId)) {
94
                    $allowDhrToEdit = api_get_configuration_value('allow_agenda_edit_for_hrm');
95
                    if ($allowDhrToEdit) {
96
                        $isHrm = SessionManager::isUserSubscribedAsHRM($sessionId, api_get_user_id());
97
                        if ($isHrm) {
98
                            $isAllowToEdit = true;
99
                        }
100
                    }
101
                }
102
                break;
103
            case 'admin':
104
                $isAllowToEdit = api_is_platform_admin();
105
                break;
106
            case 'personal':
107
                $isAllowToEdit = !api_is_anonymous();
108
                break;
109
        }
110
111
        $this->setIsAllowedToEdit($isAllowToEdit);
112
        $this->events = [];
113
        $agendaColors = array_merge(
114
            [
115
                'platform' => 'red', //red
116
                'course' => '#458B00', //green
117
                'group' => '#A0522D', //siena
118
                'session' => '#00496D', // kind of green
119
                'other_session' => '#999', // kind of green
120
                'personal' => 'steel blue', //steel blue
121
                'student_publication' => '#FF8C00', //DarkOrange
122
            ],
123
            api_get_configuration_value('agenda_colors') ?: []
124
        );
125
126
        // Event colors
127
        $this->event_platform_color = $agendaColors['platform'];
128
        $this->event_course_color = $agendaColors['course'];
129
        $this->event_group_color = $agendaColors['group'];
130
        $this->event_session_color = $agendaColors['session'];
131
        $this->eventOtherSessionColor = $agendaColors['other_session'];
132
        $this->event_personal_color = $agendaColors['personal'];
133
        $this->eventStudentPublicationColor = $agendaColors['student_publication'];
134
    }
135
136
    /**
137
     * @param int $senderId
138
     */
139
    public function setSenderId($senderId)
140
    {
141
        $this->senderId = (int) $senderId;
142
    }
143
144
    /**
145
     * @return int
146
     */
147
    public function getSenderId()
148
    {
149
        return $this->senderId;
150
    }
151
152
    /**
153
     * @param string $type can be 'personal', 'admin'  or  'course'
154
     */
155
    public function setType($type)
156
    {
157
        $typeList = $this->getTypes();
158
        if (in_array($type, $typeList)) {
159
            $this->type = $type;
160
        }
161
    }
162
163
    /**
164
     * 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