Completed
Push — master ( f41061...196bfc )
by Julito
09:03
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('LoginX'),
2060
                                    $user_info['username']
2061
                                ),
2062
                                ENT_QUOTES
2063
                            );
2064
                            $sent_to[] = "<span title='".$username."'>".$user_info['complete_name']."</span>";
2065
                        }
2066
                    }
2067
                    $sent_to = implode('@@', $sent_to);
2068
                    $sent_to = str_replace(
2069
                        '@@',
2070
                        '</div><div class="label_tag notice">',
2071
                        $sent_to
2072
                    );
2073
                    $event['sent_to'] = '<div class="label_tag notice">'.$sent_to.'</div>';
2074
                }
2075
2076
                //Event sent to everyone!
2077
                if (empty($event['sent_to'])) {
2078
                    $event['sent_to'] = '<div class="label_tag notice">'.get_lang('Everyone').'</div>';
2079
                }
2080
2081
                $event['description'] = $row['content'];
2082
                $event['visibility'] = $row['visibility'];
2083
                $event['real_id'] = $row['id'];
2084
                $event['allDay'] = isset($row['all_day']) && $row['all_day'] == 1 ? $row['all_day'] : 0;
2085
                $event['parent_event_id'] = $row['parent_event_id'];
2086
                $event['has_children'] = $this->hasChildren($row['id'], $courseId) ? 1 : 0;
2087
                $event['comment'] = $row['comment'];
2088
                $this->events[] = $event;
2089
            }
2090
        }
2091
2092
        return $this->events;
2093
    }
2094
2095
    /**
2096
     * @param int $start tms
2097
     * @param int $end   tms
2098
     *
2099
     * @return array
2100
     */
2101
    public function getPlatformEvents($start, $end)
2102
    {
2103
        $start = isset($start) && !empty($start) ? api_get_utc_datetime(intval($start)) : null;
2104
        $end = isset($end) && !empty($end) ? api_get_utc_datetime(intval($end)) : null;
2105
        $dateCondition = '';
2106
2107
        if (!empty($start) && !empty($end)) {
2108
            $dateCondition .= "AND (
2109
                 start_date BETWEEN '".$start."' AND '".$end."' OR
2110
                 end_date BETWEEN '".$start."' AND '".$end."' OR
2111
                 (
2112
                     start_date IS NOT NULL AND end_date IS NOT NULL AND
2113
                     YEAR(start_date) = YEAR(end_date) AND
2114
                     MONTH('$start') BETWEEN MONTH(start_date) AND MONTH(end_date)
2115
                 )
2116
            )";
2117
        }
2118
2119
        $access_url_id = api_get_current_access_url_id();
2120
2121
        $sql = "SELECT *
2122
                FROM ".$this->tbl_global_agenda."
2123
                WHERE access_url_id = $access_url_id
2124
                $dateCondition";
2125
        $result = Database::query($sql);
2126
        $my_events = [];
2127
        if (Database::num_rows($result)) {
2128
            while ($row = Database::fetch_array($result, 'ASSOC')) {
2129
                $event = [];
2130
                $event['id'] = 'platform_'.$row['id'];
2131
                $event['title'] = $row['title'];
2132
                $event['className'] = 'platform';
2133
                $event['allDay'] = 'false';
2134
                $event['borderColor'] = $event['backgroundColor'] = $this->event_platform_color;
2135
                $event['editable'] = false;
2136
                $event['type'] = 'admin';
2137
2138
                if (api_is_platform_admin() && $this->type === 'admin') {
2139
                    $event['editable'] = true;
2140
                }
2141
2142
                if (!empty($row['start_date'])) {
2143
                    $event['start'] = $this->formatEventDate($row['start_date']);
2144
                    $event['start_date_localtime'] = api_get_local_time($row['start_date']);
2145
                }
2146
2147
                if (!empty($row['end_date'])) {
2148
                    $event['end'] = $this->formatEventDate($row['end_date']);
2149
                    $event['end_date_localtime'] = api_get_local_time($row['end_date']);
2150
                }
2151
                $event['allDay'] = isset($row['all_day']) && $row['all_day'] == 1 ? $row['all_day'] : 0;
2152
                $event['parent_event_id'] = 0;
2153
                $event['has_children'] = 0;
2154
                $event['description'] = $row['content'];
2155
2156
                $my_events[] = $event;
2157
                $this->events[] = $event;
2158
            }
2159
        }
2160
2161
        return $my_events;
2162
    }
2163
2164
    /**
2165
     * @param FormValidator $form
2166
     * @param array         $groupList
2167
     * @param array         $userList
2168
     * @param array         $sendTo               array('users' => [1, 2], 'groups' => [3, 4])
2169
     * @param array         $attributes
2170
     * @param bool          $addOnlyItemsInSendTo
2171
     * @param bool          $required
2172
     */
2173
    public function setSendToSelect(
2174
        $form,
2175
        $groupList = [],
2176
        $userList = [],
2177
        $sendTo = [],
2178
        $attributes = [],
2179
        $addOnlyItemsInSendTo = false,
2180
        $required = false
2181
    ) {
2182
        $params = [
2183
            'id' => 'users_to_send_id',
2184
            'data-placeholder' => get_lang('Select'),
2185
            'multiple' => 'multiple',
2186
            'class' => 'multiple-select',
2187
        ];
2188
2189
        if (!empty($attributes)) {
2190
            $params = array_merge($params, $attributes);
2191
            if (empty($params['multiple'])) {
2192
                unset($params['multiple']);
2193
            }
2194
        }
2195
2196
        $sendToGroups = isset($sendTo['groups']) ? $sendTo['groups'] : [];
2197
        $sendToUsers = isset($sendTo['users']) ? $sendTo['users'] : [];
2198
2199
        /** @var HTML_QuickForm_select $select */
2200
        $select = $form->addSelect(
2201
            'users_to_send',
2202
            get_lang('To'),
2203
            null,
2204
            $params
2205
        );
2206
2207
        if ($required) {
2208
            $form->setRequired($select);
2209
        }
2210
2211
        $selectedEveryoneOptions = [];
2212
        if (isset($sendTo['everyone']) && $sendTo['everyone']) {
2213
            $selectedEveryoneOptions = ['selected'];
2214
            $sendToUsers = [];
2215
        }
2216
2217
        $select->addOption(
2218
            get_lang('Everyone'),
2219
            'everyone',
2220
            $selectedEveryoneOptions
2221
        );
2222
2223
        $options = [];
2224
        if (is_array($groupList)) {
2225
            foreach ($groupList as $group) {
2226
                $count_users = isset($group['count_users']) ? $group['count_users'] : $group['userNb'];
2227
                $count_users = " &ndash; $count_users ".get_lang('Users');
2228
                $option = [
2229
                    'text' => $group['name'].$count_users,
2230
                    'value' => "GROUP:".$group['id'],
2231
                ];
2232
                $selected = in_array(
2233
                    $group['id'],
2234
                    $sendToGroups
2235
                ) ? true : false;
2236
                if ($selected) {
2237
                    $option['selected'] = 'selected';
2238
                }
2239
2240
                if ($addOnlyItemsInSendTo) {
2241
                    if ($selected) {
2242
                        $options[] = $option;
2243
                    }
2244
                } else {
2245
                    $options[] = $option;
2246
                }
2247
            }
2248
            $select->addOptGroup($options, get_lang('Groups'));
2249
        }
2250
2251
        // adding the individual users to the select form
2252
        if (is_array($userList)) {
2253
            $options = [];
2254
            foreach ($userList as $user) {
2255
                if ($user['status'] == ANONYMOUS) {
2256
                    continue;
2257
                }
2258
                $option = [
2259
                    'text' => api_get_person_name(
2260
                            $user['firstname'],
2261
                            $user['lastname']
2262
                        ).' ('.$user['username'].')',
2263
                    'value' => "USER:".$user['user_id'],
2264
                ];
2265
2266
                $selected = in_array(
2267
                    $user['user_id'],
2268
                    $sendToUsers
2269
                ) ? true : false;
2270
2271
                if ($selected) {
2272
                    $option['selected'] = 'selected';
2273
                }
2274
2275
                if ($addOnlyItemsInSendTo) {
2276
                    if ($selected) {
2277
                        $options[] = $option;
2278
                    }
2279
                } else {
2280
                    $options[] = $option;
2281
                }
2282
            }
2283
2284
            $select->addOptGroup($options, get_lang('Users'));
2285
        }
2286
    }
2287
2288
    /**
2289
     * Separates the users and groups array
2290
     * users have a value USER:XXX (with XXX the user id
2291
     * groups have a value GROUP:YYY (with YYY the group id)
2292
     * use the 'everyone' key.
2293
     *
2294
     * @author Julio Montoya based in separate_users_groups in agenda.inc.php
2295
     *
2296
     * @param array $to
2297
     *
2298
     * @return array
2299
     */
2300
    public function parseSendToArray($to)
2301
    {
2302
        $groupList = [];
2303
        $userList = [];
2304
        $sendTo = null;
2305
2306
        $sendTo['everyone'] = false;
2307
        if (is_array($to) && count($to) > 0) {
2308
            foreach ($to as $item) {
2309
                if ($item == 'everyone') {
2310
                    $sendTo['everyone'] = true;
2311
                } else {
2312
                    list($type, $id) = explode(':', $item);
2313
                    switch ($type) {
2314
                        case 'GROUP':
2315
                            $groupList[] = $id;
2316
                            break;
2317
                        case 'USER':
2318
                            $userList[] = $id;
2319
                            break;
2320
                    }
2321
                }
2322
            }
2323
            $sendTo['groups'] = $groupList;
2324
            $sendTo['users'] = $userList;
2325
        }
2326
2327
        return $sendTo;
2328
    }
2329
2330
    /**
2331
     * @param array $params
2332
     *
2333
     * @return FormValidator
2334
     */
