Passed
Push — master ( ad6737...b4c9af )
by Julito
10:24
created

Agenda::hasChildren()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 18
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

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