2335
    public function getForm($params = [])
2336
    {
2337
        $action = isset($params['action']) ? Security::remove_XSS($params['action']) : null;
2338
        $id = isset($params['id']) ? (int) $params['id'] : 0;
2339
2340
        $url = api_get_self().'?action='.$action.'&id='.$id.'&type='.$this->type;
2341
        if ($this->type == 'course') {
2342
            $url = api_get_self().'?'.api_get_cidreq().'&action='.$action.'&id='.$id.'&type='.$this->type;
2343
        }
2344
2345
        $form = new FormValidator(
2346
            'add_event',
2347
            'post',
2348
            $url,
2349
            null,
2350
            ['enctype' => 'multipart/form-data']
2351
        );
2352
2353
        $idAttach = isset($params['id_attach']) ? (int) $params['id_attach'] : null;
2354
        $groupId = api_get_group_id();
2355
        $form_Title = get_lang('AddCalendarItem');
2356
        if (!empty($id)) {
2357
            $form_Title = get_lang('ModifyCalendarItem');
2358
        }
2359
2360
        $form->addHeader($form_Title);
2361
        $form->addElement('hidden', 'id', $id);
2362
        $form->addElement('hidden', 'action', $action);
2363
        $form->addElement('hidden', 'id_attach', $idAttach);
2364
2365
        $isSubEventEdition = false;
2366
        $isParentFromSerie = false;
2367
        $showAttachmentForm = true;
2368
2369
        if ($this->type == 'course') {
2370
            // Edition mode.
2371
            if (!empty($id)) {
2372
                $showAttachmentForm = false;
2373
                if (isset($params['parent_event_id']) && !empty($params['parent_event_id'])) {
2374
                    $isSubEventEdition = true;
2375
                }
2376
                if (!empty($params['repeat_info'])) {
2377
                    $isParentFromSerie = true;
2378
                }
2379
            }
2380
        }
2381
2382
        if ($isSubEventEdition) {
2383
            $form->addElement(
2384
                'label',
2385
                null,
2386
                Display::return_message(
2387
                    get_lang('EditingThisEventWillRemoveItFromTheSerie'),
2388
                    'warning'
2389
                )
2390
            );
2391
        }
2392
2393
        $form->addElement('text', 'title', get_lang('ItemTitle'));
2394
2395
        if (isset($groupId) && !empty($groupId)) {
2396
            $form->addElement(
2397
                'hidden',
2398
                'users_to_send[]',
2399
                "GROUP:$groupId"
2400
            );
2401
            $form->addElement('hidden', 'to', 'true');
2402
        } else {
2403
            $sendTo = isset($params['send_to']) ? $params['send_to'] : ['everyone' => true];
2404
            if ($this->type == 'course') {
2405
                $this->showToForm($form, $sendTo, [], false, true);
2406
            }
2407
        }
2408
2409
        $form->addDateRangePicker(
2410
            'date_range',
2411
            get_lang('DateRange'),
2412
            false,
2413
            ['id' => 'date_range']
2414
        );
2415
        $form->addElement('checkbox', 'all_day', null, get_lang('AllDay'));
2416
2417
        if ($this->type == 'course') {
2418
            $repeat = $form->addElement(
2419
                'checkbox',
2420
                'repeat',
2421
                null,
2422
                get_lang('RepeatEvent'),
2423
                ['onclick' => 'return plus_repeated_event();']
2424
            );
2425
            $form->addElement(
2426
                'html',
2427
                '<div id="options2" style="display:none">'
2428
            );
2429
            $form->addElement(
2430
                'select',
2431
                'repeat_type',
2432
                get_lang('RepeatType'),
2433
                self::getRepeatTypes()
2434
            );
2435
            $form->addElement(
2436
                'date_picker',
2437
                'repeat_end_day',
2438
                get_lang('RepeatEnd'),
2439
                ['id' => 'repeat_end_date_form']
2440
            );
2441
2442
            if ($isSubEventEdition || $isParentFromSerie) {
2443
                $repeatInfo = $params['repeat_info'];
2444
                if ($isSubEventEdition) {
2445
                    $parentEvent = $params['parent_info'];
2446
                    $repeatInfo = $parentEvent['repeat_info'];
2447
                }
2448
                $params['repeat'] = 1;
2449
                $params['repeat_type'] = $repeatInfo['cal_type'];
2450
                $params['repeat_end_day'] = substr(
2451
                    api_get_local_time($repeatInfo['cal_end']),
2452
                    0,
2453
                    10
2454
                );
2455
2456
                $form->freeze(['repeat_type', 'repeat_end_day']);
2457
                $repeat->_attributes['disabled'] = 'disabled';
2458
            }
2459
            $form->addElement('html', '</div>');
2460
        }
2461
2462
        if (!empty($id)) {
2463
            if (empty($params['end_date'])) {
2464
                $params['date_range'] = $params['end_date'];
2465
            }
2466
2467
            $params['date_range'] =
2468
                substr(api_get_local_time($params['start_date']), 0, 16).' / '.
2469
                substr(api_get_local_time($params['end_date']), 0, 16);
2470
        }
2471
2472
        $toolbar = 'Agenda';
2473
        if (!api_is_allowed_to_edit(null, true)) {
2474
            $toolbar = 'AgendaStudent';
2475
        }
2476
2477
        $form->addElement(
2478
            'html_editor',
2479
            'content',
2480
            get_lang('Description'),
2481
            null,
2482
            [
2483
                'ToolbarSet' => $toolbar,
2484
                'Width' => '100%',
2485
                'Height' => '200',
2486
            ]
2487
        );
2488
2489
        if ($this->type == 'course') {
2490
            $form->addElement('textarea', 'comment', get_lang('Comment'));
2491
            $form->addLabel(
2492
                get_lang('FilesAttachment'),
2493
                '<span id="filepaths">
2494
                        <div id="filepath_1">
2495
                            <input type="file" name="attach_1"/><br />
2496
                            '.get_lang('Description').'&nbsp;&nbsp;<input type="text" name="legend[]" /><br /><br />
2497
                        </div>
2498
                    </span>'
2499
            );
2500
2501
            $form->addLabel(
2502
                '',
2503
                '<span id="link-more-attach">
2504
                    <a href="javascript://" onclick="return add_image_form()">'.
2505
                get_lang('AddOneMoreFile').'</a>
2506
                 </span>&nbsp;('.sprintf(
2507
                    get_lang('MaximunFileSizeX'),
2508
                    format_file_size(
2509
                        api_get_setting('message_max_upload_filesize')
2510
                    )
2511
                ).')'
2512
            );
2513
2514
            if (isset($params['attachment']) && !empty($params['attachment'])) {
2515
                $attachmentList = $params['attachment'];
2516
                foreach ($attachmentList as $attachment) {
2517
                    $params['file_comment'] = $attachment['comment'];
2518
                    if (!empty($attachment['path'])) {
2519
                        $form->addElement(
2520
                            'checkbox',
2521
                            'delete_attachment['.$attachment['id'].']',
2522
                            null,
2523
                            get_lang(
2524
                                'DeleteAttachment'
2525
                            ).': '.$attachment['filename']
2526
                        );
2527
                    }
2528
                }
2529
            }
2530
2531
            $form->addElement(
2532
                'textarea',
2533
                'file_comment',
2534
                get_lang('FileComment')
2535
            );
2536
        }
2537
2538
        if (empty($id)) {
2539
            $form->addElement(
2540
                'checkbox',
2541
                'add_announcement',
2542
                null,
2543
                get_lang('AddAnnouncement').'&nbsp('.get_lang('SendMail').')'
2544
            );
2545
        }
2546
2547
        if ($id) {
2548
            $form->addButtonUpdate(get_lang('ModifyEvent'));
2549
        } else {
2550
            $form->addButtonSave(get_lang('AgendaAdd'));
2551
        }
2552
2553
        $form->setDefaults($params);
2554
        $form->addRule(
2555
            'date_range',
2556
            get_lang('ThisFieldIsRequired'),
2557
            'required'
2558
        );
2559
        $form->addRule('title', get_lang('ThisFieldIsRequired'), 'required');
2560
2561
        return $form;
2562
    }
2563
2564
    /**
2565
     * @param FormValidator $form
2566
     * @param array         $sendTo               array('everyone' => false, 'users' => [1, 2], 'groups' => [3, 4])
2567
     * @param array         $attributes
2568
     * @param bool          $addOnlyItemsInSendTo
2569
     * @param bool          $required
2570
     *
2571
     * @return bool
2572
     */
2573
    public function showToForm(
2574
        $form,
2575
        $sendTo = [],
2576
        $attributes = [],
2577
        $addOnlyItemsInSendTo = false,
2578
        $required = false
2579
    ) {
2580
        if ($this->type != 'course') {
2581
            return false;
2582
        }
2583
2584
        $order = 'lastname';
2585
        if (api_is_western_name_order()) {
2586
            $order = 'firstname';
2587
        }
2588
2589
        $userList = CourseManager::get_user_list_from_course_code(
2590
            api_get_course_id(),
2591
            $this->sessionId,
2592
            null,
2593
            $order
2594
        );
2595
2596
        $groupList = CourseManager::get_group_list_of_course(
2597
            api_get_course_id(),
2598
            $this->sessionId
2599
        );
2600
2601
        $this->setSendToSelect(
2602
            $form,
2603
            $groupList,
2604
            $userList,
2605
            $sendTo,
2606
            $attributes,
2607
            $addOnlyItemsInSendTo,
2608
            $required
2609
        );
2610
2611
        return true;
2612
    }
2613
2614
    /**
2615
     * @param int   $id
2616
     * @param int   $visibility 0= invisible, 1 visible
2617
     * @param array $courseInfo
2618
     * @param int   $userId
2619
     */
2620
    public static function changeVisibility(
2621
        $id,
2622
        $visibility,
2623
        $courseInfo,
2624
        $userId = null
2625
    ) {
2626
        $id = intval($id);
2627
        if (empty($userId)) {
2628
            $userId = api_get_user_id();
2629
        } else {
2630
            $userId = intval($userId);
2631
        }
2632
2633
        if ($visibility == 0) {
2634
            api_item_property_update(
2635
                $courseInfo,
2636
                TOOL_CALENDAR_EVENT,
2637
                $id,
2638
                'invisible',
2639
                $userId
2640
            );
2641
        } else {
2642
            api_item_property_update(
2643
                $courseInfo,
2644
                TOOL_CALENDAR_EVENT,
2645
                $id,
2646
                'visible',
2647
                $userId
2648
            );
2649
        }
2650
    }
2651
2652
    /**
2653
     * Get repeat types.
2654
     *
2655
     * @return array
2656
     */
2657
    public static function getRepeatTypes()
2658
    {
2659
        return [
2660
            'daily' => get_lang('RepeatDaily'),
2661
            'weekly' => get_lang('RepeatWeekly'),
2662
            'monthlyByDate' => get_lang('RepeatMonthlyByDate'),
2663
            //monthlyByDay"> get_lang('RepeatMonthlyByDay');
2664
            //monthlyByDayR' => get_lang('RepeatMonthlyByDayR'),
2665
            'yearly' => get_lang('RepeatYearly'),
2666
        ];
2667
    }
2668
2669
    /**
2670
     * Show a list with all the attachments according to the post's id.
2671
     *
2672
     * @param int   $eventId
2673
     * @param array $courseInfo
2674
     *
2675
     * @return array with the post info
2676
     */
2677
    public function getAttachmentList($eventId, $courseInfo)
2678
    {
2679
        $tableAttachment = Database::get_course_table(TABLE_AGENDA_ATTACHMENT);
2680
        $courseId = (int) $courseInfo['real_id'];
2681
        $eventId = (int) $eventId;
2682
2683
        $sql = "SELECT id, path, filename, comment
2684
                FROM $tableAttachment
2685
                WHERE
2686
                    c_id = $courseId AND
2687
                    agenda_id = $eventId";
2688
        $result = Database::query($sql);
2689
        $list = [];
2690
        if (Database::num_rows($result) != 0) {
2691
            $list = Database::store_result($result, 'ASSOC');
2692
        }
2693
2694
        return $list;
2695
    }
2696
2697
    /**
2698
     * Show a list with all the attachments according to the post's id.
2699
     *
2700
     * @param int   $attachmentId
2701
     * @param int   $eventId
2702
     * @param array $courseInfo
2703
     *
2704
     * @return array with the post info
2705
     */
2706
    public function getAttachment($attachmentId, $eventId, $courseInfo)
2707
    {
2708
        if (empty($courseInfo) || empty($attachmentId) || empty($eventId)) {
2709
            return [];
2710
        }
2711
2712
        $tableAttachment = Database::get_course_table(TABLE_AGENDA_ATTACHMENT);
2713
        $courseId = (int) $courseInfo['real_id'];
2714
        $eventId = (int) $eventId;
2715
        $attachmentId = (int) $attachmentId;
2716
2717
        $row = [];
2718
        $sql = "SELECT id, path, filename, comment
2719
                FROM $tableAttachment
2720
                WHERE
2721
                    c_id = $courseId AND
2722
                    agenda_id = $eventId AND
2723
                    id = $attachmentId
2724
                ";
2725
        $result = Database::query($sql);
2726
        if (Database::num_rows($result) != 0) {
2727
            $row = Database::fetch_array($result, 'ASSOC');
2728
        }
2729
2730
        return $row;
2731
    }
2732
2733
    /**
2734
     * Add an attachment file into agenda.
2735
     *
2736
     * @param int    $eventId
2737
     * @param array  $fileUserUpload ($_FILES['user_upload'])
2738
     * @param string $comment        about file
2739
     * @param array  $courseInfo
2740
     *
2741
     * @return string
2742
     */
2743
    public function addAttachment(
2744
        $eventId,
2745
        $fileUserUpload,
2746
        $comment,
2747
        $courseInfo
2748
    ) {
2749
        $agenda_table_attachment = Database::get_course_table(TABLE_AGENDA_ATTACHMENT);
2750
        $eventId = (int) $eventId;
2751
2752
        // Storing the attachments
2753
        $upload_ok = false;
2754
        if (!empty($fileUserUpload['name'])) {
2755
            $upload_ok = process_uploaded_file($fileUserUpload);
2756
        }
2757
2758
        if (!empty($upload_ok)) {
2759
            $courseDir = $courseInfo['directory'].'/upload/calendar';
2760
            $sys_course_path = api_get_path(SYS_COURSE_PATH);
2761
            $uploadDir = $sys_course_path.$courseDir;
2762
2763
            // Try to add an extension to the file if it hasn't one
2764
            $new_file_name = add_ext_on_mime(
2765
                stripslashes($fileUserUpload['name']),
2766
                $fileUserUpload['type']
2767
            );
2768
2769
            // user's file name
2770
            $file_name = $fileUserUpload['name'];
2771
2772
            if (!filter_extension($new_file_name)) {
2773
                return Display::return_message(
2774
                    get_lang('UplUnableToSaveFileFilteredExtension'),
2775
                    'error'
2776
                );
2777
            } else {
2778
                $new_file_name = uniqid('');
2779
                $new_path = $uploadDir.'/'.$new_file_name;
2780
                $result = @move_uploaded_file(
2781
                    $fileUserUpload['tmp_name'],
2782
                    $new_path
2783
                );
2784
                $courseId = api_get_course_int_id();
2785
                $size = intval($fileUserUpload['size']);
2786
                // Storing the attachments if any
2787
                if ($result) {
2788
                    $params = [
2789
                        'c_id' => $courseId,
2790
                        'filename' => $file_name,
2791
                        'comment' => $comment,
2792
                        'path' => $new_file_name,
2793
                        'agenda_id' => $eventId,
2794
                        'size' => $size,
2795
                    ];
2796
                    $id = Database::insert($agenda_table_attachment, $params);
2797
                    if ($id) {
2798
                        $sql = "UPDATE $agenda_table_attachment
2799
                                SET id = iid WHERE iid = $id";
2800
                        Database::query($sql);
2801
2802
                        api_item_property_update(
2803
                            $courseInfo,
2804
                            'calendar_event_attachment',
2805
                            $id,
2806
                            'AgendaAttachmentAdded',
2807
                            api_get_user_id()
2808
                        );
2809
                    }
2810
                }
2811
            }
2812
        }
2813
    }
2814
2815
    /**
2816
     * @param int    $attachmentId
2817
     * @param int    $eventId
2818
     * @param array  $fileUserUpload
2819
     * @param string $comment
2820
     * @param array  $courseInfo
2821
     */
2822
    public function updateAttachment(
2823
        $attachmentId,
2824
        $eventId,
2825
        $fileUserUpload,
2826
        $comment,
2827
        $courseInfo
2828
    ) {
2829
        $attachment = $this->getAttachment(
2830
            $attachmentId,
2831
            $eventId,
2832
            $courseInfo
2833
        );
2834
        if (!empty($attachment)) {
2835
            $this->deleteAttachmentFile($attachmentId, $courseInfo);
2836
        }
2837
        $this->addAttachment($eventId, $fileUserUpload, $comment, $courseInfo);
2838
    }
2839
2840
    /**
2841
     * This function delete a attachment file by id.
2842
     *
2843
     * @param int   $attachmentId
2844
     * @param array $courseInfo
2845
     *
2846
     * @return string
2847
     */
2848
    public function deleteAttachmentFile($attachmentId, $courseInfo)
2849
    {
2850
        $table = Database::get_course_table(TABLE_AGENDA_ATTACHMENT);
2851
        $attachmentId = (int) $attachmentId;
2852
        $courseId = $courseInfo['real_id'];
2853
2854
        if (empty($courseId) || empty($attachmentId)) {
2855
            return false;
2856
        }
2857
2858
        $sql = "DELETE FROM $table
2859
                WHERE c_id = $courseId AND id = ".$attachmentId;
2860
        $result = Database::query($sql);
2861
2862
        // update item_property
2863
        api_item_property_update(
2864
            $courseInfo,
2865
            'calendar_event_attachment',
2866
            $attachmentId,
2867
            'AgendaAttachmentDeleted',
2868
            api_get_user_id()
2869
        );
2870
2871
        if (!empty($result)) {
2872
            return Display::return_message(
2873
                get_lang("AttachmentFileDeleteSuccess"),
2874
                'confirmation'
2875
            );
2876
        }
2877
    }
2878
2879
    /**
2880
     * @param int $eventId
2881
     *
2882
     * @return array
2883
     */
2884
    public function getAllRepeatEvents($eventId)
2885
    {
2886
        $events = [];
2887
        $eventId = (int) $eventId;
2888
2889
        switch ($this->type) {
2890
            case 'personal':
2891
                break;
2892
            case 'course':
2893
                if (!empty($this->course['real_id'])) {
2894
                    $sql = "SELECT * FROM ".$this->tbl_course_agenda."
2895
                            WHERE
2896
                                c_id = ".$this->course['real_id']." AND
2897
                                parent_event_id = ".$eventId;
2898
                    $result = Database::query($sql);
2899
                    if (Database::num_rows($result)) {
2900
                        while ($row = Database::fetch_array($result, 'ASSOC')) {
2901
                            $events[] = $row;
2902
                        }
2903
                    }
2904
                }
2905
                break;
2906
        }
2907
2908
        return $events;
2909
    }
2910
2911
    /**
2912
     * @param int $eventId
2913
     * @param int $courseId
2914
     *
2915
     * @return bool
2916
     */
2917
    public function hasChildren($eventId, $courseId)
2918
    {
2919
        $eventId = (int) $eventId;
2920
        $courseId = (int) $courseId;
2921
2922
        $sql = "SELECT count(DISTINCT(id)) as count
2923
                FROM ".$this->tbl_course_agenda."
2924
                WHERE
2925
                    c_id = $courseId AND
2926
                    parent_event_id = $eventId";
2927
        $result = Database::query($sql);
2928
        if (Database::num_rows($result)) {
2929
            $row = Database::fetch_array($result, 'ASSOC');
2930
2931
            return $row['count'] > 0;
2932
        }
2933
2934
        return false;
2935
    }
2936
2937
    /**
2938
     * @param int    $filter
2939
     * @param string $view
2940
     *
2941
     * @return string
2942
     */
2943
    public function displayActions($view, $filter = 0)
2944
    {
2945
        $courseInfo = api_get_course_info();
2946
        $groupInfo = GroupManager::get_group_properties(api_get_group_id());
2947
        $groupIid = isset($groupInfo['iid']) ? $groupInfo['iid'] : 0;
2948
2949
        $courseCondition = '';
2950
        if (!empty($courseInfo)) {
2951
            $courseCondition = api_get_cidreq();
2952
        }
2953
2954
        $actionsLeft = '';
2955
        $actionsLeft .= "<a href='".api_get_path(WEB_CODE_PATH)."calendar/agenda_js.php?type={$this->type}&".$courseCondition."'>".
2956
            Display::return_icon(
2957
                'calendar.png',
2958
                get_lang('Calendar'),
2959
                '',
2960
                ICON_SIZE_MEDIUM
2961
            )."</a>";
2962
2963
        $actionsLeft .= "<a href='".api_get_path(WEB_CODE_PATH)."calendar/agenda_list.php?type={$this->type}&".$courseCondition."'>".
2964
            Display::return_icon(
2965
                'week.png',
2966
                get_lang('AgendaList'),
2967
                '',
2968
                ICON_SIZE_MEDIUM
2969
            )."</a>";
2970
2971
        $form = '';
2972
        if (api_is_allowed_to_edit(false, true) ||
2973
            (api_get_course_setting('allow_user_edit_agenda') == '1' &&
2974
                !api_is_anonymous()) &&
2975
            api_is_allowed_to_session_edit(false, true) ||
2976
            (GroupManager::user_has_access(
2977
                api_get_user_id(),
2978
                $groupIid,
2979
                GroupManager::GROUP_TOOL_CALENDAR
2980
            ) &&
2981
            GroupManager::is_tutor_of_group(api_get_user_id(), $groupInfo))
2982
        ) {
2983
            $actionsLeft .= Display::url(
2984
                Display::return_icon(
2985
                    'new_event.png',
2986
                    get_lang('AgendaAdd'),
2987
                    '',
2988
                    ICON_SIZE_MEDIUM
2989
                ),
2990
                api_get_path(WEB_CODE_PATH)."calendar/agenda.php?".api_get_cidreq()."&action=add&type=".$this->type
2991
            );
2992
2993
            $actionsLeft .= Display::url(
2994
                Display::return_icon(
2995
                    'import_calendar.png',
2996
                    get_lang('ICalFileImport'),
2997
                    '',
2998
                    ICON_SIZE_MEDIUM
2999
                ),
3000
                api_get_path(WEB_CODE_PATH)."calendar/agenda.php?".api_get_cidreq()."&action=importical&type=".$this->type
3001
            );
3002
3003
            if ($this->type === 'course') {
3004
                if (!isset($_GET['action'])) {
3005
                    $form = new FormValidator(
3006
                        'form-search',
3007
                        'post',
3008
                        '',
3009
                        '',
3010
                        [],
3011
                        FormValidator::LAYOUT_INLINE
3012
                    );
3013
                    $attributes = [
3014
                        'multiple' => false,
3015
                        'id' => 'select_form_id_search',
3016
                    ];
3017
                    $selectedValues = $this->parseAgendaFilter($filter);
3018
                    $this->showToForm($form, $selectedValues, $attributes);
3019
                    $form = $form->returnForm();
3020
                }
3021
            }
3022
        }
3023
3024
        if (api_is_platform_admin() ||
3025
            api_is_teacher() ||
3026
            api_is_student_boss() ||
3027
            api_is_drh() ||
3028
            api_is_session_admin() ||
3029
            api_is_coach()
3030
        ) {
3031
            if ($this->type == 'personal') {
3032
                $form = null;
3033
                if (!isset($_GET['action'])) {
3034
                    $form = new FormValidator(
3035
                        'form-search',
3036
                        'get',
3037
                        api_get_self().'?type=personal&',
3038
                        '',
3039
                        [],
3040
                        FormValidator::LAYOUT_INLINE
3041
                    );
3042
3043
                    if (api_is_drh()) {
3044
                        $sessionList = SessionManager::get_sessions_followed_by_drh(
3045
                            api_get_user_id()
3046
                        );
3047
                        if (!empty($sessionList)) {
3048
                            $sessions = [];
3049
                            foreach ($sessionList as $sessionItem) {
3050
                                $sessions[$sessionItem['id']] = strip_tags($sessionItem['name']);
3051
                            }
3052
                        }
3053
                    } else {
3054
                        $sessions = SessionManager::get_sessions_by_user(
3055
                            api_get_user_id()
3056
                        );
3057
                        $sessions = array_column(
3058
                            $sessions,
3059
                            'session_name',
3060
                            'session_id'
3061
                        );
3062
                    }
3063
                    $form->addHidden('type', 'personal');
3064
                    $sessions = ['0' => get_lang('Select An Option')] + $sessions;
3065
3066
                    $form->addSelect(
3067
                        'session_id',
3068
                        get_lang('Session'),
3069
                        $sessions,
3070
                        ['id' => 'session_id', 'onchange' => 'submit();', 'icon' => 'broom']
3071
                    )->setButton(true);
3072
                    $form = $form->returnForm();
3073
                }
3074
            }
3075
        }
3076
3077
        $actionsRight = '';
3078
        if ($view == 'calendar') {
3079
            $actionsRight .= $form;
3080
        }
3081
3082
        $toolbar = Display::toolbarAction(
3083
            'toolbar-agenda',
3084
            [$actionsLeft, $actionsRight]
3085
        );
3086
3087
        return $toolbar;
3088
    }
3089
3090
    /**
3091
     * @return FormValidator
3092
     */
3093
    public function getImportCalendarForm()
3094
    {
3095
        $form = new FormValidator(
3096
            'frm_import_ical',
3097
            'post',
3098
            api_get_self().'?action=importical&type='.$this->type,
3099
            ['enctype' => 'multipart/form-data']
3100
        );
3101
        $form->addElement('header', get_lang('ICalFileImport'));
3102
        $form->addElement('file', 'ical_import', get_lang('ICalFileImport'));
3103
        $form->addRule(
3104
            'ical_import',
3105
            get_lang('ThisFieldIsRequired'),
3106
            'required'
3107
        );
3108
        $form->addButtonImport(get_lang('Import'), 'ical_submit');
3109
3110
        return $form;
3111
    }
3112
3113
    /**
3114
     * @param array $courseInfo
3115
     * @param $file
3116
     *
3117
     * @return false|string
3118
     */
3119
    public function importEventFile($courseInfo, $file)
3120
    {
3121
        $charset = api_get_system_encoding();
3122
        $filepath = api_get_path(SYS_ARCHIVE_PATH).$file['name'];
3123
        $messages = [];
3124
3125
        if (!@move_uploaded_file($file['tmp_name'], $filepath)) {
3126
            error_log(
3127
                'Problem moving uploaded file: '.$file['error'].' in '.__FILE__.' line '.__LINE__
3128
            );
3129
3130
            return false;
3131
        }
3132
3133
        $data = file_get_contents($filepath);
3134
3135
        $trans = [
3136
            'DAILY' => 'daily',
3137
            'WEEKLY' => 'weekly',
3138
            'MONTHLY' => 'monthlyByDate',
3139
            'YEARLY' => 'yearly',
3140
        ];
3141
        $sentTo = ['everyone' => true];
3142
        $calendar = Sabre\VObject\Reader::read($data);
3143
        $currentTimeZone = api_get_timezone();
3144
        if (!empty($calendar->VEVENT)) {
3145
            foreach ($calendar->VEVENT as $event) {
3146
                $start = $event->DTSTART->getDateTime();
3147
                $end = $event->DTEND->getDateTime();
3148
                //Sabre\VObject\DateTimeParser::parseDateTime(string $dt, \Sabre\VObject\DateTimeZone $tz)
3149
3150
                $startDateTime = api_get_local_time(
3151
                    $start->format('Y-m-d H:i:s'),
3152
                    $currentTimeZone,
3153
                    $start->format('e')
3154
                );
3155
                $endDateTime = api_get_local_time(
3156
                    $end->format('Y-m-d H:i'),
3157
                    $currentTimeZone,
3158
                    $end->format('e')
3159
                );
3160
                $title = api_convert_encoding(
3161
                    (string) $event->summary,
3162
                    $charset,
3163
                    'UTF-8'
3164
                );
3165
                $description = api_convert_encoding(
3166
                    (string) $event->description,
3167
                    $charset,
3168
                    'UTF-8'
3169
                );
3170
3171
                $id = $this->addEvent(
3172
                    $startDateTime,
3173
                    $endDateTime,
3174
                    'false',
3175
                    $title,
3176
                    $description,
3177
                    $sentTo
3178
                );
3179
3180
                $messages[] = " $title - ".$startDateTime." - ".$endDateTime;
3181
3182
                //$attendee = (string)$event->attendee;
3183
                /** @var Sabre\VObject\Property\ICalendar\Recur $repeat */
3184
                $repeat = $event->RRULE;
3185
                if ($id && !empty($repeat)) {
3186
                    $repeat = $repeat->getParts();
3187
                    $freq = $trans[$repeat['FREQ']];
3188
3189
                    if (isset($repeat['UNTIL']) && !empty($repeat['UNTIL'])) {
3190
                        // Check if datetime or just date (strlen == 8)
3191
                        if (strlen($repeat['UNTIL']) == 8) {
3192
                            // Fix the datetime format to avoid exception in the next step
3193
                            $repeat['UNTIL'] .= 'T000000';
3194
                        }
3195
                        $until = Sabre\VObject\DateTimeParser::parseDateTime(
3196
                            $repeat['UNTIL'],
3197
                            new DateTimeZone($currentTimeZone)
3198
                        );
3199
                        $until = $until->format('Y-m-d H:i:s');
3200
                        $this->addRepeatedItem(
3201
                            $id,
3202
                            $freq,
3203
                            $until,
3204
                            $sentTo
3205
                        );
3206
                    }
3207
3208
                    if (!empty($repeat['COUNT'])) {
3209
                        /*$count = $repeat['COUNT'];
3210
                        $interval = $repeat['INTERVAL'];
3211
                        $endDate = null;
3212
                        switch($freq) {
3213
                            case 'daily':
3214
                                $start = api_strtotime($startDateTime);
3215
                                $date = new DateTime($startDateTime);
3216
                                $days = $count * $interval;
3217
                                var_dump($days);
3218
                                $date->add(new DateInterval("P".$days."D"));
3219
                                $endDate = $date->format('Y-m-d H:i');
3220
                                //$endDate = $count *
3221
                                for ($i = 0; $i < $count; $i++) {
3222
                                    $days = 86400 * 7
3223
                                }
3224
                            }
3225
                        }*/
3226
                        //$res = agenda_add_repeat_item($courseInfo, $id, $freq, $count, $attendee);
3227
                        /*$this->addRepeatedItem(
3228
                            $id,
3229
                            $freq,
3230
                            $endDate,
3231
                            $sentTo
3232
                        );*/
3233
                    }
3234
                }
3235
            }
3236
        }
3237
3238
        if (!empty($messages)) {
3239
            $messages = implode('<br /> ', $messages);
3240
        } else {
3241
            $messages = get_lang('NoAgendaItems');
3242
        }
3243
3244
        return $messages;
3245
    }
3246
3247
    /**
3248
     * Parse filter turns USER:12 to ['users' => [12])] or G:1 ['groups' => [1]].
3249
     *
3250
     * @param int $filter
3251
     *
3252
     * @return array
3253
     */
3254
    public function parseAgendaFilter($filter)
3255
    {
3256
        $everyone = false;
3257
        $groupId = null;
3258
        $userId = null;
3259
3260
        if ($filter == 'everyone') {
3261
            $everyone = true;
3262
        } else {
3263
            if (substr($filter, 0, 1) == 'G') {
3264
                $groupId = str_replace('GROUP:', '', $filter);
3265
            } else {
3266
                $userId = str_replace('USER:', '', $filter);
3267
            }
3268
        }
3269
        if (empty($userId) && empty($groupId)) {
3270
            $everyone = true;
3271
        }
3272
3273
        return [
3274
            'everyone' => $everyone,
3275
            'users' => [$userId],
3276
            'groups' => [$groupId],
3277
        ];
3278
    }
3279
3280
    /**
3281
     *    This function retrieves all the agenda items of all the courses the user is subscribed to.
3282
     */
3283
    public static function get_myagendaitems(
3284
        $user_id,
3285
        $courses_dbs,
3286
        $month,
3287
        $year
3288
    ) {
3289
        $user_id = intval($user_id);
3290
3291
        $items = [];
3292
        $my_list = [];
3293
3294
        // get agenda-items for every course
3295
        foreach ($courses_dbs as $key => $array_course_info) {
3296
            //databases of the courses
3297
            $TABLEAGENDA = Database::get_course_table(TABLE_AGENDA);
3298
            $TABLE_ITEMPROPERTY = Database::get_course_table(
3299
                TABLE_ITEM_PROPERTY
3300
            );
3301
3302
            $group_memberships = GroupManager::get_group_ids(
3303
                $array_course_info['real_id'],
3304
                $user_id
3305
            );
3306
            $course_user_status = CourseManager::getUserInCourseStatus(
3307
                $user_id,
3308
                $array_course_info['real_id']
3309
            );
3310
            // if the user is administrator of that course we show all the agenda items
3311
            if ($course_user_status == '1') {
3312
                //echo "course admin";
3313
                $sqlquery = "SELECT DISTINCT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref
3314
							FROM ".$TABLEAGENDA." agenda,
3315
								 ".$TABLE_ITEMPROPERTY." ip
3316
							WHERE agenda.id = ip.ref
3317
							AND MONTH(agenda.start_date)='".$month."'
3318
							AND YEAR(agenda.start_date)='".$year."'
3319
							AND ip.tool='".TOOL_CALENDAR_EVENT."'
3320
							AND ip.visibility='1'
3321
							GROUP BY agenda.id
3322
							ORDER BY start_date ";
3323
            } else {
3324
                // if the user is not an administrator of that course
3325
                if (is_array($group_memberships) && count(
3326
                        $group_memberships
3327
                    ) > 0
3328
                ) {
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 IS NULL OR ip.to_group_id IN (0, ".implode(
3337
                            ", ",
3338
                            $group_memberships
3339
                        ).")) )
3340
								AND ip.visibility='1'
3341
								ORDER BY start_date ";
3342
                } else {
3343
                    $sqlquery = "SELECT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref
3344
								FROM ".$TABLEAGENDA." agenda,
3345
									".$TABLE_ITEMPROPERTY." ip
3346
								WHERE agenda.id = ip.ref
3347
								AND MONTH(agenda.start_date)='".$month."'
3348
								AND YEAR(agenda.start_date)='".$year."'
3349
								AND ip.tool='".TOOL_CALENDAR_EVENT."'
3350
								AND ( ip.to_user_id='".$user_id."' OR ip.to_group_id='0' OR ip.to_group_id IS NULL)
3351
								AND ip.visibility='1'
3352
								ORDER BY start_date ";
3353
                }
3354
            }
3355
            $result = Database::query($sqlquery);
3356
3357
            while ($item = Database::fetch_array($result, 'ASSOC')) {
3358
                $agendaday = -1;
3359
                if (!empty($item['start_date'])) {
3360
                    $item['start_date'] = api_get_local_time(
3361
                        $item['start_date']
3362
                    );
3363
                    $item['start_date_tms'] = api_strtotime(
3364
                        $item['start_date']
3365
                    );
3366
                    $agendaday = date("j", $item['start_date_tms']);
3367
                }
3368
                if (!empty($item['end_date'])) {
3369
                    $item['end_date'] = api_get_local_time($item['end_date']);
3370
                }
3371
3372
                $url = api_get_path(
3373
                        WEB_CODE_PATH
3374
                    )."calendar/agenda.php?cidReq=".urlencode(
3375
                        $array_course_info["code"]
3376
                    )."&day=$agendaday&month=$month&year=$year#$agendaday";
3377
3378
                $item['url'] = $url;
3379
                $item['course_name'] = $array_course_info['title'];
3380
                $item['calendar_type'] = 'course';
3381
                $item['course_id'] = $array_course_info['course_id'];
3382
3383
                $my_list[$agendaday][] = $item;
3384
            }
3385
        }
3386
3387
        // sorting by hour for every day
3388
        $agendaitems = [];
3389
        foreach ($items as $agendaday => $tmpitems) {
3390
            if (!isset($agendaitems[$agendaday])) {
3391
                $agendaitems[$agendaday] = '';
3392
            }
3393
            sort($tmpitems);
3394
            foreach ($tmpitems as $val) {
3395
                $agendaitems[$agendaday] .= $val;
3396
            }
3397
        }
3398
3399
        return $my_list;
3400
    }
3401
3402
    /**
3403
     * This function retrieves one personal agenda item returns it.
3404
     *
3405
     * @param    array    The array containing existing events. We add to this array.
3406
     * @param    int        Day
3407
     * @param    int        Month
3408
     * @param    int        Year (4 digits)
3409
     * @param    int        Week number
3410
     * @param    string    Type of view (month_view, week_view, day_view)
3411
     *
3412
     * @return array The results of the database query, or null if not found
3413
     */
3414
    public static function get_global_agenda_items(
3415
        $agendaitems,
3416
        $day = "",
3417
        $month = "",
3418
        $year = "",
3419
        $week = "",
3420
        $type
3421
    ) {
3422
        $tbl_global_agenda = Database::get_main_table(
3423
            TABLE_MAIN_SYSTEM_CALENDAR
3424
        );
3425
        $month = intval($month);
3426
        $year = intval($year);
3427
        $week = intval($week);
3428
        $day = intval($day);
3429
        // 1. creating the SQL statement for getting the personal agenda items in MONTH view
3430
3431
        $current_access_url_id = api_get_current_access_url_id();
3432
3433
        if ($type == "month_view" or $type == "") {
3434
            // We are in month view
3435
            $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";
3436
        }
3437
        // 2. creating the SQL statement for getting the personal agenda items in WEEK view
3438
        if ($type == "week_view") { // we are in week view
3439
            $start_end_day_of_week = self::calculate_start_end_of_week(
3440
                $week,
3441
                $year
3442
            );
3443
            $start_day = $start_end_day_of_week['start']['day'];
3444
            $start_month = $start_end_day_of_week['start']['month'];
3445
            $start_year = $start_end_day_of_week['start']['year'];
3446
            $end_day = $start_end_day_of_week['end']['day'];
3447
            $end_month = $start_end_day_of_week['end']['month'];
3448
            $end_year = $start_end_day_of_week['end']['year'];
3449
            // in sql statements you have to use year-month-day for date calculations
3450
            $start_filter = $start_year."-".$start_month."-".$start_day." 00:00:00";
3451
            $start_filter = api_get_utc_datetime($start_filter);
3452
3453
            $end_filter = $end_year."-".$end_month."-".$end_day." 23:59:59";
3454
            $end_filter = api_get_utc_datetime($end_filter);
3455
            $sql = " SELECT * FROM ".$tbl_global_agenda." WHERE start_date>='".$start_filter."' AND start_date<='".$end_filter."' AND  access_url_id = $current_access_url_id ";
3456
        }
3457
        // 3. creating the SQL statement for getting the personal agenda items in DAY view
3458
        if ($type == "day_view") { // we are in day view
3459
            // we could use mysql date() function but this is only available from 4.1 and higher
3460
            $start_filter = $year."-".$month."-".$day." 00:00:00";
3461
            $start_filter = api_get_utc_datetime($start_filter);
3462
3463
            $end_filter = $year."-".$month."-".$day." 23:59:59";
3464
            $end_filter = api_get_utc_datetime($end_filter);
3465
            $sql = " SELECT * FROM ".$tbl_global_agenda." WHERE start_date>='".$start_filter."' AND start_date<='".$end_filter."'  AND  access_url_id = $current_access_url_id";
3466
        }
3467
3468
        $result = Database::query($sql);
3469
3470
        while ($item = Database::fetch_array($result)) {
3471
            if (!empty($item['start_date'])) {
3472
                $item['start_date'] = api_get_local_time($item['start_date']);
3473
                $item['start_date_tms'] = api_strtotime($item['start_date']);
3474
            }
3475
            if (!empty($item['end_date'])) {
3476
                $item['end_date'] = api_get_local_time($item['end_date']);
3477
            }
3478
3479
            // we break the date field in the database into a date and a time part
3480
            $agenda_db_date = explode(" ", $item['start_date']);
3481
            $date = $agenda_db_date[0];
3482
            $time = $agenda_db_date[1];
3483
            // we divide the date part into a day, a month and a year
3484
            $agendadate = explode("-", $date);
3485
            $year = intval($agendadate[0]);
3486
            $month = intval($agendadate[1]);
3487
            $day = intval($agendadate[2]);
3488
            // we divide the time part into hour, minutes, seconds
3489
            $agendatime = explode(":", $time);
3490
            $hour = $agendatime[0];
3491
            $minute = $agendatime[1];
3492
            $second = $agendatime[2];
3493
3494
            if ($type == 'month_view') {
3495
                $item['calendar_type'] = 'global';
3496
                $agendaitems[$day][] = $item;
3497
                continue;
3498
            }
3499
3500
            $start_time = api_format_date(
3501
                $item['start_date'],
3502
                TIME_NO_SEC_FORMAT
3503
            );
3504
            $end_time = '';
3505
            if (!empty($item['end_date'])) {
3506
                $end_time = ' - '.api_format_date(
3507
                        $item['end_date'],
3508
                        DATE_TIME_FORMAT_LONG
3509
                    );
3510
            }
3511
3512
            // if the student has specified a course we a add a link to that course
3513
            if ($item['course'] != "") {
3514
                $url = api_get_path(
3515
                        WEB_CODE_PATH
3516
                    )."admin/agenda.php?cidReq=".urlencode(
3517
                        $item['course']
3518
                    )."&day=$day&month=$month&year=$year#$day"; // RH  //Patrick Cool: to highlight the relevant agenda item
3519
                $course_link = "<a href=\"$url\" title=\"".$item['course']."\">".$item['course']."</a>";
3520
            } else {
3521
                $course_link = "";
3522
            }
3523
            // Creating the array that will be returned. If we have week or month view we have an array with the date as the key
3524
            // if we have a day_view we use a half hour as index => key 33 = 16h30
3525
            if ($type !== "day_view") {
3526
                // This is the array construction for the WEEK or MONTH view
3527
                //Display the Agenda global in the tab agenda (administrator)
3528
                $agendaitems[$day] .= "<i>$start_time $end_time</i>&nbsp;-&nbsp;";
3529
                $agendaitems[$day] .= "<b>".get_lang('GlobalEvent')."</b>";
3530
                $agendaitems[$day] .= "<div>".$item['title']."</div><br>";
3531
            } else {
3532
                // this is the array construction for the DAY view
3533
                $halfhour = 2 * $agendatime['0'];
3534
                if ($agendatime['1'] >= '30') {
3535
                    $halfhour = $halfhour + 1;
3536
                }
3537
                if (!is_array($agendaitems[$halfhour])) {
3538
                    $content = $agendaitems[$halfhour];
3539
                }
3540
                $agendaitems[$halfhour] = $content."<div><i>$hour:$minute</i> <b>".get_lang(
3541
                        'GlobalEvent'
3542
                    ).":  </b>".$item['title']."</div>";
3543
            }
3544
        }
3545
3546
        return $agendaitems;
3547
    }
3548
3549
    /**
3550
     * This function retrieves all the personal agenda items and add them to the agenda items found by the other
3551
     * functions.
3552
     */
3553
    public static function get_personal_agenda_items(
3554
        $user_id,
3555
        $agendaitems,
3556
        $day = "",
3557
        $month = "",
3558
        $year = "",
3559
        $week = "",
3560
        $type
3561
    ) {
3562
        $tbl_personal_agenda = Database::get_main_table(TABLE_PERSONAL_AGENDA);
3563
        $user_id = intval($user_id);
3564
3565
        // 1. creating the SQL statement for getting the personal agenda items in MONTH view
3566
        if ($type == "month_view" or $type == "") {
3567
            // we are in month view
3568
            $sql = "SELECT * FROM ".$tbl_personal_agenda." WHERE user='".$user_id."' and MONTH(date)='".$month."' AND YEAR(date) = '".$year."'  ORDER BY date ASC";
3569
        }
3570
3571
        // 2. creating the SQL statement for getting the personal agenda items in WEEK view
3572
        // we are in week view
3573
        if ($type == "week_view") {
3574
            $start_end_day_of_week = self::calculate_start_end_of_week(
3575
                $week,
3576
                $year
3577
            );
3578
            $start_day = $start_end_day_of_week['start']['day'];
3579
            $start_month = $start_end_day_of_week['start']['month'];
3580
            $start_year = $start_end_day_of_week['start']['year'];
3581
            $end_day = $start_end_day_of_week['end']['day'];
3582
            $end_month = $start_end_day_of_week['end']['month'];
3583
            $end_year = $start_end_day_of_week['end']['year'];
3584
            // in sql statements you have to use year-month-day for date calculations
3585
            $start_filter = $start_year."-".$start_month."-".$start_day." 00:00:00";
3586
            $start_filter = api_get_utc_datetime($start_filter);
3587
            $end_filter = $end_year."-".$end_month."-".$end_day." 23:59:59";
3588
            $end_filter = api_get_utc_datetime($end_filter);
3589
            $sql = " SELECT * FROM ".$tbl_personal_agenda." WHERE user='".$user_id."' AND date>='".$start_filter."' AND date<='".$end_filter."'";
3590
        }
3591
        // 3. creating the SQL statement for getting the personal agenda items in DAY view
3592
        if ($type == "day_view") {
3593
            // we are in day view
3594
            // we could use mysql date() function but this is only available from 4.1 and higher
3595
            $start_filter = $year."-".$month."-".$day." 00:00:00";
3596
            $start_filter = api_get_utc_datetime($start_filter);
3597
            $end_filter = $year."-".$month."-".$day." 23:59:59";
3598
            $end_filter = api_get_utc_datetime($end_filter);
3599
            $sql = " SELECT * FROM ".$tbl_personal_agenda." WHERE user='".$user_id."' AND date>='".$start_filter."' AND date<='".$end_filter."'";
3600
        }
3601
3602
        $result = Database::query($sql);
3603
        while ($item = Database::fetch_array($result, 'ASSOC')) {
3604
            $time_minute = api_convert_and_format_date(
3605
                $item['date'],
3606
                TIME_NO_SEC_FORMAT
3607
            );
3608
            $item['date'] = api_get_local_time($item['date']);
3609
            $item['start_date_tms'] = api_strtotime($item['date']);
3610
            $item['content'] = $item['text'];
3611
3612
            // we break the date field in the database into a date and a time part
3613
            $agenda_db_date = explode(" ", $item['date']);
3614
            $date = $agenda_db_date[0];
3615
            $time = $agenda_db_date[1];
3616
            // we divide the date part into a day, a month and a year
3617
            $agendadate = explode("-", $item['date']);
3618
            $year = intval($agendadate[0]);
3619
            $month = intval($agendadate[1]);
3620
            $day = intval($agendadate[2]);
3621
            // we divide the time part into hour, minutes, seconds
3622
            $agendatime = explode(":", $time);
3623
3624
            $hour = $agendatime[0];
3625
            $minute = $agendatime[1];
3626
            $second = $agendatime[2];
3627
3628
            if ($type == 'month_view') {
3629
                $item['calendar_type'] = 'personal';
3630
                $item['start_date'] = $item['date'];
3631
                $agendaitems[$day][] = $item;
3632
                continue;
3633
            }
3634
3635
            // if the student has specified a course we a add a link to that course
3636
            if ($item['course'] != "") {
3637
                $url = api_get_path(
3638
                        WEB_CODE_PATH
3639
                    )."calendar/agenda.php?cidReq=".urlencode(
3640
                        $item['course']
3641
                    )."&day=$day&month=$month&year=$year#$day"; // RH  //Patrick Cool: to highlight the relevant agenda item
3642
                $course_link = "<a href=\"$url\" title=\"".$item['course']."\">".$item['course']."</a>";
3643
            } else {
3644
                $course_link = "";
3645
            }
3646
            // Creating the array that will be returned. If we have week or month view we have an array with the date as the key
3647
            // if we have a day_view we use a half hour as index => key 33 = 16h30
3648
            if ($type !== "day_view") {
3649
                // This is the array construction for the WEEK or MONTH view
3650
3651
                //Display events in agenda
3652
                $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 />";
3653
            } else {
3654
                // this is the array construction for the DAY view
3655
                $halfhour = 2 * $agendatime['0'];
3656
                if ($agendatime['1'] >= '30') {
3657
                    $halfhour = $halfhour + 1;
3658
                }
3659
3660
                //Display events by list
3661
                $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>";
3662
            }
3663
        }
3664
3665
        return $agendaitems;
3666
    }
3667
3668
    /**
3669
     * Show the monthcalender of the given month.
3670
     *
3671
     * @param    array    Agendaitems
3672
     * @param    int    Month number
3673
     * @param    int    Year number
3674
     * @param    array    Array of strings containing long week day names (deprecated, you can send an empty array
3675
     *                          instead)
3676
     * @param    string    The month name
3677
     */
3678
    public static function display_mymonthcalendar(
3679
        $user_id,
3680
        $agendaitems,
3681
        $month,
3682
        $year,
3683
        $weekdaynames = [],
3684
        $monthName,
3685
        $show_content = true
3686
    ) {
3687
        global $DaysShort, $course_path;
3688
        //Handle leap year
3689
        $numberofdays = [
3690
            0,
3691
            31,
3692
            28,
3693
            31,
3694
            30,
3695
            31,
3696
            30,
3697
            31,
3698
            31,
3699
            30,
3700
            31,
3701
            30,
3702
            31,
3703
        ];
3704
        if (($year % 400 == 0) or ($year % 4 == 0 and $year % 100 != 0)) {
3705
            $numberofdays[2] = 29;
3706
        }
3707
        //Get the first day of the month
3708
        $dayone = getdate(mktime(0, 0, 0, $month, 1, $year));
3709
        //Start the week on monday
3710
        $startdayofweek = $dayone['wday'] != 0 ? ($dayone['wday'] - 1) : 6;
3711
        $g_cc = (isset($_GET['courseCode']) ? $_GET['courseCode'] : '');
3712
3713
        $next_month = ($month == 1 ? 12 : $month - 1);
3714
        $prev_month = ($month == 12 ? 1 : $month + 1);
3715
3716
        $next_year = ($month == 1 ? $year - 1 : $year);
3717
        $prev_year = ($month == 12 ? $year + 1 : $year);
3718
3719
        if ($show_content) {
3720
            $back_url = Display::url(
3721
                get_lang('Previous'),
3722
                api_get_self()."?coursePath=".urlencode(
3723
                    $course_path
3724
                )."&courseCode=".Security::remove_XSS(
3725
                    $g_cc
3726
                )."&action=view&view=month&month=".$next_month."&year=".$next_year
3727
            );
3728
            $next_url = Display::url(
3729
                get_lang('Next'),
3730
                api_get_self()."?coursePath=".urlencode(
3731
                    $course_path
3732
                )."&courseCode=".Security::remove_XSS(
3733
                    $g_cc
3734
                )."&action=view&view=month&month=".$prev_month."&year=".$prev_year
3735
            );
3736
        } else {
3737
            $back_url = Display::url(
3738
                get_lang('Previous'),
3739
                '',
3740
                [
3741
                    'onclick' => "load_calendar('".$user_id."','".$next_month."', '".$next_year."'); ",
3742
                    'class' => 'btn ui-button ui-widget ui-state-default',
3743
                ]
3744
            );
3745
            $next_url = Display::url(
3746
                get_lang('Next'),
3747
                '',
3748
                [
3749
                    'onclick' => "load_calendar('".$user_id."','".$prev_month."', '".$prev_year."'); ",
3750
                    'class' => 'float-right btn ui-button ui-widget ui-state-default',
3751
                ]
3752
            );
3753
        }
3754
        $html = '';
3755
        $html .= '<div class="actions">';
3756
        $html .= '<div class="row">';
3757
        $html .= '<div class="col-md-4">'.$back_url.'</div>';
3758
        $html .= '<div class="col-md-4"><p class="agenda-title text-center">'.$monthName." ".$year.'</p></div>';
3759
        $html .= '<div class="col-md-4">'.$next_url.'</div>';
3760
        $html .= '</div>';
3761
        $html .= '</div>';
3762
        $html .= '<table id="agenda_list2" class="table table-bordered">';
3763
        $html .= '<tr>';
3764
        for ($ii = 1; $ii < 8; $ii++) {
3765
            $html .= '<td class="weekdays">'.$DaysShort[$ii % 7].'</td>';
3766
        }
3767
        $html .= '</tr>';
3768
3769
        $curday = -1;
3770
        $today = getdate();
3771
        while ($curday <= $numberofdays[$month]) {
3772
            $html .= "<tr>";
3773
            for ($ii = 0; $ii < 7; $ii++) {
3774
                if (($curday == -1) && ($ii == $startdayofweek)) {
3775
                    $curday = 1;
3776
                }
3777
                if (($curday > 0) && ($curday <= $numberofdays[$month])) {
3778
                    $bgcolor = $class = 'class="days_week"';
3779
                    $dayheader = Display::div(
3780
                        $curday,
3781
                        ['class' => 'agenda_day']
3782
                    );
3783
                    if (($curday == $today['mday']) && ($year == $today['year']) && ($month == $today['mon'])) {
3784
                        $class = "class=\"days_today\" style=\"width:10%;\"";
3785
                    }
3786
3787
                    $html .= "<td ".$class.">".$dayheader;
3788
3789
                    if (!empty($agendaitems[$curday])) {
3790
                        $items = $agendaitems[$curday];
3791
                        $items = msort($items, 'start_date_tms');
3792
3793
                        foreach ($items as $value) {
3794
                            $value['title'] = Security::remove_XSS(
3795
                                $value['title']
3796
                            );
3797
                            $start_time = api_format_date(
3798
                                $value['start_date'],
3799
                                TIME_NO_SEC_FORMAT
3800
                            );
3801
                            $end_time = '';
3802
3803
                            if (!empty($value['end_date'])) {
3804
                                $end_time = '-&nbsp;<i>'.api_format_date(
3805
                                        $value['end_date'],
3806
                                        DATE_TIME_FORMAT_LONG
3807
                                    ).'</i>';
3808
                            }
3809
                            $complete_time = '<i>'.api_format_date(
3810
                                    $value['start_date'],
3811
                                    DATE_TIME_FORMAT_LONG
3812
                                ).'</i>&nbsp;'.$end_time;
3813
                            $time = '<i>'.$start_time.'</i>';
3814
3815
                            switch ($value['calendar_type']) {
3816
                                case 'personal':
3817
                                    $bg_color = '#D0E7F4';
3818
                                    $icon = Display::return_icon(
3819
                                        'user.png',
3820
                                        get_lang('MyAgenda'),
3821
                                        [],
3822
                                        ICON_SIZE_SMALL
3823
                                    );
3824
                                    break;
3825
                                case 'global':
3826
                                    $bg_color = '#FFBC89';
3827
                                    $icon = Display::return_icon(
3828
                                        'view_remove.png',
3829
                                        get_lang('GlobalEvent'),
3830
                                        [],
3831
                                        ICON_SIZE_SMALL
3832
                                    );
3833
                                    break;
3834
                                case 'course':
3835
                                    $bg_color = '#CAFFAA';
3836
                                    $icon_name = 'course.png';
3837
                                    if (!empty($value['session_id'])) {
3838
                                        $icon_name = 'session.png';
3839
                                    }
3840
                                    if ($show_content) {
3841
                                        $icon = Display::url(
3842
                                            Display::return_icon(
3843
                                                $icon_name,
3844
                                                $value['course_name'].' '.get_lang(
3845
                                                    'Course'
3846
                                                ),
3847
                                                [],
3848
                                                ICON_SIZE_SMALL
3849
                                            ),
3850
                                            $value['url']
3851
                                        );
3852
                                    } else {
3853
                                        $icon = Display::return_icon(
3854
                                            $icon_name,
3855
                                            $value['course_name'].' '.get_lang(
3856
                                                'Course'
3857
                                            ),
3858
                                            [],
3859
                                            ICON_SIZE_SMALL
3860
                                        );
3861
                                    }
3862
                                    break;
3863
                                default:
3864
                                    break;
3865
                            }
3866
3867
                            $result = '<div class="rounded_div_agenda" style="background-color:'.$bg_color.';">';
3868
3869
                            if ($show_content) {
3870
                                //Setting a personal event to green
3871
                                $icon = Display::div(
3872
                                    $icon,
3873
                                    ['style' => 'float:right']
3874
                                );
3875
3876
                                $link = $value['calendar_type'].'_'.$value['id'].'_'.$value['course_id'].'_'.$value['session_id'];
3877
3878
                                //Link to bubble
3879
                                $url = Display::url(
3880
                                    cut($value['title'], 40),
3881
                                    '#',
3882
                                    ['id' => $link, 'class' => 'opener']
3883
                                );
3884
                                $result .= $time.' '.$icon.' '.Display::div(
3885
                                        $url
3886
                                    );
3887
3888
                                //Hidden content
3889
                                $content = Display::div(
3890
                                    $icon.Display::tag(
3891
                                        'h2',
3892
                                        $value['course_name']
3893
                                    ).'<hr />'.Display::tag(
3894
                                        'h3',
3895
                                        $value['title']
3896
                                    ).$complete_time.'<hr />'.Security::remove_XSS(
3897
                                        $value['content']
3898
                                    )
3899
                                );
3900
3901
                                //Main div
3902
                                $result .= Display::div(
3903
                                    $content,
3904
                                    [
3905
                                        'id' => 'main_'.$link,
3906
                                        'class' => 'dialog',
3907
                                        'style' => 'display:none',
3908
                                    ]
3909
                                );
3910
                                $result .= '</div>';
3911
                                $html .= $result;
3912
                            } else {
3913
                                $html .= $result .= $icon.'</div>';
3914
                            }
3915
                        }
3916
                    }
3917
                    $html .= "</td>";
3918
                    $curday++;
3919
                } else {
3920
                    $html .= "<td></td>";
3921
                }
3922
            }
3923
            $html .= "</tr>";
3924
        }
3925
        $html .= "</table>";
3926
        echo $html;
3927
    }
3928
3929
    /**
3930
     * Get personal agenda items between two dates (=all events from all registered courses).
3931
     *
3932
     * @param int $user_id user ID of the user
3933
     * @param    string    Optional start date in datetime format (if no start date is given, uses today)
3934
     * @param    string    Optional end date in datetime format (if no date is given, uses one year from now)
3935
     *
3936
     * @return array array of events ordered by start date, in
3937
     *               [0]('datestart','dateend','title'),[1]('datestart','dateend','title','link','coursetitle') format,
3938
     *               where datestart and dateend are in yyyyMMddhhmmss format
3939
     *
3940
     * @deprecated use agenda events
3941
     */
3942
    public static function get_personal_agenda_items_between_dates(
3943
        $user_id,
3944
        $date_start = '',
3945
        $date_end = ''
3946
    ) {
3947
        $items = [];
3948
        if ($user_id != strval(intval($user_id))) {
3949
            return $items;
3950
        }
3951
        if (empty($date_start)) {
3952
            $date_start = date('Y-m-d H:i:s');
3953
        }
3954
        if (empty($date_end)) {
3955
            $date_end = date(
3956
                'Y-m-d H:i:s',
3957
                mktime(0, 0, 0, date("m"), date("d"), date("Y") + 1)
3958
            );
3959
        }
3960
        $expr = '/\d{4}-\d{2}-\d{2}\ \d{2}:\d{2}:\d{2}/';
3961
        if (!preg_match($expr, $date_start)) {
3962
            return $items;
3963
        }
3964
        if (!preg_match($expr, $date_end)) {
3965
            return $items;
3966
        }
3967
3968
        // get agenda-items for every course
3969
        $courses = api_get_user_courses($user_id, false);
3970
        foreach ($courses as $id => $course) {
3971
            $c = api_get_course_info_by_id($course['real_id']);
3972
            //databases of the courses
3973
            $t_a = Database::get_course_table(TABLE_AGENDA, $course['db']);
3974
            $t_ip = Database::get_course_table(
3975
                TABLE_ITEM_PROPERTY,
3976
                $course['db']
3977
            );
3978
            // get the groups to which the user belong
3979
            $group_memberships = GroupManager:: get_group_ids(
3980
                $course['db'],
3981
                $user_id
3982
            );
3983
            // if the user is administrator of that course we show all the agenda items
3984
            if ($course['status'] == '1') {
3985
                //echo "course admin";
3986
                $sqlquery = "SELECT ".
3987
                    " DISTINCT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref ".
3988
                    " FROM ".$t_a." agenda, ".
3989
                    $t_ip." ip ".
3990
                    " WHERE agenda.id = ip.ref ".
3991
                    " AND agenda.start_date>='$date_start' ".
3992
                    " AND agenda.end_date<='$date_end' ".
3993
                    " AND ip.tool='".TOOL_CALENDAR_EVENT."' ".
3994
                    " AND ip.visibility='1' ".
3995
                    " GROUP BY agenda.id ".
3996
                    " ORDER BY start_date ";
3997
            } else {
3998
                // if the user is not an administrator of that course, then...
3999
                if (is_array($group_memberships) && count(
4000
                        $group_memberships
4001
                    ) > 0
4002
                ) {
4003
                    $sqlquery = "SELECT ".
4004
                        "DISTINCT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref ".
4005
                        " FROM ".$t_a." agenda, ".
4006
                        $t_ip." ip ".
4007
                        " WHERE agenda.id = ip.ref ".
4008
                        " AND agenda.start_date>='$date_start' ".
4009
                        " AND agenda.end_date<='$date_end' ".
4010
                        " AND ip.tool='".TOOL_CALENDAR_EVENT."' ".
4011
                        " AND	( ip.to_user_id='".$user_id."' OR (ip.to_group_id IS NULL OR ip.to_group_id IN (0, ".implode(
4012
                            ", ",
4013
                            $group_memberships
4014
                        ).")) ) ".
4015
                        " AND ip.visibility='1' ".
4016
                        " ORDER BY start_date ";
4017
                } else {
4018
                    $sqlquery = "SELECT ".
4019
                        "DISTINCT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref ".
4020
                        " FROM ".$t_a." agenda, ".
4021
                        $t_ip." ip ".
4022
                        " WHERE agenda.id = ip.ref ".
4023
                        " AND agenda.start_date>='$date_start' ".
4024
                        " AND agenda.end_date<='$date_end' ".
4025
                        " AND ip.tool='".TOOL_CALENDAR_EVENT."' ".
4026
                        " AND ( ip.to_user_id='".$user_id."' OR ip.to_group_id='0' OR ip.to_group_id IS NULL) ".
4027
                        " AND ip.visibility='1' ".
4028
                        " ORDER BY start_date ";
4029
                }
4030
            }
4031
4032
            $result = Database::query($sqlquery);
4033
            while ($item = Database::fetch_array($result)) {
4034
                $agendaday = date("j", strtotime($item['start_date']));
4035
                $month = date("n", strtotime($item['start_date']));
4036
                $year = date("Y", strtotime($item['start_date']));
4037
                $URL = api_get_path(
4038
                        WEB_PATH
4039
                    )."main/calendar/agenda.php?cidReq=".urlencode(
4040
                        $course["code"]
4041
                    )."&day=$agendaday&month=$month&year=$year#$agendaday";
4042
                list($year, $month, $day, $hour, $min, $sec) = explode(
4043
                    '[-: ]',
4044
                    $item['start_date']
4045
                );
4046
                $start_date = $year.$month.$day.$hour.$min;
4047
                list($year, $month, $day, $hour, $min, $sec) = explode(
4048
                    '[-: ]',
4049
                    $item['end_date']
4050
                );
4051
                $end_date = $year.$month.$day.$hour.$min;
4052
4053
                $items[] = [
4054
                    'datestart' => $start_date,
4055
                    'dateend' => $end_date,
4056
                    'title' => $item['title'],
4057
                    'link' => $URL,
4058
                    'coursetitle' => $c['name'],
4059
                ];
4060
            }
4061
        }
4062
4063
        return $items;
4064
    }
4065
4066
    /**
4067
     * This function calculates the startdate of the week (monday)
4068
     * and the enddate of the week (sunday)
4069
     * and returns it as an array.
4070
     */
4071
    public static function calculate_start_end_of_week($week_number, $year)
4072
    {
4073
        // determine the start and end date
4074
        // step 1: we calculate a timestamp for a day in this week
4075
        $random_day_in_week = mktime(
4076
                0,
4077
                0,
4078
                0,
4079
                1,
4080
                1,
4081
                $year
4082
            ) + ($week_number) * (7 * 24 * 60 * 60); // we calculate a random day in this week
4083
        // step 2: we which day this is (0=sunday, 1=monday, ...)
4084
        $number_day_in_week = date('w', $random_day_in_week);
4085
        // step 3: we calculate the timestamp of the monday of the week we are in
4086
        $start_timestamp = $random_day_in_week - (($number_day_in_week - 1) * 24 * 60 * 60);
4087
        // step 4: we calculate the timestamp of the sunday of the week we are in
4088
        $end_timestamp = $random_day_in_week + ((7 - $number_day_in_week + 1) * 24 * 60 * 60) - 3600;
4089
        // step 5: calculating the start_day, end_day, start_month, end_month, start_year, end_year
4090
        $start_day = date('j', $start_timestamp);
4091
        $start_month = date('n', $start_timestamp);
4092
        $start_year = date('Y', $start_timestamp);
4093
        $end_day = date('j', $end_timestamp);
4094
        $end_month = date('n', $end_timestamp);
4095
        $end_year = date('Y', $end_timestamp);
4096
        $start_end_array['start']['day'] = $start_day;
4097
        $start_end_array['start']['month'] = $start_month;
4098
        $start_end_array['start']['year'] = $start_year;
4099
        $start_end_array['end']['day'] = $end_day;
4100
        $start_end_array['end']['month'] = $end_month;
4101
        $start_end_array['end']['year'] = $end_year;
4102
4103
        return $start_end_array;
4104
    }
4105
4106
    /**
4107
     * @return bool
4108
     */
4109
    public function getIsAllowedToEdit()
4110
    {
4111
        return $this->isAllowedToEdit;
4112
    }
4113
4114
    /**
4115
     * @param bool $isAllowedToEdit
4116
     */
4117
    public function setIsAllowedToEdit($isAllowedToEdit)
4118
    {
4119
        $this->isAllowedToEdit = $isAllowedToEdit;
4120
    }
4121
4122
    /**
4123
     * Format needed for the Fullcalendar js lib.
4124
     *
4125
     * @param string $utcTime
4126
     *
4127
     * @return bool|string
4128
     */
4129
    public function formatEventDate($utcTime)
4130
    {
4131
        $utcTimeZone = new DateTimeZone('UTC');
4132
        $platformTimeZone = new DateTimeZone(api_get_timezone());
4133
4134
        $eventDate = new DateTime($utcTime, $utcTimeZone);
4135
        $eventDate->setTimezone($platformTimeZone);
4136
4137
        return $eventDate->format(DateTime::ISO8601);
4138
    }
4139
}
4140