Passed
Push — master ( de4742...03bb22 )
by Julito
08:04
created

Agenda::getIsAllowedToEdit()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
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\SysCalendar;
7
use Chamilo\CoreBundle\Framework\Container;
8
use Chamilo\CourseBundle\Entity\CCalendarEvent;
9
use Chamilo\CourseBundle\Entity\CCalendarEventAttachment;
10
use Chamilo\CourseBundle\Entity\CGroup;
11
use Chamilo\CoreBundle\Entity\Course;
12
use Symfony\Component\HttpFoundation\File\UploadedFile;
13
14
/**
15
 * Class Agenda.
16
 *
17
 * @author: Julio Montoya <[email protected]>
18
 */
19
class Agenda
20
{
21
    public $events = [];
22
    /** @var string Current type */
23
    public $type = 'personal';
24
    public $types = ['personal', 'admin', 'course'];
25
    public $sessionId = 0;
26
    public $senderId;
27
    /** @var array */
28
    public $course;
29
    /** @var string */
30
    public $comment;
31
    public $eventStudentPublicationColor;
32
    /** @var array */
33
    private $sessionInfo;
34
    /** @var bool */
35
    private $isAllowedToEdit;
36
37
    private $tbl_global_agenda;
38
    private $tbl_personal_agenda;
39
    private $tbl_course_agenda;
40
    private $table_repeat;
41
42
    /**
43
     * Constructor.
44
     *
45
     * @param string $type
46
     * @param int    $senderId  Optional The user sender ID
47
     * @param int    $courseId  Optional. The course ID
48
     * @param int    $sessionId Optional The session ID
49
     */
50
    public function __construct(
51
        $type,
52
        $senderId = 0,
53
        $courseId = 0,
54
        $sessionId = 0
55
    ) {
56
        // Table definitions
57
        $this->tbl_global_agenda = Database::get_main_table(TABLE_MAIN_SYSTEM_CALENDAR);
58
        $this->tbl_personal_agenda = Database::get_main_table(TABLE_PERSONAL_AGENDA);
59
        $this->tbl_course_agenda = Database::get_course_table(TABLE_AGENDA);
60
        $this->table_repeat = Database::get_course_table(TABLE_AGENDA_REPEAT);
61
62
        $this->setType($type);
63
        $this->setSenderId($senderId ?: api_get_user_id());
64
        $isAllowToEdit = false;
65
66
        switch ($type) {
67
            case 'course':
68
                $sessionId = $sessionId ?: api_get_session_id();
69
                $sessionInfo = api_get_session_info($sessionId);
70
                $this->setSessionId($sessionId);
71
                $this->setSessionInfo($sessionInfo);
72
73
                // Setting the course object if we are in a course
74
                $courseInfo = api_get_course_info_by_id($courseId);
75
                if (!empty($courseInfo)) {
76
                    $this->set_course($courseInfo);
77
                }
78
79
                // Check if teacher/admin rights.
80
                $isAllowToEdit = api_is_allowed_to_edit(false, true);
81
                // Check course setting.
82
                if ('1' === api_get_course_setting('allow_user_edit_agenda')
83
                    && api_is_allowed_in_course()
84
                ) {
85
                    $isAllowToEdit = true;
86
                }
87
88
                $group = api_get_group_entity();
89
                if (!empty($group)) {
90
                    $userHasAccess = GroupManager::userHasAccess(
91
                        api_get_user_id(),
92
                        $group,
93
                        GroupManager::GROUP_TOOL_CALENDAR
94
                    );
95
                    $isTutor = GroupManager::isTutorOfGroup(
96
                        api_get_user_id(),
97
                        $group
98
                    );
99
100
                    $isGroupAccess = $userHasAccess || $isTutor;
101
                    $isAllowToEdit = false;
102
                    if ($isGroupAccess) {
103
                        $isAllowToEdit = true;
104
                    }
105
                }
106
107
                if (!empty($sessionId)) {
108
                    $allowDhrToEdit = api_get_configuration_value('allow_agenda_edit_for_hrm');
109
                    if ($allowDhrToEdit) {
110
                        $isHrm = SessionManager::isUserSubscribedAsHRM($sessionId, api_get_user_id());
111
                        if ($isHrm) {
112
                            $isAllowToEdit = true;
113
                        }
114
                    }
115
                }
116
                break;
117
            case 'admin':
118
                $isAllowToEdit = api_is_platform_admin();
119
                break;
120
            case 'personal':
121
                $isAllowToEdit = !api_is_anonymous();
122
                break;
123
        }
124
125
        $this->setIsAllowedToEdit($isAllowToEdit);
126
        $this->events = [];
127
        $agendaColors = array_merge(
128
            [
129
                'platform' => 'red', //red
130
                'course' => '#458B00', //green
131
                'group' => '#A0522D', //siena
132
                'session' => '#00496D', // kind of green
133
                'other_session' => '#999', // kind of green
134
                'personal' => 'steel blue', //steel blue
135
                'student_publication' => '#FF8C00', //DarkOrange
136
            ],
137
            api_get_configuration_value('agenda_colors') ?: []
138
        );
139
140
        // Event colors
141
        $this->event_platform_color = $agendaColors['platform'];
142
        $this->event_course_color = $agendaColors['course'];
143
        $this->event_group_color = $agendaColors['group'];
144
        $this->event_session_color = $agendaColors['session'];
145
        $this->eventOtherSessionColor = $agendaColors['other_session'];
146
        $this->event_personal_color = $agendaColors['personal'];
147
        $this->eventStudentPublicationColor = $agendaColors['student_publication'];
148
    }
149
150
    /**
151
     * @param int $senderId
152
     */
153
    public function setSenderId($senderId)
154
    {
155
        $this->senderId = (int) $senderId;
156
    }
157
158
    /**
159
     * @return int
160
     */
161
    public function getSenderId()
162
    {
163
        return $this->senderId;
164
    }
165
166
    /**
167
     * @param string $type can be 'personal', 'admin'  or  'course'
168
     */
169
    public function setType($type)
170
    {
171
        $typeList = $this->getTypes();
172
        if (in_array($type, $typeList)) {
173
            $this->type = $type;
174
        }
175
    }
176
177
    /**
178
     * Returns the type previously set (and filtered) through setType
179
     * If setType() was not called, then type defaults to "personal" as
180
     * set in the class definition.
181
     */
182
    public function getType()
183
    {
184
        if (isset($this->type)) {
185
            return $this->type;
186
        }
187
    }
188
189
    /**
190
     * @param int $id
191
     */
192
    public function setSessionId($id)
193
    {
194
        $this->sessionId = (int) $id;
195
    }
196
197
    /**
198
     * @param array $sessionInfo
199
     */
200
    public function setSessionInfo($sessionInfo)
201
    {
202
        $this->sessionInfo = $sessionInfo;
203
    }
204
205
    /**
206
     * @return int $id
207
     */
208
    public function getSessionId()
209
    {
210
        return $this->sessionId;
211
    }
212
213
    /**
214
     * @param array $courseInfo
215
     */
216
    public function set_course($courseInfo)
217
    {
218
        $this->course = $courseInfo;
219
    }
220
221
    /**
222
     * @return array
223
     */
224
    public function getTypes()
225
    {
226
        return $this->types;
227
    }
228
229
    /**
230
     * Adds an event to the calendar.
231
     *
232
     * @param string         $start                 datetime format: 2012-06-14 09:00:00 in local time
233
     * @param string         $end                   datetime format: 2012-06-14 09:00:00 in local time
234
     * @param string         $allDay                (true, false)
235
     * @param string         $title
236
     * @param string         $content
237
     * @param array          $usersToSend           array('everyone') or a list of user/group ids
238
     * @param bool           $addAsAnnouncement     event as a *course* announcement
239
     * @param int            $parentEventId
240
     * @param UploadedFile[] $attachmentArray       array of $_FILES['']
241
     * @param array          $attachmentCommentList
242
     * @param string         $eventComment
243
     * @param string         $color
244
     *
245
     * @return int
246
     */
247
    public function addEvent(
248
        $start,
249
        $end,
250
        $allDay,
251
        $title,
252
        $content,
253
        $usersToSend = [],
254
        $addAsAnnouncement = false,
255
        $parentEventId = 0,
256
        $attachmentArray = [],
257
        $attachmentCommentList = [],
258
        $eventComment = '',
259
        $color = ''
260
    ) {
261
        $start = api_get_utc_datetime($start, false, true);
262
        $end = api_get_utc_datetime($end, false, true);
263
        $allDay = isset($allDay) && 'true' === $allDay ? 1 : 0;
264
        $id = null;
265
266
        $em = Database::getManager();
267
        switch ($this->type) {
268
            case 'personal':
269
                $event = new PersonalAgenda();
270
                $event
271
                    ->setTitle($title)
272
                    ->setText($content)
273
                    ->setDate($start)
274
                    ->setEndDate($end)
275
                    ->setAllDay($allDay)
276
                    ->setColor($color)
277
                    ->setUser(api_get_user_entity())
278
                ;
279
                $em->persist($event);
280
                $em->flush();
281
                $id = $event->getId();
282
                break;
283
            case 'course':
284
                $sessionId = $this->getSessionId();
285
                $sessionEntity = api_get_session_entity($sessionId);
286
                $courseEntity = api_get_course_entity($this->course['real_id']);
287
                $groupEntity = api_get_group_entity(api_get_group_id());
288
289
                $event = new CCalendarEvent();
290
                $event
291
                    ->setTitle($title)
292
                    ->setContent($content)
293
                    ->setStartDate($start)
294
                    ->setEndDate($end)
295
                    ->setAllDay($allDay)
296
                    ->setColor($color)
297
                    ->setComment($eventComment)
298
                ;
299
300
                if (!empty($parentEventId)) {
301
                    $repo = Container::getCalendarEventRepository();
302
                    $parentEvent = $repo->find($parentEventId);
303
                    $event->setParentEvent($parentEvent);
304
                }
305
306
                $event->setParent($courseEntity);
307
308
                if (!empty($usersToSend)) {
309
                    $sendTo = $this->parseSendToArray($usersToSend);
310
                    if ($sendTo['everyone']) {
311
                        $event->addCourseLink($courseEntity, $sessionEntity, $groupEntity);
312
                    } else {
313
                        // Storing the selected groups
314
                        if (!empty($sendTo['groups'])) {
315
                            foreach ($sendTo['groups'] as $group) {
316
                                $groupInfo = null;
317
                                if ($group) {
318
                                    $groupInfo = api_get_group_entity($group);
319
                                    $event->addCourseLink($courseEntity, $sessionEntity, $groupInfo);
320
                                }
321
                            }
322
                        }
323
324
                        // storing the selected users
325
                        if (!empty($sendTo['users'])) {
326
                            foreach ($sendTo['users'] as $userId) {
327
                                $event->addUserLink(
328
                                    api_get_user_entity($userId),
329
                                    $courseEntity,
330
                                    $sessionEntity,
331
                                    $groupEntity
332
                                );
333
                            }
334
                        }
335
                    }
336
                }
337
338
                $em->persist($event);
339
                $em->flush();
340
                $id = $event->getIid();
341
342
                if ($id) {
343
                    // Add announcement.
344
                    if ($addAsAnnouncement) {
345
                        $this->storeAgendaEventAsAnnouncement($event, $usersToSend);
346
                    }
347
348
                    // Add attachment.
349
                    if (!empty($attachmentArray)) {
350
                        $counter = 0;
351
                        foreach ($attachmentArray as $attachmentItem) {
352
                            $this->addAttachment(
353
                                $event,
354
                                $attachmentItem,
355
                                $attachmentCommentList[$counter],
356
                                $this->course
357
                            );
358
                            $counter++;
359
                        }
360
                    }
361
                }
362
                break;
363
            case 'admin':
364
                if (api_is_platform_admin()) {
365
                    $event = new SysCalendar();
366
                    $event
367
                        ->setTitle($title)
368
                        ->setContent($content)
369
                        ->setStartDate($start)
370
                        ->setEndDate($end)
371
                        ->setAllDay($allDay)
372
                        ->setUrl(api_get_url_entity())
373
                    ;
374
                    $em->persist($event);
375
                    $em->flush();
376
                    $id = $event->getId();
377
                }
378
                break;
379
        }
380
381
        return $id;
382
    }
383
384
    /**
385
     * @param string $type
386
     * @param string $startEvent      in UTC
387
     * @param string $endEvent        in UTC
388
     * @param string $repeatUntilDate in UTC
389
     *
390
     * @throws Exception
391
     *
392
     * @return array
393
     */
394
    public function generateDatesByType($type, $startEvent, $endEvent, $repeatUntilDate)
395
    {
396
        $continue = true;
397
        $repeatUntilDate = new DateTime($repeatUntilDate, new DateTimeZone('UTC'));
398
        $loopMax = 365;
399
        $counter = 0;
400
        $list = [];
401
402
        switch ($type) {
403
            case 'daily':
404
                $interval = 'P1D';
405
                break;
406
            case 'weekly':
407
                $interval = 'P1W';
408
                break;
409
            case 'monthlyByDate':
410
                $interval = 'P1M';
411
                break;
412
            case 'monthlyByDay':
413
            case 'monthlyByDayR':
414
                // not yet implemented
415
                break;
416
            case 'yearly':
417
                $interval = 'P1Y';
418
                break;
419
        }
420
421
        if (empty($interval)) {
422
            return [];
423
        }
424
        $timeZone = api_get_timezone();
425
426
        while ($continue) {
427
            $startDate = new DateTime($startEvent, new DateTimeZone('UTC'));
428
            $endDate = new DateTime($endEvent, new DateTimeZone('UTC'));
429
430
            $startDate->add(new DateInterval($interval));
431
            $endDate->add(new DateInterval($interval));
432
433
            $newStartDate = $startDate->format('Y-m-d H:i:s');
434
            $newEndDate = $endDate->format('Y-m-d H:i:s');
435
436
            $startEvent = $newStartDate;
437
            $endEvent = $newEndDate;
438
439
            if ($endDate > $repeatUntilDate) {
440
                break;
441
            }
442
443
            // @todo remove comment code
444
            $startDateInLocal = new DateTime($newStartDate, new DateTimeZone($timeZone));
445
            if (0 == $startDateInLocal->format('I')) {
446
                // Is saving time? Then fix UTC time to add time
447
                $seconds = $startDateInLocal->getOffset();
448
                $startDate->add(new DateInterval("PT".$seconds."S"));
449
                $startDateFixed = $startDate->format('Y-m-d H:i:s');
450
                $startDateInLocalFixed = new DateTime($startDateFixed, new DateTimeZone($timeZone));
451
                $newStartDate = $startDateInLocalFixed->format('Y-m-d H:i:s');
452
            }
453
454
            $endDateInLocal = new DateTime($newEndDate, new DateTimeZone($timeZone));
455
            if (0 == $endDateInLocal->format('I')) {
456
                // Is saving time? Then fix UTC time to add time
457
                $seconds = $endDateInLocal->getOffset();
458
                $endDate->add(new DateInterval("PT".$seconds."S"));
459
                $endDateFixed = $endDate->format('Y-m-d H:i:s');
460
                $endDateInLocalFixed = new DateTime($endDateFixed, new DateTimeZone($timeZone));
461
                $newEndDate = $endDateInLocalFixed->format('Y-m-d H:i:s');
462
            }
463
            $list[] = ['start' => $newStartDate, 'end' => $newEndDate, 'i' => $startDateInLocal->format('I')];
464
            $counter++;
465
466
            // just in case stop if more than $loopMax
467
            if ($counter > $loopMax) {
468
                break;
469
            }
470
        }
471
472
        return $list;
473
    }
474
475
    /**
476
     * @param int    $eventId
477
     * @param string $type
478
     * @param string $end     in UTC
479
     * @param array  $sentTo
480
     *
481
     * @return bool
482
     */
483
    public function addRepeatedItem($eventId, $type, $end, $sentTo = [])
484
    {
485
        $t_agenda = Database::get_course_table(TABLE_AGENDA);
486
        $t_agenda_r = Database::get_course_table(TABLE_AGENDA_REPEAT);
487
488
        if (empty($this->course)) {
489
            return false;
490
        }
491
492
        $eventId = (int) $eventId;
493
494
        $sql = "SELECT title, content, start_date, end_date, all_day
495
                FROM $t_agenda
496
                WHERE iid = $eventId";
497
        $res = Database::query($sql);
498
499
        if (1 !== Database::num_rows($res)) {
500
            return false;
501
        }
502
503
        $typeList = [
504
            'daily',
505
            'weekly',
506
            'monthlyByDate',
507
            'monthlyByDay',
508
            'monthlyByDayR',
509
            'yearly',
510
        ];
511
512
        if (!in_array($type, $typeList, true)) {
513
            return false;
514
        }
515
516
        $now = time();
517
        $endTimeStamp = api_strtotime($end, 'UTC');
518
        // The event has to repeat *in the future*. We don't allow repeated
519
        // events in the past
520
        if ($endTimeStamp < $now) {
521
            return false;
522
        }
523
524
        $row = Database::fetch_array($res);
525
526
        $title = $row['title'];
527
        $content = $row['content'];
528
        $allDay = $row['all_day'];
529
530
        $type = Database::escape_string($type);
531
        $end = Database::escape_string($end);
532
        $sql = "INSERT INTO $t_agenda_r (cal_id, cal_type, cal_end)
533
                VALUES ('$eventId', '$type', '$endTimeStamp')";
534
        Database::query($sql);
535
536
        $generatedDates = $this->generateDatesByType($type, $row['start_date'], $row['end_date'], $end);
537
538
        if (empty($generatedDates)) {
539
            return false;
540
        }
541
542
        foreach ($generatedDates as $dateInfo) {
543
            $start = api_get_local_time($dateInfo['start']);
544
            $end = api_get_local_time($dateInfo['end']);
545
            $this->addEvent(
546
                $start,
547
                $end,
548
                $allDay,
549
                $title,
550
                $content,
551
                $sentTo,
552
                false,
553
                $eventId
554
            );
555
        }
556
557
        return true;
558
    }
559
560
    public function storeAgendaEventAsAnnouncement(CCalendarEvent $event, array $sentTo = [])
561
    {
562
        // Sending announcement
563
        if (!empty($sentTo)) {
564
            $id = AnnouncementManager::add_announcement(
565
                api_get_course_info(),
566
                api_get_session_id(),
567
                $event->getTitle(),
568
                $event->getContent(),
569
                $sentTo,
570
                null,
571
                null,
572
                $event->getEndDate()->format('Y-m-d H:i:s')
573
            );
574
575
            AnnouncementManager::sendEmail(
576
                api_get_course_info(),
577
                api_get_session_id(),
578
                $id
579
            );
580
581
            return true;
582
        }
583
584
        return false;
585
    }
586
587
    /**
588
     * Edits an event.
589
     *
590
     * @param int    $id
591
     * @param string $start                 datetime format: 2012-06-14 09:00:00
592
     * @param string $end                   datetime format: 2012-06-14 09:00:00
593
     * @param int    $allDay                is all day 'true' or 'false'
594
     * @param string $title
595
     * @param string $content
596
     * @param array  $usersToSend
597
     * @param array  $attachmentArray
598
     * @param array  $attachmentCommentList
599
     * @param string $comment
600
     * @param string $color
601
     * @param bool   $addAnnouncement
602
     * @param bool   $updateContent
603
     * @param int    $authorId
604
     *
605
     * @return bool
606
     */
607
    public function editEvent(
608
        $id,
609
        $start,
610
        $end,
611
        $allDay,
612
        $title,
613
        $content,
614
        $usersToSend = [],
615
        $attachmentArray = [],
616
        $attachmentCommentList = [],
617
        $comment = '',
618
        $color = '',
619
        $addAnnouncement = false,
620
        $updateContent = true,
621
        $authorId = 0
622
    ) {
623
        $startObject = api_get_utc_datetime($start, true, true);
624
        $endObject = api_get_utc_datetime($end, true, true);
625
        $start = api_get_utc_datetime($start);
626
        $end = api_get_utc_datetime($end);
627
        $allDay = isset($allDay) && 'true' == $allDay ? 1 : 0;
628
        $authorId = empty($authorId) ? api_get_user_id() : (int) $authorId;
629
630
        switch ($this->type) {
631
            case 'personal':
632
                $eventInfo = $this->get_event($id);
633
                if ($eventInfo['user'] != api_get_user_id()) {
634
                    break;
635
                }
636
                $attributes = [
637
                    'title' => $title,
638
                    'date' => $start,
639
                    'enddate' => $end,
640
                    'all_day' => $allDay,
641
                ];
642
643
                if ($updateContent) {
644
                    $attributes['text'] = $content;
645
                }
646
647
                if (!empty($color)) {
648
                    $attributes['color'] = $color;
649
                }
650
651
                Database::update(
652
                    $this->tbl_personal_agenda,
653
                    $attributes,
654
                    ['id = ?' => $id]
655
                );
656
                break;
657
            case 'course':
658
                $repo = Container::getCalendarEventRepository();
659
                $em = Database::getManager();
660
                /** @var CCalendarEvent $event */
661
                $event = $repo->find($id);
662
663
                if (empty($event)) {
664
                    return false;
665
                }
666
667
                $sentToEvent = $event->getUsersAndGroupSubscribedToResource();
668
                $courseId = $this->course['real_id'];
669
670
                if (empty($courseId)) {
671
                    return false;
672
                }
673
674
                $courseEntity = api_get_course_entity($courseId);
675
                $sessionEntity = api_get_session_entity($this->sessionId);
676
                $groupEntity = api_get_group_entity(api_get_group_id());
677
678
                if ($this->getIsAllowedToEdit()) {
679
                    $event
680
                        ->setTitle($title)
681
                        ->setStartDate($startObject)
682
                        ->setEndDate($endObject)
683
                        ->setAllDay($allDay)
684
                        ->setComment($comment)
685
                    ;
686
687
                    if ($updateContent) {
688
                        $event->setContent($content);
689
                    }
690
691
                    if (!empty($color)) {
692
                        $event->setColor($color);
693
                    }
694
695
                    if (!empty($usersToSend)) {
696
                        $sendTo = $this->parseSendToArray($usersToSend);
697
698
                        $usersToDelete = array_diff($sentToEvent['users'], $sendTo['users']);
699
                        $usersToAdd = array_diff($sendTo['users'], $sentToEvent['users']);
700
                        $groupsToDelete = array_diff($sentToEvent['groups'], $sendTo['groups']);
701
                        $groupToAdd = array_diff($sendTo['groups'], $sentToEvent['groups']);
702
703
                        //var_dump($sendTo['everyone'], $usersToDelete, $usersToAdd, $groupsToDelete, $groupToAdd);exit;
704
                        $links = $event->getResourceNode()->getResourceLinks();
705
706
                        if ($sendTo['everyone']) {
707
                            // Delete all from group
708
                            if (isset($sentToEvent['groups']) && !empty($sentToEvent['groups'])) {
709
                                foreach ($sentToEvent['groups'] as $group) {
710
                                    foreach ($links as $link) {
711
                                        if ($link->hasGroup() && $link->getGroup()->getIid() === $group) {
712
                                            $em->remove($link);
713
                                        }
714
                                    }
715
                                }
716
                            }
717
718
                            // Storing the selected users.
719
                            if (isset($sentToEvent['users']) && !empty($sentToEvent['users'])) {
720
                                foreach ($sentToEvent['users'] as $userId) {
721
                                    foreach ($links as $link) {
722
                                        if ($link->hasUser() && $link->getUser()->getId() === $userId) {
723
                                            $em->remove($link);
724
                                        }
725
                                    }
726
                                }
727
                            }
728
                        } else {
729
                            foreach ($links as $link) {
730
                                $em->remove($link);
731
                            }
732
733
                            // Add groups
734
                            if (!empty($groupToAdd)) {
735
                                foreach ($groupToAdd as $group) {
736
                                    $group = api_get_group_entity($group);
737
                                    $event->addCourseLink($courseEntity, $sessionEntity, $group);
738
                                }
739
                            }
740
741
                            // Delete groups.
742
                            if (!empty($groupsToDelete)) {
743
                                foreach ($groupsToDelete as $group) {
744
                                    foreach ($links as $link) {
745
                                        if ($link->hasGroup() && $link->getGroup()->getIid() === $group) {
746
                                            $em->remove($link);
747
                                        }
748
                                    }
749
                                }
750
                            }
751
752
                            // Add users.
753
                            if (!empty($usersToAdd)) {
754
                                foreach ($usersToAdd as $userId) {
755
                                    $event = $event->addUserLink(
756
                                        api_get_user_entity($userId),
757
                                        $courseEntity,
758
                                        $sessionEntity,
759
                                        $groupEntity
760
                                    );
761
                                }
762
                            }
763
764
                            // Delete users.
765
                            if (!empty($usersToDelete)) {
766
                                foreach ($usersToDelete as $userId) {
767
                                    foreach ($links as $link) {
768
                                        if ($link->hasUser() && $link->getUser()->getId() === $userId) {
769
                                            $em->remove($link);
770
                                        }
771
                                    }
772
                                }
773
                            }
774
                        }
775
                    }
776
777
                    $em->persist($event);
778
                    $em->flush($event);
779
780
                    // Add announcement.
781
                    if (isset($addAnnouncement) && !empty($addAnnouncement)) {
782
                        $this->storeAgendaEventAsAnnouncement($event, $usersToSend);
783
                    }
784
785
                    // Add attachment.
786
                    if (isset($attachmentArray) && !empty($attachmentArray)) {
787
                        $counter = 0;
788
                        foreach ($attachmentArray as $attachmentItem) {
789
                            if (isset($attachmentItem['id'])) {
790
                                $this->updateAttachment(
791
                                    $attachmentItem['id'],
792
                                    $id,
793
                                    $attachmentItem,
794
                                    $attachmentCommentList[$counter],
795
                                    $this->course
796
                                );
797
                                $counter++;
798
                            }
799
                        }
800
                    }
801
802
                    return true;
803
                }
804
805
                return false;
806
                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...
807
            case 'admin':
808
            case 'platform':
809
                if (api_is_platform_admin()) {
810
                    $attributes = [
811
                        'title' => $title,
812
                        'start_date' => $start,
813
                        'end_date' => $end,
814
                        'all_day' => $allDay,
815
                    ];
816
817
                    if ($updateContent) {
818
                        $attributes['content'] = $content;
819
                    }
820
                    Database::update(
821
                        $this->tbl_global_agenda,
822
                        $attributes,
823
                        ['id = ?' => $id]
824
                    );
825
                }
826
                break;
827
        }
828
    }
829
830
    /**
831
     * @param int  $id
832
     * @param bool $deleteAllItemsFromSerie
833
     */
834
    public function deleteEvent($id, $deleteAllItemsFromSerie = false)
835
    {
836
        switch ($this->type) {
837
            case 'personal':
838
                $eventInfo = $this->get_event($id);
839
                if ($eventInfo['user'] == api_get_user_id()) {
840
                    Database::delete(
841
                        $this->tbl_personal_agenda,
842
                        ['id = ?' => $id]
843
                    );
844
                }
845
                break;
846
            case 'course':
847
                $courseId = api_get_course_int_id();
848
                $isAllowToEdit = $this->getIsAllowedToEdit();
849
850
                if (!empty($courseId) && $isAllowToEdit) {
851
                    // Delete
852
                    $eventInfo = $this->get_event($id);
853
854
                    if ($deleteAllItemsFromSerie) {
855
                        /* This is one of the children.
856
                           Getting siblings and delete 'Em all + the father! */
857
                        if (isset($eventInfo['parent_event_id']) && !empty($eventInfo['parent_event_id'])) {
858
                            // Removing items.
859
                            $events = $this->getAllRepeatEvents($eventInfo['parent_event_id']);
860
                            if (!empty($events)) {
861
                                foreach ($events as $event) {
862
                                    $this->deleteEvent($event['id']);
863
                                }
864
                            }
865
                            // Removing parent.
866
                            $this->deleteEvent($eventInfo['parent_event_id']);
867
                        } else {
868
                            // This is the father looking for the children.
869
                            $events = $this->getAllRepeatEvents($id);
870
                            if (!empty($events)) {
871
                                foreach ($events as $event) {
872
                                    $this->deleteEvent($event['id']);
873
                                }
874
                            }
875
                        }
876
                    }
877
878
                    $repo = Container::getCalendarEventRepository();
879
                    $event = $repo->find($id);
880
881
                    if ($event) {
882
                        Database::getManager()->remove($event);
883
                        Database::getManager()->flush();
884
885
                        // Removing from events.
886
                        /*Database::delete(
887
                            $this->tbl_course_agenda,
888
                            ['id = ? AND c_id = ?' => [$id, $courseId]]
889
                        );*/
890
891
                        /*api_item_property_update(
892
                            $this->course,
893
                            TOOL_CALENDAR_EVENT,
894
                            $id,
895
                            'delete',
896
                            api_get_user_id()
897
                        );*/
898
899
                        // Removing from series.
900
                        Database::delete(
901
                            $this->table_repeat,
902
                            [
903
                                'cal_id = ?' => [
904
                                    $id,
905
                                ],
906
                            ]
907
                        );
908
                        // Attachments are already deleted using the doctrine remove() function.
909
                        /*if (isset($eventInfo['attachment']) && !empty($eventInfo['attachment'])) {
910
                            foreach ($eventInfo['attachment'] as $attachment) {
911
                                self::deleteAttachmentFile(
912
                                    $attachment['id'],
913
                                    $this->course
914
                                );
915
                            }
916
                        }*/
917
                        echo 1;
918
                    }
919
                }
920
                break;
921
            case 'admin':
922
                if (api_is_platform_admin()) {
923
                    Database::delete(
924
                        $this->tbl_global_agenda,
925
                        ['id = ?' => $id]
926
                    );
927
                }
928
                break;
929
        }
930
    }
931
932
    /**
933
     * Get agenda events.
934
     *
935
     * @param int    $start
936
     * @param int    $end
937
     * @param int    $courseId
938
     * @param int    $groupId
939
     * @param int    $user_id
940
     * @param string $format
941
     *
942
     * @return array|string
943
     */
944
    public function getEvents(
945
        $start,
946
        $end,
947
        $courseId = null,
948
        $groupId = null,
949
        $user_id = 0,
950
        $format = 'json'
951
    ) {
952
        switch ($this->type) {
953
            case 'admin':
954
                $this->getPlatformEvents($start, $end);
955
                break;
956
            case 'course':
957
                $course = api_get_course_entity($courseId);
958
959
                // Session coach can see all events inside a session.
960
                if (api_is_coach()) {
961
                    // Own course
962
                    $this->getCourseEvents(
963
                        $start,
964
                        $end,
965
                        $course,
966
                        $groupId,
967
                        $this->sessionId,
968
                        $user_id
969
                    );
970
971
                    // Others
972
                    $this->getSessionEvents(
973
                        $start,
974
                        $end,
975
                        $this->sessionId,
976
                        $user_id,
977
                        $this->eventOtherSessionColor
978
                    );
979
                } else {
980
                    $this->getCourseEvents(
981
                        $start,
982
                        $end,
983
                        $course,
984
                        $groupId,
985
                        $this->sessionId,
986
                        $user_id
987
                    );
988
                }
989
                break;
990
            case 'personal':
991
            default:
992
                $sessionFilterActive = false;
993
                if (!empty($this->sessionId)) {
994
                    $sessionFilterActive = true;
995
                }
996
997
                if (false == $sessionFilterActive) {
998
                    // Getting personal events
999
                    $this->getPersonalEvents($start, $end);
1000
1001
                    // Getting platform/admin events
1002
                    $this->getPlatformEvents($start, $end);
1003
                }
1004
1005
                $ignoreVisibility = api_get_configuration_value('personal_agenda_show_all_session_events');
1006
1007
                // Getting course events
1008
                $my_course_list = [];
1009
                if (!api_is_anonymous()) {
1010
                    $session_list = SessionManager::get_sessions_by_user(
1011
                        api_get_user_id(),
1012
                        $ignoreVisibility
1013
                    );
1014
                    $my_course_list = CourseManager::get_courses_list_by_user_id(
1015
                        api_get_user_id(),
1016
                        false
1017
                    );
1018
                }
1019
1020
                if (api_is_drh() && api_drh_can_access_all_session_content()) {
1021
                    $session_list = [];
1022
                    $sessionList = SessionManager::get_sessions_followed_by_drh(
1023
                        api_get_user_id(),
1024
                        null,
1025
                        null,
1026
                        null,
1027
                        true,
1028
                        false
1029
                    );
1030
1031
                    if (!empty($sessionList)) {
1032
                        foreach ($sessionList as $sessionItem) {
1033
                            $sessionId = $sessionItem['id'];
1034
                            $courses = SessionManager::get_course_list_by_session_id(
1035
                                $sessionId
1036
                            );
1037
                            $sessionInfo = [
1038
                                'session_id' => $sessionId,
1039
                                'courses' => $courses,
1040
                            ];
1041
                            $session_list[] = $sessionInfo;
1042
                        }
1043
                    }
1044
                }
1045
1046
                if (!empty($session_list)) {
1047
                    foreach ($session_list as $session_item) {
1048
                        if ($sessionFilterActive) {
1049
                            if ($this->sessionId != $session_item['session_id']) {
1050
                                continue;
1051
                            }
1052
                        }
1053
1054
                        $my_courses = $session_item['courses'];
1055
                        $my_session_id = $session_item['session_id'];
1056
1057
                        if (!empty($my_courses)) {
1058
                            foreach ($my_courses as $course_item) {
1059
                                $course = api_get_course_entity($course_item['real_id']);
1060
                                $this->getCourseEvents(
1061
                                    $start,
1062
                                    $end,
1063
                                    $course,
1064
                                    0,
1065
                                    $my_session_id
1066
                                );
1067
                            }
1068
                        }
1069
                    }
1070
                }
1071
1072
                if (!empty($my_course_list) && false == $sessionFilterActive) {
1073
                    foreach ($my_course_list as $courseInfoItem) {
1074
                        $course = api_get_course_entity($courseInfoItem['real_id']);
1075
                        if (isset($courseId) && !empty($courseId)) {
1076
                            if ($course->getId() == $courseId) {
1077
                                $this->getCourseEvents(
1078
                                    $start,
1079
                                    $end,
1080
                                    $course,
1081
                                    0,
1082
                                    0,
1083
                                    $user_id
1084
                                );
1085
                            }
1086
                        } else {
1087
                            $this->getCourseEvents(
1088
                                $start,
1089
                                $end,
1090
                                $course,
1091
                                0,
1092
                                0,
1093
                                $user_id
1094
                            );
1095
                        }
1096
                    }
1097
                }
1098
                break;
1099
        }
1100
1101
        $this->cleanEvents();
1102
1103
        switch ($format) {
1104
            case 'json':
1105
                if (empty($this->events)) {
1106
                    return '[]';
1107
                }
1108
1109
                return json_encode($this->events);
1110
                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...
1111
            case 'array':
1112
                if (empty($this->events)) {
1113
                    return [];
1114
                }
1115
1116
                return $this->events;
1117
                break;
1118
        }
1119
    }
1120
1121
    /**
1122
     * Clean events.
1123
     *
1124
     * @return bool
1125
     */
1126
    public function cleanEvents()
1127
    {
1128
        if (empty($this->events)) {
1129
            return false;
1130
        }
1131
1132
        foreach ($this->events as &$event) {
1133
            $event['description'] = Security::remove_XSS($event['description']);
1134
            $event['title'] = Security::remove_XSS($event['title']);
1135
        }
1136
1137
        return true;
1138
    }
1139
1140
    /**
1141
     * @param int $id
1142
     * @param int $minute_delta
1143
     *
1144
     * @return int
1145
     */
1146
    public function resizeEvent($id, $minute_delta)
1147
    {
1148
        $id = (int) $id;
1149
        $delta = (int) $minute_delta;
1150
        $event = $this->get_event($id);
1151
        if (!empty($event)) {
1152
            switch ($this->type) {
1153
                case 'personal':
1154
                    $sql = "UPDATE $this->tbl_personal_agenda SET
1155
                            enddate = DATE_ADD(enddate, INTERVAL $delta MINUTE)
1156
							WHERE id = ".$id;
1157
                    Database::query($sql);
1158
                    break;
1159
                case 'course':
1160
                    $sql = "UPDATE $this->tbl_course_agenda SET
1161
                            end_date = DATE_ADD(end_date, INTERVAL $delta MINUTE)
1162
							WHERE
1163
							    c_id = ".$this->course['real_id']." AND
1164
							    id = ".$id;
1165
                    Database::query($sql);
1166
                    break;
1167
                case 'admin':
1168
                    $sql = "UPDATE $this->tbl_global_agenda SET
1169
                            end_date = DATE_ADD(end_date, INTERVAL $delta MINUTE)
1170
							WHERE id = ".$id;
1171
                    Database::query($sql);
1172
                    break;
1173
            }
1174
        }
1175
1176
        return 1;
1177
    }
1178
1179
    /**
1180
     * @param int $id
1181
     * @param int $minute_delta minutes
1182
     * @param int $allDay
1183
     *
1184
     * @return int
1185
     */
1186
    public function move_event($id, $minute_delta, $allDay)
1187
    {
1188
        $id = (int) $id;
1189
        $event = $this->get_event($id);
1190
1191
        if (empty($event)) {
1192
            return false;
1193
        }
1194
1195
        // we convert the hour delta into minutes and add the minute delta
1196
        $delta = (int) $minute_delta;
1197
        $allDay = (int) $allDay;
1198
1199
        if (!empty($event)) {
1200
            switch ($this->type) {
1201
                case 'personal':
1202
                    $sql = "UPDATE $this->tbl_personal_agenda SET
1203
                            all_day = $allDay, date = DATE_ADD(date, INTERVAL $delta MINUTE),
1204
                            enddate = DATE_ADD(enddate, INTERVAL $delta MINUTE)
1205
							WHERE id=".$id;
1206
                    Database::query($sql);
1207
                    break;
1208
                case 'course':
1209
                    $sql = "UPDATE $this->tbl_course_agenda SET
1210
                            all_day = $allDay,
1211
                            start_date = DATE_ADD(start_date, INTERVAL $delta MINUTE),
1212
                            end_date = DATE_ADD(end_date, INTERVAL $delta MINUTE)
1213
							WHERE
1214
							    c_id = ".$this->course['real_id']." AND
1215
							    id=".$id;
1216
                    Database::query($sql);
1217
                    break;
1218
                case 'admin':
1219
                    $sql = "UPDATE $this->tbl_global_agenda SET
1220
                            all_day = $allDay,
1221
                            start_date = DATE_ADD(start_date,INTERVAL $delta MINUTE),
1222
                            end_date = DATE_ADD(end_date, INTERVAL $delta MINUTE)
1223
							WHERE id=".$id;
1224
                    Database::query($sql);
1225
                    break;
1226
            }
1227
        }
1228
1229
        return 1;
1230
    }
1231
1232
    /**
1233
     * Gets a single event.
1234
     *
1235
     * @param int $id event id
1236
     *
1237
     * @return array
1238
     */
1239
    public function get_event($id)
1240
    {
1241
        // make sure events of the personal agenda can only be seen by the user himself
1242
        $id = (int) $id;
1243
        $event = null;
1244
        switch ($this->type) {
1245
            case 'personal':
1246
                $sql = "SELECT * FROM ".$this->tbl_personal_agenda."
1247
                        WHERE id = $id AND user = ".api_get_user_id();
1248
                $result = Database::query($sql);
1249
                if (Database::num_rows($result)) {
1250
                    $event = Database::fetch_array($result, 'ASSOC');
1251
                    $event['description'] = $event['text'];
1252
                    $event['content'] = $event['text'];
1253
                    $event['start_date'] = $event['date'];
1254
                    $event['end_date'] = $event['enddate'];
1255
                }
1256
                break;
1257
            case 'course':
1258
                $repo = Container::getCalendarEventRepository();
1259
                /** @var CCalendarEvent $eventEntity */
1260
                $eventEntity = $repo->find($id);
1261
1262
                if (!empty($this->course['real_id'])) {
1263
                    if ($eventEntity) {
1264
                        $event = [];
1265
                        $event['iid'] = $eventEntity->getIid();
1266
                        $event['title'] = $eventEntity->getTitle();
1267
                        $event['content'] = $eventEntity->getContent();
1268
                        $event['all_day'] = $eventEntity->getAllDay();
1269
                        $event['start_date'] = $eventEntity->getStartDate()->format('Y-m-d H:i:s');
1270
                        $event['end_date'] = $eventEntity->getEndDate()->format('Y-m-d H:i:s');
1271
                        $event['description'] = $eventEntity->getComment();
1272
1273
                        // Getting send to array
1274
                        $event['send_to'] = $eventEntity->getUsersAndGroupSubscribedToResource();
1275
1276
                        // Getting repeat info
1277
                        $event['repeat_info'] = $eventEntity->getRepeatEvents();
1278
1279
                        if (!empty($event['parent_event_id'])) {
1280
                            $event['parent_info'] = $eventEntity->getParentEvent();
1281
                        }
1282
1283
                        $event['attachment'] = $eventEntity->getAttachments();
1284
                    }
1285
                }
1286
                break;
1287
            case 'admin':
1288
            case 'platform':
1289
                $sql = "SELECT * FROM ".$this->tbl_global_agenda."
1290
                        WHERE id = $id";
1291
                $result = Database::query($sql);
1292
                if (Database::num_rows($result)) {
1293
                    $event = Database::fetch_array($result, 'ASSOC');
1294
                    $event['description'] = $event['content'];
1295
                }
1296
                break;
1297
        }
1298
1299
        return $event;
1300
    }
1301
1302
    /**
1303
     * Gets personal events.
1304
     *
1305
     * @param int $start
1306
     * @param int $end
1307
     *
1308
     * @return array
1309
     */
1310
    public function getPersonalEvents($start, $end)
1311
    {
1312
        $start = (int) $start;
1313
        $end = (int) $end;
1314
        $startCondition = '';
1315
        $endCondition = '';
1316
1317
        if (0 !== $start) {
1318
            $startCondition = "AND date >= '".api_get_utc_datetime($start)."'";
1319
        }
1320
        if (0 !== $start) {
1321
            $endCondition = "AND (enddate <= '".api_get_utc_datetime($end)."' OR enddate IS NULL)";
1322
        }
1323
        $user_id = api_get_user_id();
1324
1325
        $sql = "SELECT * FROM ".$this->tbl_personal_agenda."
1326
                WHERE user = $user_id $startCondition $endCondition";
1327
1328
        $result = Database::query($sql);
1329
        $my_events = [];
1330
        if (Database::num_rows($result)) {
1331
            while ($row = Database::fetch_array($result, 'ASSOC')) {
1332
                $event = [];
1333
                $event['id'] = 'personal_'.$row['id'];
1334
                $event['title'] = $row['title'];
1335
                $event['className'] = 'personal';
1336
                $event['borderColor'] = $event['backgroundColor'] = $this->event_personal_color;
1337
                $event['editable'] = true;
1338
                $event['sent_to'] = get_lang('Me');
1339
                $event['type'] = 'personal';
1340
1341
                if (!empty($row['date'])) {
1342
                    $event['start'] = $this->formatEventDate($row['date']);
1343
                    $event['start_date_localtime'] = api_get_local_time($row['date']);
1344
                }
1345
1346
                if (!empty($row['enddate'])) {
1347
                    $event['end'] = $this->formatEventDate($row['enddate']);
1348
                    $event['end_date_localtime'] = api_get_local_time($row['enddate']);
1349
                }
1350
1351
                $event['description'] = $row['text'];
1352
                $event['allDay'] = isset($row['all_day']) && 1 == $row['all_day'] ? $row['all_day'] : 0;
1353
                $event['parent_event_id'] = 0;
1354
                $event['has_children'] = 0;
1355
1356
                $my_events[] = $event;
1357
                $this->events[] = $event;
1358
            }
1359
        }
1360
1361
        // Add plugin personal events
1362
        $this->plugin = new AppPlugin();
1363
        $plugins = $this->plugin->getInstalledPluginListObject();
1364
        /** @var Plugin $plugin */
1365
        foreach ($plugins as $plugin) {
1366
            if ($plugin->hasPersonalEvents && method_exists($plugin, 'getPersonalEvents')) {
1367
                $pluginEvents = $plugin->getPersonalEvents($this, $start, $end);
1368
1369
                if (!empty($pluginEvents)) {
1370
                    $this->events = array_merge($this->events, $pluginEvents);
1371
                }
1372
            }
1373
        }
1374
1375
        return $my_events;
1376
    }
1377
1378
    /**
1379
     * @param int    $start
1380
     * @param int    $end
1381
     * @param int    $sessionId
1382
     * @param int    $userId
1383
     * @param string $color
1384
     *
1385
     * @return array
1386
     */
1387
    public function getSessionEvents(
1388
        $start,
1389
        $end,
1390
        $sessionId = 0,
1391
        $userId = 0,
1392
        $color = ''
1393
    ) {
1394
        $courses = SessionManager::get_course_list_by_session_id($sessionId);
1395
1396
        if (!empty($courses)) {
1397
            foreach ($courses as $course) {
1398
                $course = api_get_course_entity($course['real_id']);
1399
                $this->getCourseEvents(
1400
                    $start,
1401
                    $end,
1402
                    $course,
1403
                    0,
1404
                    $sessionId,
1405
                    0,
1406
                    $color
1407
                );
1408
            }
1409
        }
1410
    }
1411
1412
    /**
1413
     * @param int    $start
1414
     * @param int    $end
1415
     * @param Course $course
1416
     * @param int    $groupId
1417
     * @param int    $sessionId
1418
     * @param int    $user_id
1419
     * @param string $color
1420
     *
1421
     * @return array
1422
     */
1423
    public function getCourseEvents(
1424
        $start,
1425
        $end,
1426
        Course $course,
1427
        $groupId = 0,
1428
        $sessionId = 0,
1429
        $user_id = 0,
1430
        $color = ''
1431
    ) {
1432
        $start = (int) $start;
1433
        $end = (int) $end;
1434
1435
        $start = !empty($start) ? api_get_utc_datetime($start) : null;
1436
        $end = !empty($end) ? api_get_utc_datetime($end) : null;
1437
1438
        if (null === $course) {
1439
            return [];
1440
        }
1441
1442
        $courseId = $course->getId();
1443
        $userId = api_get_user_id();
1444
        $sessionId = (int) $sessionId;
1445
        $user_id = (int) $user_id;
1446
1447
        $groupList = GroupManager::get_group_list(
1448
            null,
1449
            $course,
1450
            null,
1451
            $sessionId
1452
        );
1453
1454
        if (api_is_platform_admin() || api_is_allowed_to_edit()) {
1455
            $isAllowToEdit = true;
1456
        } else {
1457
            $isAllowToEdit = CourseManager::isCourseTeacher($userId, $courseId);
1458
        }
1459
1460
        $isAllowToEditByHrm = false;
1461
        if (!empty($sessionId)) {
1462
            $allowDhrToEdit = api_get_configuration_value('allow_agenda_edit_for_hrm');
1463
            if ($allowDhrToEdit) {
1464
                $isHrm = SessionManager::isUserSubscribedAsHRM($sessionId, $userId);
1465
                if ($isHrm) {
1466
                    $isAllowToEdit = $isAllowToEditByHrm = true;
1467
                }
1468
            }
1469
        }
1470
1471
        $groupMemberships = [];
1472
        if (!empty($groupId)) {
1473
            $groupMemberships = [$groupId];
1474
        } else {
1475
            if ($isAllowToEdit) {
1476
                if (!empty($groupList)) {
1477
                    $groupMemberships = array_column($groupList, 'iid');
1478
                }
1479
            } else {
1480
                // get only related groups from user
1481
                $groupMemberships = GroupManager::get_group_ids($courseId, $userId);
1482
            }
1483
        }
1484
1485
        $repo = Container::getCalendarEventRepository();
1486
        $session = api_get_session_entity($sessionId);
1487
        $qb = $repo->getResourcesByCourseOnly($course, $course->getResourceNode());
1488
        $userCondition = '';
1489
1490
        if ($isAllowToEdit) {
1491
            // No group filter was asked
1492
            if (empty($groupId)) {
1493
                if (empty($user_id)) {
1494
                    // Show all events not added in group
1495
                    $userCondition = ' (links.group IS NULL) ';
1496
                    // admin see only his stuff
1497
                    if ('personal' === $this->type) {
1498
                        $userCondition = " (links.user = ".api_get_user_id()." AND (links.group IS NULL) ";
1499
                        $userCondition .= " OR ( (links.user IS NULL)  AND (links.group IS NULL ))) ";
1500
                    }
1501
1502
                    if (!empty($groupMemberships)) {
1503
                        // Show events sent to selected groups
1504
                        $userCondition .= " OR (links.user IS NULL) AND (links.group IN (".implode(", ", $groupMemberships).")) ";
1505
                    }
1506
                } else {
1507
                    // Show events of requested user in no group
1508
                    $userCondition = " (links.user = $user_id AND links.group IS NULL) ";
1509
                    // Show events sent to selected groups
1510
                    if (!empty($groupMemberships)) {
1511
                        $userCondition .= " OR (links.user = $user_id) AND (links.group IN (".implode(", ", $groupMemberships).")) ";
1512
                    }
1513
                }
1514
            } else {
1515
                // Show only selected groups (depending of user status)
1516
                $userCondition = " (links.user is NULL) AND (links.group IN (".implode(", ", $groupMemberships).")) ";
1517
1518
                if (!empty($groupMemberships)) {
1519
                    // Show send to $user_id in selected groups
1520
                    $userCondition .= " OR (links.user = $user_id) AND (links.group IN (".implode(", ", $groupMemberships).")) ";
1521
                }
1522
            }
1523
        } else {
1524
            // No group filter was asked
1525
            if (empty($groupId)) {
1526
                // Show events sent to everyone and no group
1527
                $userCondition = ' ( (links.user is NULL) AND (links.group IS NULL) ';
1528
                // Show events sent to selected groups
1529
                if (!empty($groupMemberships)) {
1530
                    $userCondition .= " OR (links.user is NULL) AND
1531
                                        (links.group IN (".implode(", ", $groupMemberships)."))) ";
1532
                } else {
1533
                    $userCondition .= " ) ";
1534
                }
1535
                $userCondition .= " OR (links.user = ".api_get_user_id()." AND (links.group IS NULL )) ";
1536
            } else {
1537
                if (!empty($groupMemberships)) {
1538
                    // Show send to everyone - and only selected groups
1539
                    $userCondition = " (links.user is NULL) AND
1540
                                       (links.group IN (".implode(", ", $groupMemberships).")) ";
1541
                }
1542
            }
1543
1544
            // Show sent to only me and no group
1545
            if (!empty($groupMemberships)) {
1546
                $userCondition .= " OR (
1547
                                    links.user = ".api_get_user_id().") AND
1548
                                    (links.group IN (".implode(", ", $groupMemberships).")
1549
                                    ) ";
1550
            }
1551
        }
1552
1553
        if (!empty($userCondition)) {
1554
            $qb->andWhere($userCondition);
1555
        }
1556
1557
        if (!empty($start) && !empty($end)) {
1558
            $qb->andWhere(
1559
                $qb->expr()->orX(
1560
                    'resource.startDate BETWEEN :start AND :end',
1561
                    'resource.endDate BETWEEN :start AND :end',
1562
                    $qb->expr()->orX(
1563
                        'resource.startDate IS NOT NULL AND resource.endDate IS NOT NULL AND
1564
                            YEAR(resource.startDate) = YEAR(resource.endDate) AND
1565
                            MONTH(:start) BETWEEN MONTH(resource.startDate) AND MONTH(resource.endDate)
1566
                        '
1567
                    )
1568
                )
1569
            )
1570
            ->setParameter('start', $start)
1571
            ->setParameter('end', $end);
1572
        }
1573
1574
        /*
1575
        if (empty($sessionId)) {
1576
            $sessionCondition = "
1577
            (
1578
                agenda.session_id = 0 AND (ip.session_id IS NULL OR ip.session_id = 0)
1579
            ) ";
1580
        } else {
1581
            $sessionCondition = "
1582
            (
1583
                agenda.session_id = $sessionId AND
1584
                ip.session_id = $sessionId
1585
            ) ";
1586
        }
1587
1588
        if (api_is_allowed_to_edit()) {
1589
            $visibilityCondition = " (ip.visibility IN ('1', '0'))  ";
1590
        } else {
1591
            $visibilityCondition = " (ip.visibility = '1') ";
1592
        }
1593
1594
        $sql = "SELECT DISTINCT
1595
                    agenda.*,
1596
                    ip.visibility,
1597
                    ip.to_group_id,
1598
                    ip.insert_user_id,
1599
                    ip.ref,
1600
                    to_user_id
1601
                FROM $tlb_course_agenda agenda
1602
                INNER JOIN $tbl_property ip
1603
                ON (
1604
                    agenda.id = ip.ref AND
1605
                    agenda.c_id = ip.c_id AND
1606
                    ip.tool = '".TOOL_CALENDAR_EVENT."'
1607
                )
1608
                WHERE
1609
                    $sessionCondition AND
1610
                    ($userCondition) AND
1611
                    $visibilityCondition AND
1612
                    agenda.c_id = $courseId
1613
        ";
1614
        $dateCondition = '';
1615
        if (!empty($start) && !empty($end)) {
1616
            $dateCondition .= "AND (
1617
                 agenda.start_date BETWEEN '".$start."' AND '".$end."' OR
1618
                 agenda.end_date BETWEEN '".$start."' AND '".$end."' OR
1619
                 (
1620
                     agenda.start_date IS NOT NULL AND agenda.end_date IS NOT NULL AND
1621
                     YEAR(agenda.start_date) = YEAR(agenda.end_date) AND
1622
                     MONTH('$start') BETWEEN MONTH(agenda.start_date) AND MONTH(agenda.end_date)
1623
                 )
1624
            )";
1625
        }
1626
1627
        $sql .= $dateCondition;
1628
        $result = Database::query($sql);*/
1629
        $coachCanEdit = false;
1630
        if (!empty($sessionId)) {
1631
            $coachCanEdit = api_is_coach($sessionId, $courseId) || api_is_platform_admin();
1632
        }
1633
        $events = $qb->getQuery()->getResult();
1634
1635
        $repo = Container::getCalendarEventAttachmentRepository();
1636
1637
        /** @var CCalendarEvent $row */
1638
        foreach ($events as $row) {
1639
            $eventId = $row->getIid();
1640
            $event = [];
1641
            $event['id'] = 'course_'.$eventId;
1642
            $event['unique_id'] = $eventId;
1643
1644
            $eventsAdded[] = $eventId;
1645
            $attachmentList = $row->getAttachments();
1646
            $event['attachment'] = '';
1647
            if (!empty($attachmentList)) {
1648
                $icon = Display::returnFontAwesomeIcon(
1649
                    'paperclip',
1650
                    '1'
1651
                );
1652
                /** @var CCalendarEventAttachment $attachment */
1653
                foreach ($attachmentList as $attachment) {
1654
                    $url = $repo->getResourceFileDownloadUrl($attachment).'?'.api_get_cidreq();
1655
                    $event['attachment'] .= $icon.
1656
                        Display::url(
1657
                            $attachment->getFilename(),
1658
                            $url
1659
                        ).'<br />';
1660
                }
1661
            }
1662
1663
            $event['title'] = $row->getTitle();
1664
            $event['className'] = 'course';
1665
            $event['allDay'] = 'false';
1666
            $event['course_id'] = $courseId;
1667
            $event['borderColor'] = $event['backgroundColor'] = $this->event_course_color;
1668
1669
            $sessionInfo = [];
1670
            /*if (!empty($row->getSessionId())) {
1671
                $sessionInfo = api_get_session_info($row->getSessionId());
1672
                $event['borderColor'] = $event['backgroundColor'] = $this->event_session_color;
1673
            }*/
1674
1675
            $event['session_name'] = $sessionInfo['name'] ?? '';
1676
            $event['course_name'] = $course->getTitle();
1677
1678
            /*if (isset($row['to_group_id']) && !empty($row['to_group_id'])) {
1679
                $event['borderColor'] = $event['backgroundColor'] = $this->event_group_color;
1680
            }*/
1681
1682
            if (!empty($color)) {
1683
                $event['borderColor'] = $event['backgroundColor'] = $color;
1684
            }
1685
1686
            if ($row->getColor()) {
1687
                $event['borderColor'] = $event['backgroundColor'] = $row->getColor();
1688
            }
1689
1690
            $event['resourceEditable'] = false;
1691
            if ($this->getIsAllowedToEdit() && 'course' === $this->type) {
1692
                $event['resourceEditable'] = true;
1693
                if (!empty($sessionId)) {
1694
                    if (false == $coachCanEdit) {
1695
                        $event['resourceEditable'] = false;
1696
                    }
1697
                    if ($isAllowToEditByHrm) {
1698
                        $event['resourceEditable'] = true;
1699
                    }
1700
                }
1701
                // if user is author then he can edit the item
1702
                if (api_get_user_id() == $row->getResourceNode()->getCreator()->getId()) {
1703
                    $event['resourceEditable'] = true;
1704
                }
1705
            }
1706
1707
            if (!empty($row->getStartDate())) {
1708
                $event['start'] = $this->formatEventDate($row->getStartDate()->format('Y-m-d H:i:s'));
1709
                $event['start_date_localtime'] = api_get_local_time($row->getStartDate()->format('Y-m-d H:i:s'));
1710
            }
1711
            if (!empty($row->getEndDate())) {
1712
                $event['end'] = $this->formatEventDate($row->getEndDate()->format('Y-m-d H:i:s'));
1713
                $event['end_date_localtime'] = api_get_local_time($row->getEndDate()->format('Y-m-d H:i:s'));
1714
            }
1715
1716
            $event['sent_to'] = '';
1717
            $event['type'] = 'course';
1718
            /*if (0 != $row->getSessionId()) {
1719
                $event['type'] = 'session';
1720
            }*/
1721
1722
            $everyone = false;
1723
            $links = $row->getResourceNode()->getResourceLinks();
1724
            $sentTo = [];
1725
            foreach ($links as $link) {
1726
                if ($link->getUser()) {
1727
                    $sentTo[] = $link->getUser()->getFirstname();
1728
                }
1729
                if ($link->getCourse()) {
1730
                    $sentTo[] = $link->getCourse()->getName();
1731
                }
1732
                if ($link->getSession()) {
1733
                    $sentTo[] = $link->getSession()->getName();
1734
                }
1735
                if ($link->getGroup()) {
1736
                    $sentTo[] = $link->getGroup()->getName();
1737
                }
1738
            }
1739
1740
            // Event Sent to a group?
1741
            /*if (isset($row['to_group_id']) && !empty($row['to_group_id'])) {
1742
                $sent_to = [];
1743
                if (!empty($group_to_array)) {
1744
                    foreach ($group_to_array as $group_item) {
1745
                        $sent_to[] = $groupNameList[$group_item];
1746
                    }
1747
                }
1748
                $sent_to = implode('@@', $sent_to);
1749
                $sent_to = str_replace(
1750
                    '@@',
1751
                    '</div><div class="label_tag notice">',
1752
                    $sent_to
1753
                );
1754
                $event['sent_to'] = '<div class="label_tag notice">'.$sent_to.'</div>';
1755
                $event['type'] = 'group';
1756
            }*/
1757
1758
            // Event sent to a user?
1759
            /*if (isset($row['to_user_id'])) {
1760
                $sent_to = [];
1761
                if (!empty($user_to_array)) {
1762
                    foreach ($user_to_array as $item) {
1763
                        $user_info = api_get_user_info($item);
1764
                        // Add username as tooltip for $event['sent_to'] - ref #4226
1765
                        $username = api_htmlentities(
1766
                            sprintf(
1767
                                get_lang('Login: %s'),
1768
                                $user_info['username']
1769
                            ),
1770
                            ENT_QUOTES
1771
                        );
1772
                        $sent_to[] = "<span title='".$username."'>".$user_info['complete_name']."</span>";
1773
                    }
1774
                }
1775
                $sent_to = implode('@@', $sent_to);
1776
                $sent_to = str_replace(
1777
                    '@@',
1778
                    '</div><div class="label_tag notice">',
1779
                    $sent_to
1780
                );
1781
                $event['sent_to'] = '<div class="label_tag notice">'.$sent_to.'</div>';
1782
            }*/
1783
1784
            //Event sent to everyone!
1785
            /*if (empty($event['sent_to'])) {
1786
                $event['sent_to'] = '<div class="label_tag notice">'.get_lang('Everyone').'</div>';
1787
            }*/
1788
            $event['sent_to'] = implode('<br />', $sentTo);
1789
            $event['description'] = $row->getContent();
1790
            $event['visibility'] = $row->isVisible($course, $session) ? 1 : 0;
1791
            $event['real_id'] = $eventId;
1792
            $event['allDay'] = $row->getAllDay();
1793
            $event['parent_event_id'] = $row->getParentEvent() ? $row->getParentEvent()->getIid() : null;
1794
            $event['has_children'] = $row->getChildren()->count() > 0;
1795
            $event['comment'] = $row->getComment();
1796
            $this->events[] = $event;
1797
        }
1798
1799
        return $this->events;
1800
    }
1801
1802
    /**
1803
     * @param int $start tms
1804
     * @param int $end   tms
1805
     *
1806
     * @return array
1807
     */
1808
    public function getPlatformEvents($start, $end)
1809
    {
1810
        $start = isset($start) && !empty($start) ? api_get_utc_datetime(intval($start)) : null;
1811
        $end = isset($end) && !empty($end) ? api_get_utc_datetime(intval($end)) : null;
1812
        $dateCondition = '';
1813
1814
        if (!empty($start) && !empty($end)) {
1815
            $dateCondition .= "AND (
1816
                 start_date BETWEEN '".$start."' AND '".$end."' OR
1817
                 end_date BETWEEN '".$start."' AND '".$end."' OR
1818
                 (
1819
                     start_date IS NOT NULL AND end_date IS NOT NULL AND
1820
                     YEAR(start_date) = YEAR(end_date) AND
1821
                     MONTH('$start') BETWEEN MONTH(start_date) AND MONTH(end_date)
1822
                 )
1823
            )";
1824
        }
1825
1826
        $access_url_id = api_get_current_access_url_id();
1827
1828
        $sql = "SELECT *
1829
                FROM ".$this->tbl_global_agenda."
1830
                WHERE access_url_id = $access_url_id
1831
                $dateCondition";
1832
        $result = Database::query($sql);
1833
        $my_events = [];
1834
        if (Database::num_rows($result)) {
1835
            while ($row = Database::fetch_array($result, 'ASSOC')) {
1836
                $event = [];
1837
                $event['id'] = 'platform_'.$row['id'];
1838
                $event['title'] = $row['title'];
1839
                $event['className'] = 'platform';
1840
                $event['allDay'] = 'false';
1841
                $event['borderColor'] = $event['backgroundColor'] = $this->event_platform_color;
1842
                $event['editable'] = false;
1843
                $event['type'] = 'admin';
1844
1845
                if (api_is_platform_admin() && 'admin' === $this->type) {
1846
                    $event['editable'] = true;
1847
                }
1848
1849
                if (!empty($row['start_date'])) {
1850
                    $event['start'] = $this->formatEventDate($row['start_date']);
1851
                    $event['start_date_localtime'] = api_get_local_time($row['start_date']);
1852
                }
1853
1854
                if (!empty($row['end_date'])) {
1855
                    $event['end'] = $this->formatEventDate($row['end_date']);
1856
                    $event['end_date_localtime'] = api_get_local_time($row['end_date']);
1857
                }
1858
                $event['allDay'] = isset($row['all_day']) && 1 == $row['all_day'] ? $row['all_day'] : 0;
1859
                $event['parent_event_id'] = 0;
1860
                $event['has_children'] = 0;
1861
                $event['description'] = $row['content'];
1862
1863
                $my_events[] = $event;
1864
                $this->events[] = $event;
1865
            }
1866
        }
1867
1868
        return $my_events;
1869
    }
1870
1871
    /**
1872
     * @param CGroup[] $groupList
1873
     * @param array    $userList
1874
     * @param array    $sendTo               array('users' => [1, 2], 'groups' => [3, 4])
1875
     * @param array    $attributes
1876
     * @param bool     $addOnlyItemsInSendTo
1877
     * @param bool     $required
1878
     */
1879
    public function setSendToSelect(
1880
        FormValidator $form,
1881
        $groupList = [],
1882
        $userList = [],
1883
        $sendTo = [],
1884
        $attributes = [],
1885
        $addOnlyItemsInSendTo = false,
1886
        $required = false
1887
    ) {
1888
        $params = [
1889
            'id' => 'users_to_send_id',
1890
            'data-placeholder' => get_lang('Select'),
1891
            'multiple' => 'multiple',
1892
            'class' => 'multiple-select',
1893
        ];
1894
1895
        if (!empty($attributes)) {
1896
            $params = array_merge($params, $attributes);
1897
            if (empty($params['multiple'])) {
1898
                unset($params['multiple']);
1899
            }
1900
        }
1901
1902
        $sendToGroups = isset($sendTo['groups']) ? $sendTo['groups'] : [];
1903
        $sendToUsers = isset($sendTo['users']) ? $sendTo['users'] : [];
1904
1905
        $select = $form->addSelect(
1906
            'users_to_send',
1907
            get_lang('To'),
1908
            null,
1909
            $params
1910
        );
1911
1912
        if ($required) {
1913
            $form->setRequired($select);
1914
        }
1915
1916
        $selectedEveryoneOptions = [];
1917
        if (isset($sendTo['everyone']) && $sendTo['everyone']) {
1918
            $selectedEveryoneOptions = ['selected'];
1919
            $sendToUsers = [];
1920
        }
1921
1922
        $select->addOption(
1923
            get_lang('Everyone'),
1924
            'everyone',
1925
            $selectedEveryoneOptions
1926
        );
1927
1928
        $options = [];
1929
        if (is_array($groupList)) {
1930
            foreach ($groupList as $group) {
1931
                $groupId = $group->getIid();
1932
                $count = $group->getMembers()->count();
1933
                $countUsers = " &ndash; $count ".get_lang('Users');
1934
                $option = [
1935
                    'text' => $group->getName().$countUsers,
1936
                    'value' => "GROUP:".$groupId,
1937
                ];
1938
1939
                $selected = in_array(
1940
                    $groupId,
1941
                    $sendToGroups
1942
                ) ? true : false;
1943
                if ($selected) {
1944
                    $option['selected'] = 'selected';
1945
                }
1946
1947
                if ($addOnlyItemsInSendTo) {
1948
                    if ($selected) {
1949
                        $options[] = $option;
1950
                    }
1951
                } else {
1952
                    $options[] = $option;
1953
                }
1954
            }
1955
            $select->addOptGroup($options, get_lang('Groups'));
1956
        }
1957
1958
        // adding the individual users to the select form
1959
        if (is_array($userList)) {
1960
            $options = [];
1961
            foreach ($userList as $user) {
1962
                if (ANONYMOUS == $user['status']) {
1963
                    continue;
1964
                }
1965
                $option = [
1966
                    'text' => api_get_person_name(
1967
                            $user['firstname'],
1968
                            $user['lastname']
1969
                        ).' ('.$user['username'].')',
1970
                    'value' => "USER:".$user['user_id'],
1971
                ];
1972
1973
                $selected = in_array(
1974
                    $user['user_id'],
1975
                    $sendToUsers
1976
                ) ? true : false;
1977
1978
                if ($selected) {
1979
                    $option['selected'] = 'selected';
1980
                }
1981
1982
                if ($addOnlyItemsInSendTo) {
1983
                    if ($selected) {
1984
                        $options[] = $option;
1985
                    }
1986
                } else {
1987
                    $options[] = $option;
1988
                }
1989
            }
1990
1991
            $select->addOptGroup($options, get_lang('Users'));
1992
        }
1993
    }
1994
1995
    /**
1996
     * Separates the users and groups array
1997
     * users have a value USER:XXX (with XXX the user id
1998
     * groups have a value GROUP:YYY (with YYY the group id)
1999
     * use the 'everyone' key.
2000
     *
2001
     * @author Julio Montoya based in separate_users_groups in agenda.inc.php
2002
     *
2003
     * @param array $to
2004
     *
2005
     * @return array
2006
     */
2007
    public function parseSendToArray($to)
2008
    {
2009
        $groupList = [];
2010
        $userList = [];
2011
        $sendTo = null;
2012
2013
        $sendTo['everyone'] = false;
2014
        if (is_array($to) && count($to) > 0) {
2015
            foreach ($to as $item) {
2016
                if ('everyone' == $item) {
2017
                    $sendTo['everyone'] = true;
2018
                } else {
2019
                    [$type, $id] = explode(':', $item);
2020
                    switch ($type) {
2021
                        case 'GROUP':
2022
                            $groupList[] = $id;
2023
                            break;
2024
                        case 'USER':
2025
                            $userList[] = $id;
2026
                            break;
2027
                    }
2028
                }
2029
            }
2030
            $sendTo['groups'] = $groupList;
2031
            $sendTo['users'] = $userList;
2032
        }
2033
2034
        return $sendTo;
2035
    }
2036
2037
    /**
2038
     * @param array $params
2039
     *
2040
     * @return FormValidator
2041
     */
2042
    public function getForm($params = [])
2043
    {
2044
        $action = isset($params['action']) ? Security::remove_XSS($params['action']) : null;
2045
        $id = isset($params['id']) ? (int) $params['id'] : 0;
2046
2047
        $url = api_get_self().'?action='.$action.'&id='.$id.'&type='.$this->type;
2048
        if ('course' === $this->type) {
2049
            $url = api_get_self().'?'.api_get_cidreq().'&action='.$action.'&id='.$id.'&type='.$this->type;
2050
        }
2051
2052
        $form = new FormValidator(
2053
            'add_event',
2054
            'post',
2055
            $url,
2056
            null,
2057
            ['enctype' => 'multipart/form-data']
2058
        );
2059
2060
        $idAttach = isset($params['id_attach']) ? (int) $params['id_attach'] : null;
2061
        $groupId = api_get_group_id();
2062
        $form_Title = get_lang('Add event to agenda');
2063
        if (!empty($id)) {
2064
            $form_Title = get_lang('Edit event');
2065
        }
2066
2067
        $form->addHeader($form_Title);
2068
        $form->addHidden('id', $id);
2069
        $form->addHidden('action', $action);
2070
        $form->addHidden('id_attach', $idAttach);
2071
2072
        $isSubEventEdition = false;
2073
        $isParentFromSerie = false;
2074
        $showAttachmentForm = true;
2075
2076
        if ('course' === $this->type) {
2077
            // Edition mode.
2078
            if (!empty($id)) {
2079
                $showAttachmentForm = false;
2080
                if (isset($params['parent_event_id']) && !empty($params['parent_event_id'])) {
2081
                    $isSubEventEdition = true;
2082
                }
2083
                if (!empty($params['repeat_info'])) {
2084
                    $isParentFromSerie = true;
2085
                }
2086
            }
2087
        }
2088
2089
        if ($isSubEventEdition) {
2090
            $form->addElement(
2091
                'label',
2092
                null,
2093
                Display::return_message(
2094
                    get_lang('Editing this event will remove it from the serie of events it is currently part of'),
2095
                    'warning'
2096
                )
2097
            );
2098
        }
2099
2100
        $form->addElement('text', 'title', get_lang('Event name'));
2101
2102
        if (isset($groupId) && !empty($groupId)) {
2103
            $form->addElement(
2104
                'hidden',
2105
                'users_to_send[]',
2106
                "GROUP:$groupId"
2107
            );
2108
            $form->addElement('hidden', 'to', 'true');
2109
        } else {
2110
            $sendTo = isset($params['send_to']) ? $params['send_to'] : ['everyone' => true];
2111
            if ('course' === $this->type) {
2112
                $this->showToForm($form, $sendTo, [], false, true);
2113
            }
2114
        }
2115
2116
        $form->addDateRangePicker(
2117
            'date_range',
2118
            get_lang('Date range'),
2119
            false,
2120
            ['id' => 'date_range']
2121
        );
2122
        $form->addElement('checkbox', 'all_day', null, get_lang('All day'));
2123
2124
        if ('course' === $this->type) {
2125
            $repeat = $form->addElement(
2126
                'checkbox',
2127
                'repeat',
2128
                null,
2129
                get_lang('Repeat event'),
2130
                ['onclick' => 'return plus_repeated_event();']
2131
            );
2132
            $form->addElement(
2133
                'html',
2134
                '<div id="options2" style="display:none">'
2135
            );
2136
            $form->addElement(
2137
                'select',
2138
                'repeat_type',
2139
                get_lang('Repeat type'),
2140
                self::getRepeatTypes()
2141
            );
2142
            $form->addElement(
2143
                'date_picker',
2144
                'repeat_end_day',
2145
                get_lang('Repeat end date'),
2146
                ['id' => 'repeat_end_date_form']
2147
            );
2148
2149
            if ($isSubEventEdition || $isParentFromSerie) {
2150
                $repeatInfo = $params['repeat_info'];
2151
                if ($isSubEventEdition) {
2152
                    $parentEvent = $params['parent_info'];
2153
                    $repeatInfo = $parentEvent['repeat_info'];
2154
                }
2155
                $params['repeat'] = 1;
2156
                $params['repeat_type'] = $repeatInfo['cal_type'];
2157
                $params['repeat_end_day'] = substr(
2158
                    api_get_local_time($repeatInfo['cal_end']),
2159
                    0,
2160
                    10
2161
                );
2162
2163
                $form->freeze(['repeat_type', 'repeat_end_day']);
2164
                $repeat->_attributes['disabled'] = 'disabled';
2165
            }
2166
            $form->addElement('html', '</div>');
2167
        }
2168
2169
        if (!empty($id)) {
2170
            if (empty($params['end_date'])) {
2171
                $params['date_range'] = $params['end_date'];
2172
            }
2173
2174
            $params['date_range'] =
2175
                substr(api_get_local_time($params['start_date']), 0, 16).' / '.
2176
                substr(api_get_local_time($params['end_date']), 0, 16);
2177
        }
2178
2179
        $toolbar = 'Agenda';
2180
        if (!api_is_allowed_to_edit(null, true)) {
2181
            $toolbar = 'AgendaStudent';
2182
        }
2183
2184
        $form->addHtmlEditor(
2185
            'content',
2186
            get_lang('Description'),
2187
            null,
2188
            [
2189
                'ToolbarSet' => $toolbar,
2190
                'Width' => '100%',
2191
                'Height' => '200',
2192
            ]
2193
        );
2194
2195
        if ('course' === $this->type) {
2196
            $form->addTextarea('comment', get_lang('Comment'));
2197
            $form->addLabel(
2198
                get_lang('Files attachments'),
2199
                '<div id="filepaths" class="file-upload-event">
2200
2201
                        <div id="filepath_1">
2202
                            <input type="file" name="attach_1"/>
2203
2204
                            <label>'.get_lang('Description').'</label>
2205
                            <input class="form-control" type="text" name="legend[]" />
2206
                        </div>
2207
2208
                    </div>'
2209
            );
2210
2211
            $form->addLabel(
2212
                '',
2213
                '<span id="link-more-attach">
2214
                    <a href="javascript://" onclick="return add_image_form()">'.
2215
                get_lang('Add one more file').'</a>
2216
                 </span>&nbsp;('.sprintf(
2217
                    get_lang('Maximun file size: %s'),
2218
                    format_file_size(
2219
                        api_get_setting('message_max_upload_filesize')
2220
                    )
2221
                ).')'
2222
            );
2223
2224
            if (isset($params['attachment']) && !empty($params['attachment'])) {
2225
                $attachmentList = $params['attachment'];
2226
                /** @var CCalendarEventAttachment $attachment */
2227
                foreach ($attachmentList as $attachment) {
2228
                    $form->addElement(
2229
                        'checkbox',
2230
                        'delete_attachment['.$attachment->getIid().']',
2231
                        null,
2232
                        get_lang('Delete attachment').': '.$attachment->getFilename()
2233
                    );
2234
                }
2235
            }
2236
2237
            $form->addTextarea(
2238
                'file_comment',
2239
                get_lang('File comment')
2240
            );
2241
        }
2242
2243
        if (empty($id)) {
2244
            $form->addElement(
2245
                'checkbox',
2246
                'add_announcement',
2247
                null,
2248
                get_lang('Add an announcement').'&nbsp('.get_lang('Send mail').')'
2249
            );
2250
        }
2251
2252
        if ($id) {
2253
            $form->addButtonUpdate(get_lang('Edit event'));
2254
        } else {
2255
            $form->addButtonSave(get_lang('Add event'));
2256
        }
2257
2258
        $form->setDefaults($params);
2259
        $form->addRule(
2260
            'date_range',
2261
            get_lang('Required field'),
2262
            'required'
2263
        );
2264
        $form->addRule('title', get_lang('Required field'), 'required');
2265
2266
        return $form;
2267
    }
2268
2269
    /**
2270
     * @param FormValidator $form
2271
     * @param array         $sendTo               array('everyone' => false, 'users' => [1, 2], 'groups' => [3, 4])
2272
     * @param array         $attributes
2273
     * @param bool          $addOnlyItemsInSendTo
2274
     * @param bool          $required
2275
     *
2276
     * @return bool
2277
     */
2278
    public function showToForm(
2279
        $form,
2280
        $sendTo = [],
2281
        $attributes = [],
2282
        $addOnlyItemsInSendTo = false,
2283
        $required = false
2284
    ) {
2285
        if ('course' !== $this->type) {
2286
            return false;
2287
        }
2288
2289
        $order = 'lastname';
2290
        if (api_is_western_name_order()) {
2291
            $order = 'firstname';
2292
        }
2293
2294
        $userList = CourseManager::get_user_list_from_course_code(
2295
            api_get_course_id(),
2296
            $this->sessionId,
2297
            null,
2298
            $order
2299
        );
2300
2301
        $groupList = CourseManager::get_group_list_of_course(
2302
            api_get_course_id(),
2303
            $this->sessionId
2304
        );
2305
2306
        $this->setSendToSelect(
2307
            $form,
2308
            $groupList,
2309
            $userList,
2310
            $sendTo,
2311
            $attributes,
2312
            $addOnlyItemsInSendTo,
2313
            $required
2314
        );
2315
2316
        return true;
2317
    }
2318
2319
    /**
2320
     * @param int   $id
2321
     * @param int   $visibility 0= invisible, 1 visible
2322
     * @param array $courseInfo
2323
     * @param int   $userId
2324
     */
2325
    public static function changeVisibility(
2326
        $id,
2327
        $visibility,
2328
        $courseInfo,
2329
        $userId = null
2330
    ) {
2331
        $id = (int) $id;
2332
2333
        $repo = Container::getCalendarEventRepository();
2334
        /** @var CCalendarEvent $event */
2335
        $event = $repo->find($id);
2336
        $visibility = (int) $visibility;
2337
2338
        if ($event) {
2339
            if (0 === $visibility) {
2340
                $repo->setVisibilityDraft($event);
2341
            } else {
2342
                $repo->setVisibilityPublished($event);
2343
            }
2344
        }
2345
2346
        return true;
2347
    }
2348
2349
    /**
2350
     * Get repeat types.
2351
     */
2352
    public static function getRepeatTypes(): array
2353
    {
2354
        return [
2355
            'daily' => get_lang('Daily'),
2356
            'weekly' => get_lang('Weekly'),
2357
            'monthlyByDate' => get_lang('Monthly, by date'),
2358
            //monthlyByDay"> get_lang('Monthly, by day');
2359
            //monthlyByDayR' => get_lang('Monthly, by dayR'),
2360
            'yearly' => get_lang('Yearly'),
2361
        ];
2362
    }
2363
2364
    /**
2365
     * Show a list with all the attachments according to the post's id.
2366
     *
2367
     * @param int   $attachmentId
2368
     * @param int   $eventId
2369
     * @param array $courseInfo
2370
     *
2371
     * @return array with the post info
2372
     */
2373
    public function getAttachment($attachmentId, $eventId, $courseInfo)
2374
    {
2375
        if (empty($courseInfo) || empty($attachmentId) || empty($eventId)) {
2376
            return [];
2377
        }
2378
2379
        $tableAttachment = Database::get_course_table(TABLE_AGENDA_ATTACHMENT);
2380
        $courseId = (int) $courseInfo['real_id'];
2381
        $eventId = (int) $eventId;
2382
        $attachmentId = (int) $attachmentId;
2383
2384
        $row = [];
2385
        $sql = "SELECT iid, path, filename, comment
2386
                FROM $tableAttachment
2387
                WHERE
2388
                    c_id = $courseId AND
2389
                    agenda_id = $eventId AND
2390
                    iid = $attachmentId
2391
                ";
2392
        $result = Database::query($sql);
2393
        if (0 != Database::num_rows($result)) {
2394
            $row = Database::fetch_array($result, 'ASSOC');
2395
        }
2396
2397
        return $row;
2398
    }
2399
2400
    /**
2401
     * Add an attachment file into agenda.
2402
     *
2403
     * @param CCalendarEvent $event
2404
     * @param UploadedFile   $file
2405
     * @param string         $comment
2406
     * @param array          $courseInfo
2407
     *
2408
     * @return string
2409
     */
2410
    public function addAttachment(
2411
        $event,
2412
        $file,
2413
        $comment,
2414
        $courseInfo
2415
    ) {
2416
        // Storing the attachments
2417
        $valid = false;
2418
        if ($file) {
2419
            $valid = process_uploaded_file($file);
2420
        }
2421
2422
        if ($valid) {
2423
            // user's file name
2424
            $fileName = $file->getClientOriginalName();
2425
            $em = Database::getManager();
2426
            $attachment = new CCalendarEventAttachment();
2427
            $attachment
2428
                ->setFilename($fileName)
2429
                ->setComment($comment)
2430
                ->setEvent($event)
2431
                ->setParent($event)
2432
                ->addCourseLink(
2433
                    api_get_course_entity(),
2434
                    api_get_session_entity(),
2435
                    api_get_group_entity()
2436
                );
2437
2438
            $repo = Container::getCalendarEventAttachmentRepository();
2439
            $em->persist($attachment);
2440
            $em->flush();
2441
2442
            $repo->addFile($attachment, $file);
2443
            $em->persist($attachment);
2444
            $em->flush();
2445
        }
2446
    }
2447
2448
    /**
2449
     * @param int    $attachmentId
2450
     * @param int    $eventId
2451
     * @param array  $fileUserUpload
2452
     * @param string $comment
2453
     * @param array  $courseInfo
2454
     */
2455
    public function updateAttachment(
2456
        $attachmentId,
2457
        $eventId,
2458
        $fileUserUpload,
2459
        $comment,
2460
        $courseInfo
2461
    ) {
2462
        $attachment = $this->getAttachment(
2463
            $attachmentId,
2464
            $eventId,
2465
            $courseInfo
2466
        );
2467
        if (!empty($attachment)) {
2468
            $this->deleteAttachmentFile($attachmentId);
2469
        }
2470
        $this->addAttachment($eventId, $fileUserUpload, $comment, $courseInfo);
2471
    }
2472
2473
    /**
2474
     * This function delete a attachment file by id.
2475
     *
2476
     * @param int $attachmentId
2477
     *
2478
     * @return string
2479
     */
2480
    public function deleteAttachmentFile($attachmentId)
2481
    {
2482
        $repo = Container::getCalendarEventAttachmentRepository();
2483
        /** @var CCalendarEventAttachment $attachment */
2484
        $attachment = $repo->find($attachmentId);
2485
        $em = Database::getManager();
2486
        if (empty($attachment)) {
2487
            return false;
2488
        }
2489
2490
        $em->remove($attachment);
2491
        $em->flush();
2492
2493
        return Display::return_message(
2494
            get_lang("The attached file has been deleted"),
2495
            'confirmation'
2496
        );
2497
    }
2498
2499
    /**
2500
     * @param int $eventId
2501
     *
2502
     * @return array
2503
     */
2504
    public function getAllRepeatEvents($eventId)
2505
    {
2506
        $events = [];
2507
        $eventId = (int) $eventId;
2508
2509
        switch ($this->type) {
2510
            case 'personal':
2511
                break;
2512
            case 'course':
2513
                if (!empty($this->course['real_id'])) {
2514
                    $sql = "SELECT * FROM ".$this->tbl_course_agenda."
2515
                            WHERE
2516
                                c_id = ".$this->course['real_id']." AND
2517
                                parent_event_id = ".$eventId;
2518
                    $result = Database::query($sql);
2519
                    if (Database::num_rows($result)) {
2520
                        while ($row = Database::fetch_array($result, 'ASSOC')) {
2521
                            $events[] = $row;
2522
                        }
2523
                    }
2524
                }
2525
                break;
2526
        }
2527
2528
        return $events;
2529
    }
2530
2531
    /**
2532
     * @param int    $filter
2533
     * @param string $view
2534
     *
2535
     * @return string
2536
     */
2537
    public function displayActions($view, $filter = 0)
2538
    {
2539
        $group = api_get_group_entity();
2540
        $groupIid = null === $group ? 0 : $group->getIid();
2541
        $codePath = api_get_path(WEB_CODE_PATH);
2542
2543
        $currentUserId = api_get_user_id();
2544
        $cidReq = api_get_cidreq();
2545
2546
        $actionsLeft = '';
2547
        $actionsLeft .= Display::url(
2548
            Display::return_icon('calendar.png', get_lang('Calendar'), [], ICON_SIZE_MEDIUM),
2549
            $codePath."calendar/agenda_js.php?type={$this->type}&$cidReq"
2550
        );
2551
        $actionsLeft .= Display::url(
2552
            Display::return_icon('week.png', get_lang('Agenda list'), [], ICON_SIZE_MEDIUM),
2553
            $codePath."calendar/agenda_list.php?type={$this->type}&$cidReq"
2554
        );
2555
2556
        $form = '';
2557
        if (api_is_allowed_to_edit(false, true) ||
2558
            ('1' == api_get_course_setting('allow_user_edit_agenda') && !api_is_anonymous()) &&
2559
            api_is_allowed_to_session_edit(false, true)
2560
            || (
2561
                GroupManager::userHasAccess($currentUserId, $group, GroupManager::GROUP_TOOL_CALENDAR)
2562
                && GroupManager::isTutorOfGroup($currentUserId, $group)
2563
            )
2564
        ) {
2565
            $actionsLeft .= Display::url(
2566
                Display::return_icon('new_event.png', get_lang('Add event'), [], ICON_SIZE_MEDIUM),
2567
                $codePath."calendar/agenda.php?action=add&type={$this->type}&$cidReq"
2568
            );
2569
2570
            $actionsLeft .= Display::url(
2571
                Display::return_icon('import_calendar.png', get_lang('Outlook import'), [], ICON_SIZE_MEDIUM),
2572
                $codePath."calendar/agenda.php?action=importical&type={$this->type}&$cidReq"
2573
            );
2574
2575
            if ('course' === $this->type) {
2576
                if (!isset($_GET['action'])) {
2577
                    $form = new FormValidator(
2578
                        'form-search',
2579
                        'post',
2580
                        '',
2581
                        '',
2582
                        [],
2583
                        FormValidator::LAYOUT_INLINE
2584
                    );
2585
                    $attributes = [
2586
                        'multiple' => false,
2587
                        'id' => 'select_form_id_search',
2588
                    ];
2589
                    $selectedValues = $this->parseAgendaFilter($filter);
2590
                    $this->showToForm($form, $selectedValues, $attributes);
2591
                    $form = $form->returnForm();
2592
                }
2593
            }
2594
        }
2595
2596
        if ('personal' === $this->type && !api_is_anonymous()) {
2597
            $actionsLeft .= Display::url(
2598
                Display::return_icon('1day.png', get_lang('Sessions plan calendar'), [], ICON_SIZE_MEDIUM),
2599
                $codePath."calendar/planification.php"
2600
            );
2601
2602
            if (api_is_student_boss() || api_is_platform_admin()) {
2603
                $actionsLeft .= Display::url(
2604
                    Display::return_icon('calendar-user.png', get_lang('MyStudentsSchedule'), [], ICON_SIZE_MEDIUM),
2605
                    $codePath.'mySpace/calendar_plan.php'
2606
                );
2607
            }
2608
        }
2609
2610
        if (api_is_platform_admin() ||
2611
            api_is_teacher() ||
2612
            api_is_student_boss() ||
2613
            api_is_drh() ||
2614
            api_is_session_admin() ||
2615
            api_is_coach()
2616
        ) {
2617
            if ('personal' === $this->type) {
2618
                $form = null;
2619
                if (!isset($_GET['action'])) {
2620
                    $form = new FormValidator(
2621
                        'form-search',
2622
                        'get',
2623
                        api_get_self().'?type=personal&',
2624
                        '',
2625
                        [],
2626
                        FormValidator::LAYOUT_INLINE
2627
                    );
2628
2629
                    $sessions = [];
2630
2631
                    if (api_is_drh()) {
2632
                        $sessionList = SessionManager::get_sessions_followed_by_drh($currentUserId);
2633
                        if (!empty($sessionList)) {
2634
                            foreach ($sessionList as $sessionItem) {
2635
                                $sessions[$sessionItem['id']] = strip_tags($sessionItem['name']);
2636
                            }
2637
                        }
2638
                    } else {
2639
                        $sessions = SessionManager::get_sessions_by_user($currentUserId);
2640
                        $sessions = array_column($sessions, 'session_name', 'session_id');
2641
                    }
2642
2643
                    $form->addHidden('type', 'personal');
2644
                    $sessions = ['0' => get_lang('Please select an option')] + $sessions;
2645
2646
                    $form->addSelect(
2647
                        'session_id',
2648
                        get_lang('Session'),
2649
                        $sessions,
2650
                        ['id' => 'session_id', 'onchange' => 'submit();']
2651
                    );
2652
2653
                    $form->addButtonReset(get_lang('Reset'));
2654
                    $form = $form->returnForm();
2655
                }
2656
            }
2657
        }
2658
2659
        $actionsRight = '';
2660
        if ('calendar' === $view) {
2661
            $actionsRight .= $form;
2662
        }
2663
2664
        return Display::toolbarAction(
2665
            'toolbar-agenda',
2666
            [$actionsLeft, $actionsRight]
2667
        );
2668
    }
2669
2670
    /**
2671
     * @return FormValidator
2672
     */
2673
    public function getImportCalendarForm()
2674
    {
2675
        $form = new FormValidator(
2676
            'frm_import_ical',
2677
            'post',
2678
            api_get_self().'?action=importical&type='.$this->type,
2679
            ['enctype' => 'multipart/form-data']
2680
        );
2681
        $form->addHeader(get_lang('Outlook import'));
2682
        $form->addElement('file', 'ical_import', get_lang('Outlook import'));
2683
        $form->addRule(
2684
            'ical_import',
2685
            get_lang('Required field'),
2686
            'required'
2687
        );
2688
        $form->addButtonImport(get_lang('Import'), 'ical_submit');
2689
2690
        return $form;
2691
    }
2692
2693
    /**
2694
     * @param array $courseInfo
2695
     * @param $file
2696
     *
2697
     * @return false|string
2698
     */
2699
    public function importEventFile($courseInfo, $file)
2700
    {
2701
        $charset = api_get_system_encoding();
2702
        $filepath = api_get_path(SYS_ARCHIVE_PATH).$file['name'];
2703
        $messages = [];
2704
2705
        if (!@move_uploaded_file($file['tmp_name'], $filepath)) {
2706
            error_log(
2707
                'Problem moving uploaded file: '.$file['error'].' in '.__FILE__.' line '.__LINE__
2708
            );
2709
2710
            return false;
2711
        }
2712
2713
        $data = file_get_contents($filepath);
2714
2715
        $trans = [
2716
            'DAILY' => 'daily',
2717
            'WEEKLY' => 'weekly',
2718
            'MONTHLY' => 'monthlyByDate',
2719
            'YEARLY' => 'yearly',
2720
        ];
2721
        $sentTo = ['everyone' => true];
2722
        $calendar = Sabre\VObject\Reader::read($data);
2723
        $currentTimeZone = api_get_timezone();
2724
        if (!empty($calendar->VEVENT)) {
2725
            foreach ($calendar->VEVENT as $event) {
2726
                $start = $event->DTSTART->getDateTime();
2727
                $end = $event->DTEND->getDateTime();
2728
                //Sabre\VObject\DateTimeParser::parseDateTime(string $dt, \Sabre\VObject\DateTimeZone $tz)
2729
2730
                $startDateTime = api_get_local_time(
2731
                    $start->format('Y-m-d H:i:s'),
2732
                    $currentTimeZone,
2733
                    $start->format('e')
2734
                );
2735
                $endDateTime = api_get_local_time(
2736
                    $end->format('Y-m-d H:i'),
2737
                    $currentTimeZone,
2738
                    $end->format('e')
2739
                );
2740
                $title = api_convert_encoding(
2741
                    (string) $event->summary,
2742
                    $charset,
2743
                    'UTF-8'
2744
                );
2745
                $description = api_convert_encoding(
2746
                    (string) $event->description,
2747
                    $charset,
2748
                    'UTF-8'
2749
                );
2750
2751
                $id = $this->addEvent(
2752
                    $startDateTime,
2753
                    $endDateTime,
2754
                    'false',
2755
                    $title,
2756
                    $description,
2757
                    $sentTo
2758
                );
2759
2760
                $messages[] = " $title - ".$startDateTime." - ".$endDateTime;
2761
2762
                //$attendee = (string)$event->attendee;
2763
                /** @var Sabre\VObject\Property\ICalendar\Recur $repeat */
2764
                $repeat = $event->RRULE;
2765
                if ($id && !empty($repeat)) {
2766
                    $repeat = $repeat->getParts();
2767
                    $freq = $trans[$repeat['FREQ']];
2768
2769
                    if (isset($repeat['UNTIL']) && !empty($repeat['UNTIL'])) {
2770
                        // Check if datetime or just date (strlen == 8)
2771
                        if (8 == strlen($repeat['UNTIL'])) {
2772
                            // Fix the datetime format to avoid exception in the next step
2773
                            $repeat['UNTIL'] .= 'T000000';
2774
                        }
2775
                        $until = Sabre\VObject\DateTimeParser::parseDateTime(
2776
                            $repeat['UNTIL'],
2777
                            new DateTimeZone($currentTimeZone)
2778
                        );
2779
                        $until = $until->format('Y-m-d H:i:s');
2780
                        $this->addRepeatedItem(
2781
                            $id,
2782
                            $freq,
2783
                            $until,
2784
                            $sentTo
2785
                        );
2786
                    }
2787
                }
2788
            }
2789
        }
2790
2791
        if (!empty($messages)) {
2792
            $messages = implode('<br /> ', $messages);
2793
        } else {
2794
            $messages = get_lang('There are no events');
2795
        }
2796
2797
        return $messages;
2798
    }
2799
2800
    /**
2801
     * Parse filter turns USER:12 to ['users' => [12])] or G:1 ['groups' => [1]].
2802
     *
2803
     * @param int $filter
2804
     *
2805
     * @return array
2806
     */
2807
    public function parseAgendaFilter($filter)
2808
    {
2809
        $everyone = false;
2810
        $groupId = null;
2811
        $userId = null;
2812
2813
        if ('everyone' === $filter) {
2814
            $everyone = true;
2815
        } else {
2816
            if ('G' === substr($filter, 0, 1)) {
2817
                $groupId = str_replace('GROUP:', '', $filter);
2818
            } else {
2819
                $userId = str_replace('USER:', '', $filter);
2820
            }
2821
        }
2822
        if (empty($userId) && empty($groupId)) {
2823
            $everyone = true;
2824
        }
2825
2826
        return [
2827
            'everyone' => $everyone,
2828
            'users' => [$userId],
2829
            'groups' => [$groupId],
2830
        ];
2831
    }
2832
2833
    /**
2834
     * @deprecated
2835
     *    This function retrieves all the agenda items of all the courses the user is subscribed to.
2836
     */
2837
    public static function get_myagendaitems(
2838
        $user_id,
2839
        $courses_dbs,
2840
        $month,
2841
        $year
2842
    ) {
2843
        $user_id = (int) $user_id;
2844
2845
        $items = [];
2846
        $my_list = [];
2847
        throw new Exception('@todo get_myagendaitems');
2848
2849
        /*
2850
        // get agenda-items for every course
2851
        foreach ($courses_dbs as $key => $array_course_info) {
2852
            //databases of the courses
2853
            $TABLEAGENDA = Database::get_course_table(TABLE_AGENDA);
2854
            $TABLE_ITEMPROPERTY = Database::get_course_table(
2855
                TABLE_ITEM_PROPERTY
2856
            );
2857
2858
            $group_memberships = GroupManager::get_group_ids(
2859
                $array_course_info['real_id'],
2860
                $user_id
2861
            );
2862
            $course_user_status = CourseManager::getUserInCourseStatus(
2863
                $user_id,
2864
                $array_course_info['real_id']
2865
            );
2866
            // if the user is administrator of that course we show all the agenda items
2867
            if ('1' == $course_user_status) {
2868
                //echo "course admin";
2869
                $sqlquery = "SELECT DISTINCT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref
2870
							FROM ".$TABLEAGENDA." agenda,
2871
								 ".$TABLE_ITEMPROPERTY." ip
2872
							WHERE agenda.id = ip.ref
2873
							AND MONTH(agenda.start_date)='".$month."'
2874
							AND YEAR(agenda.start_date)='".$year."'
2875
							AND ip.tool='".TOOL_CALENDAR_EVENT."'
2876
							AND ip.visibility='1'
2877
							GROUP BY agenda.id
2878
							ORDER BY start_date ";
2879
            } else {
2880
                // if the user is not an administrator of that course
2881
                if (is_array($group_memberships) && count(
2882
                        $group_memberships
2883
                    ) > 0
2884
                ) {
2885
                    $sqlquery = "SELECT	agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref
2886
								FROM ".$TABLEAGENDA." agenda,
2887
									".$TABLE_ITEMPROPERTY." ip
2888
								WHERE agenda.id = ip.ref
2889
								AND MONTH(agenda.start_date)='".$month."'
2890
								AND YEAR(agenda.start_date)='".$year."'
2891
								AND ip.tool='".TOOL_CALENDAR_EVENT."'
2892
								AND	( ip.to_user_id='".$user_id."' OR (ip.to_group_id IS NULL OR ip.to_group_id IN (0, ".implode(
2893
                            ", ",
2894
                            $group_memberships
2895
                        ).")) )
2896
								AND ip.visibility='1'
2897
								ORDER BY start_date ";
2898
                } else {
2899
                    $sqlquery = "SELECT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref
2900
								FROM ".$TABLEAGENDA." agenda,
2901
									".$TABLE_ITEMPROPERTY." ip
2902
								WHERE agenda.id = ip.ref
2903
								AND MONTH(agenda.start_date)='".$month."'
2904
								AND YEAR(agenda.start_date)='".$year."'
2905
								AND ip.tool='".TOOL_CALENDAR_EVENT."'
2906
								AND ( ip.to_user_id='".$user_id."' OR ip.to_group_id='0' OR ip.to_group_id IS NULL)
2907
								AND ip.visibility='1'
2908
								ORDER BY start_date ";
2909
                }
2910
            }
2911
            $result = Database::query($sqlquery);
2912
2913
            while ($item = Database::fetch_array($result, 'ASSOC')) {
2914
                $agendaday = -1;
2915
                if (!empty($item['start_date'])) {
2916
                    $item['start_date'] = api_get_local_time(
2917
                        $item['start_date']
2918
                    );
2919
                    $item['start_date_tms'] = api_strtotime(
2920
                        $item['start_date']
2921
                    );
2922
                    $agendaday = date("j", $item['start_date_tms']);
2923
                }
2924
                if (!empty($item['end_date'])) {
2925
                    $item['end_date'] = api_get_local_time($item['end_date']);
2926
                }
2927
2928
                $url = api_get_path(
2929
                        WEB_CODE_PATH
2930
                    )."calendar/agenda.php?cidReq=".urlencode(
2931
                        $array_course_info["code"]
2932
                    )."&day=$agendaday&month=$month&year=$year#$agendaday";
2933
2934
                $item['url'] = $url;
2935
                $item['course_name'] = $array_course_info['title'];
2936
                $item['calendar_type'] = 'course';
2937
                $item['course_id'] = $array_course_info['course_id'];
2938
2939
                $my_list[$agendaday][] = $item;
2940
            }
2941
        }
2942
2943
        // sorting by hour for every day
2944
        $agendaitems = [];
2945
        foreach ($items as $agendaday => $tmpitems) {
2946
            if (!isset($agendaitems[$agendaday])) {
2947
                $agendaitems[$agendaday] = '';
2948
            }
2949
            sort($tmpitems);
2950
            foreach ($tmpitems as $val) {
2951
                $agendaitems[$agendaday] .= $val;
2952
            }
2953
        }*/
2954
2955
        return $my_list;
0 ignored issues
show
Unused Code introduced by
return $my_list is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
2956
    }
2957
2958
    /**
2959
     * This function retrieves one personal agenda item returns it.
2960
     *
2961
     * @param    array    The array containing existing events. We add to this array.
2962
     * @param    int        Day
2963
     * @param    int        Month
2964
     * @param    int        Year (4 digits)
2965
     * @param    int        Week number
2966
     * @param    string    Type of view (month_view, week_view, day_view)
2967
     *
2968
     * @return array The results of the database query, or null if not found
2969
     */
2970
    public static function get_global_agenda_items(
2971
        $agendaitems,
2972
        $day,
2973
        $month,
2974
        $year,
2975
        $week,
2976
        $type
2977
    ) {
2978
        $tbl_global_agenda = Database::get_main_table(
2979
            TABLE_MAIN_SYSTEM_CALENDAR
2980
        );
2981
        $month = intval($month);
2982
        $year = intval($year);
2983
        $week = intval($week);
2984
        $day = intval($day);
2985
        // 1. creating the SQL statement for getting the personal agenda items in MONTH view
2986
2987
        $current_access_url_id = api_get_current_access_url_id();
2988
2989
        if ("month_view" == $type or "" == $type) {
2990
            // We are in month view
2991
            $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";
2992
        }
2993
        // 2. creating the SQL statement for getting the personal agenda items in WEEK view
2994
        if ("week_view" == $type) { // we are in week view
2995
            $start_end_day_of_week = self::calculate_start_end_of_week(
2996
                $week,
2997
                $year
2998
            );
2999
            $start_day = $start_end_day_of_week['start']['day'];
3000
            $start_month = $start_end_day_of_week['start']['month'];
3001
            $start_year = $start_end_day_of_week['start']['year'];
3002
            $end_day = $start_end_day_of_week['end']['day'];
3003
            $end_month = $start_end_day_of_week['end']['month'];
3004
            $end_year = $start_end_day_of_week['end']['year'];
3005
            // in sql statements you have to use year-month-day for date calculations
3006
            $start_filter = $start_year."-".$start_month."-".$start_day." 00:00:00";
3007
            $start_filter = api_get_utc_datetime($start_filter);
3008
3009
            $end_filter = $end_year."-".$end_month."-".$end_day." 23:59:59";
3010
            $end_filter = api_get_utc_datetime($end_filter);
3011
            $sql = " SELECT * FROM ".$tbl_global_agenda." WHERE start_date>='".$start_filter."' AND start_date<='".$end_filter."' AND  access_url_id = $current_access_url_id ";
3012
        }
3013
        // 3. creating the SQL statement for getting the personal agenda items in DAY view
3014
        if ("day_view" == $type) { // we are in day view
3015
            // we could use mysql date() function but this is only available from 4.1 and higher
3016
            $start_filter = $year."-".$month."-".$day." 00:00:00";
3017
            $start_filter = api_get_utc_datetime($start_filter);
3018
3019
            $end_filter = $year."-".$month."-".$day." 23:59:59";
3020
            $end_filter = api_get_utc_datetime($end_filter);
3021
            $sql = " SELECT * FROM ".$tbl_global_agenda." WHERE start_date>='".$start_filter."' AND start_date<='".$end_filter."'  AND  access_url_id = $current_access_url_id";
3022
        }
3023
3024
        $result = Database::query($sql);
3025
3026
        while ($item = Database::fetch_array($result)) {
3027
            if (!empty($item['start_date'])) {
3028
                $item['start_date'] = api_get_local_time($item['start_date']);
3029
                $item['start_date_tms'] = api_strtotime($item['start_date']);
3030
            }
3031
            if (!empty($item['end_date'])) {
3032
                $item['end_date'] = api_get_local_time($item['end_date']);
3033
            }
3034
3035
            // we break the date field in the database into a date and a time part
3036
            $agenda_db_date = explode(" ", $item['start_date']);
3037
            $date = $agenda_db_date[0];
3038
            $time = $agenda_db_date[1];
3039
            // we divide the date part into a day, a month and a year
3040
            $agendadate = explode("-", $date);
3041
            $year = intval($agendadate[0]);
3042
            $month = intval($agendadate[1]);
3043
            $day = intval($agendadate[2]);
3044
            // we divide the time part into hour, minutes, seconds
3045
            $agendatime = explode(":", $time);
3046
            $hour = $agendatime[0];
3047
            $minute = $agendatime[1];
3048
            $second = $agendatime[2];
3049
3050
            if ('month_view' == $type) {
3051
                $item['calendar_type'] = 'global';
3052
                $agendaitems[$day][] = $item;
3053
                continue;
3054
            }
3055
3056
            $start_time = api_format_date(
3057
                $item['start_date'],
3058
                TIME_NO_SEC_FORMAT
3059
            );
3060
            $end_time = '';
3061
            if (!empty($item['end_date'])) {
3062
                $end_time = ' - '.api_format_date(
3063
                        $item['end_date'],
3064
                        DATE_TIME_FORMAT_LONG
3065
                    );
3066
            }
3067
3068
            // Creating the array that will be returned. If we have week or month view we have an array with the date as the key
3069
            // if we have a day_view we use a half hour as index => key 33 = 16h30
3070
            if ("day_view" !== $type) {
3071
                // This is the array construction for the WEEK or MONTH view
3072
                //Display the Agenda global in the tab agenda (administrator)
3073
                $agendaitems[$day] .= "<i>$start_time $end_time</i>&nbsp;-&nbsp;";
3074
                $agendaitems[$day] .= "<b>".get_lang('Platform event')."</b>";
3075
                $agendaitems[$day] .= "<div>".$item['title']."</div><br>";
3076
            } else {
3077
                // this is the array construction for the DAY view
3078
                $halfhour = 2 * $agendatime['0'];
3079
                if ($agendatime['1'] >= '30') {
3080
                    $halfhour = $halfhour + 1;
3081
                }
3082
                if (!is_array($agendaitems[$halfhour])) {
3083
                    $content = $agendaitems[$halfhour];
3084
                }
3085
                $agendaitems[$halfhour] = $content."<div><i>$hour:$minute</i> <b>".get_lang(
3086
                        'Platform event'
3087
                    ).":  </b>".$item['title']."</div>";
3088
            }
3089
        }
3090
3091
        return $agendaitems;
3092
    }
3093
3094
    /**
3095
     * This function retrieves all the personal agenda items and add them to the agenda items found by the other
3096
     * functions.
3097
     */
3098
    public static function get_personal_agenda_items(
3099
        $user_id,
3100
        $agendaitems,
3101
        $day,
3102
        $month,
3103
        $year,
3104
        $week,
3105
        $type
3106
    ) {
3107
        $tbl_personal_agenda = Database::get_main_table(TABLE_PERSONAL_AGENDA);
3108
        $user_id = (int) $user_id;
3109
        $course_link = '';
3110
        // 1. creating the SQL statement for getting the personal agenda items in MONTH view
3111
        if ("month_view" === $type || "" == $type) {
3112
            // we are in month view
3113
            $sql = "SELECT * FROM ".$tbl_personal_agenda."
3114
                    WHERE user='".$user_id."' and MONTH(date)='".$month."' AND YEAR(date) = '".$year."'
3115
                    ORDER BY date ASC";
3116
        }
3117
3118
        // 2. creating the SQL statement for getting the personal agenda items in WEEK view
3119
        // we are in week view
3120
        if ("week_view" === $type) {
3121
            $start_end_day_of_week = self::calculate_start_end_of_week(
3122
                $week,
3123
                $year
3124
            );
3125
            $start_day = $start_end_day_of_week['start']['day'];
3126
            $start_month = $start_end_day_of_week['start']['month'];
3127
            $start_year = $start_end_day_of_week['start']['year'];
3128
            $end_day = $start_end_day_of_week['end']['day'];
3129
            $end_month = $start_end_day_of_week['end']['month'];
3130
            $end_year = $start_end_day_of_week['end']['year'];
3131
            // in sql statements you have to use year-month-day for date calculations
3132
            $start_filter = $start_year."-".$start_month."-".$start_day." 00:00:00";
3133
            $start_filter = api_get_utc_datetime($start_filter);
3134
            $end_filter = $end_year."-".$end_month."-".$end_day." 23:59:59";
3135
            $end_filter = api_get_utc_datetime($end_filter);
3136
            $sql = "SELECT * FROM ".$tbl_personal_agenda."
3137
                    WHERE user='".$user_id."' AND date>='".$start_filter."' AND date<='".$end_filter."'";
3138
        }
3139
        // 3. creating the SQL statement for getting the personal agenda items in DAY view
3140
        if ("day_view" === $type) {
3141
            // we are in day view
3142
            // we could use mysql date() function but this is only available from 4.1 and higher
3143
            $start_filter = $year."-".$month."-".$day." 00:00:00";
3144
            $start_filter = api_get_utc_datetime($start_filter);
3145
            $end_filter = $year."-".$month."-".$day." 23:59:59";
3146
            $end_filter = api_get_utc_datetime($end_filter);
3147
            $sql = "SELECT * FROM ".$tbl_personal_agenda."
3148
                    WHERE user='".$user_id."' AND date>='".$start_filter."' AND date<='".$end_filter."'";
3149
        }
3150
3151
        $result = Database::query($sql);
3152
        while ($item = Database::fetch_array($result, 'ASSOC')) {
3153
            $time_minute = api_convert_and_format_date(
3154
                $item['date'],
3155
                TIME_NO_SEC_FORMAT
3156
            );
3157
            $item['date'] = api_get_local_time($item['date']);
3158
            $item['start_date_tms'] = api_strtotime($item['date']);
3159
            $item['content'] = $item['text'];
3160
3161
            // we break the date field in the database into a date and a time part
3162
            $agenda_db_date = explode(" ", $item['date']);
3163
            $date = $agenda_db_date[0];
3164
            $time = $agenda_db_date[1];
3165
            // we divide the date part into a day, a month and a year
3166
            $agendadate = explode("-", $item['date']);
3167
            $year = intval($agendadate[0]);
3168
            $month = intval($agendadate[1]);
3169
            $day = intval($agendadate[2]);
3170
            // we divide the time part into hour, minutes, seconds
3171
            $agendatime = explode(":", $time);
3172
3173
            $hour = $agendatime[0];
3174
            $minute = $agendatime[1];
3175
            $second = $agendatime[2];
3176
3177
            if ('month_view' === $type) {
3178
                $item['calendar_type'] = 'personal';
3179
                $item['start_date'] = $item['date'];
3180
                $agendaitems[$day][] = $item;
3181
                continue;
3182
            }
3183
3184
            // Creating the array that will be returned.
3185
            // If we have week or month view we have an array with the date as the key
3186
            // if we have a day_view we use a half hour as index => key 33 = 16h30
3187
            if ("day_view" !== $type) {
3188
                // This is the array construction for the WEEK or MONTH view
3189
3190
                //Display events in agenda
3191
                $agendaitems[$day] .= "<div>
3192
                     <i>$time_minute</i> $course_link
3193
                     <a href=\"myagenda.php?action=view&view=personal&day=$day&month=$month&year=$year&id=".$item['id']."#".$item['id']."\" class=\"personal_agenda\">".
3194
                    $item['title']."</a></div><br />";
3195
            } else {
3196
                // this is the array construction for the DAY view
3197
                $halfhour = 2 * $agendatime['0'];
3198
                if ($agendatime['1'] >= '30') {
3199
                    $halfhour = $halfhour + 1;
3200
                }
3201
3202
                //Display events by list
3203
                $agendaitems[$halfhour] .= "<div>
3204
                    <i>$time_minute</i> $course_link
3205
                    <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>";
3206
            }
3207
        }
3208
3209
        return $agendaitems;
3210
    }
3211
3212
    /**
3213
     * Show the month calendar of the given month.
3214
     *
3215
     * @param    array    Agendaitems
3216
     * @param    int    Month number
3217
     * @param    int    Year number
3218
     * @param    array    Array of strings containing long week day names (deprecated, you can send an empty array
3219
     *                          instead)
3220
     * @param    string    The month name
3221
     */
3222
    public static function display_mymonthcalendar(
3223
        $user_id,
3224
        $agendaitems,
3225
        $month,
3226
        $year,
3227
        $weekdaynames,
3228
        $monthName,
3229
        $show_content = true
3230
    ) {
3231
        global $DaysShort, $course_path;
3232
        //Handle leap year
3233
        $numberofdays = [
3234
            0,
3235
            31,
3236
            28,
3237
            31,
3238
            30,
3239
            31,
3240
            30,
3241
            31,
3242
            31,
3243
            30,
3244
            31,
3245
            30,
3246
            31,
3247
        ];
3248
        if ((0 == $year % 400) or (0 == $year % 4 and 0 != $year % 100)) {
3249
            $numberofdays[2] = 29;
3250
        }
3251
        //Get the first day of the month
3252
        $dayone = getdate(mktime(0, 0, 0, $month, 1, $year));
3253
        //Start the week on monday
3254
        $startdayofweek = 0 != $dayone['wday'] ? ($dayone['wday'] - 1) : 6;
3255
        $g_cc = (isset($_GET['courseCode']) ? $_GET['courseCode'] : '');
3256
3257
        $next_month = (1 == $month ? 12 : $month - 1);
3258
        $prev_month = (12 == $month ? 1 : $month + 1);
3259
3260
        $next_year = (1 == $month ? $year - 1 : $year);
3261
        $prev_year = (12 == $month ? $year + 1 : $year);
3262
3263
        if ($show_content) {
3264
            $back_url = Display::url(
3265
                get_lang('Previous'),
3266
                api_get_self()."?coursePath=".urlencode(
3267
                    $course_path
3268
                )."&courseCode=".Security::remove_XSS(
3269
                    $g_cc
3270
                )."&action=view&view=month&month=".$next_month."&year=".$next_year
3271
            );
3272
            $next_url = Display::url(
3273
                get_lang('Next'),
3274
                api_get_self()."?coursePath=".urlencode(
3275
                    $course_path
3276
                )."&courseCode=".Security::remove_XSS(
3277
                    $g_cc
3278
                )."&action=view&view=month&month=".$prev_month."&year=".$prev_year
3279
            );
3280
        } else {
3281
            $back_url = Display::url(
3282
                get_lang('Previous'),
3283
                '',
3284
                [
3285
                    'onclick' => "load_calendar('".$user_id."','".$next_month."', '".$next_year."'); ",
3286
                    'class' => 'btn ui-button ui-widget ui-state-default',
3287
                ]
3288
            );
3289
            $next_url = Display::url(
3290
                get_lang('Next'),
3291
                '',
3292
                [
3293
                    'onclick' => "load_calendar('".$user_id."','".$prev_month."', '".$prev_year."'); ",
3294
                    'class' => 'pull-right btn ui-button ui-widget ui-state-default',
3295
                ]
3296
            );
3297
        }
3298
        $html = '';
3299
        $html .= '<div class="actions">';
3300
        $html .= '<div class="row">';
3301
        $html .= '<div class="col-md-4">'.$back_url.'</div>';
3302
        $html .= '<div class="col-md-4"><p class="agenda-title text-center">'.$monthName." ".$year.'</p></div>';
3303
        $html .= '<div class="col-md-4">'.$next_url.'</div>';
3304
        $html .= '</div>';
3305
        $html .= '</div>';
3306
        $html .= '<table id="agenda_list2" class="table table-bordered">';
3307
        $html .= '<tr>';
3308
        for ($ii = 1; $ii < 8; $ii++) {
3309
            $html .= '<td class="weekdays">'.$DaysShort[$ii % 7].'</td>';
3310
        }
3311
        $html .= '</tr>';
3312
3313
        $curday = -1;
3314
        $today = getdate();
3315
        while ($curday <= $numberofdays[$month]) {
3316
            $html .= "<tr>";
3317
            for ($ii = 0; $ii < 7; $ii++) {
3318
                if ((-1 == $curday) && ($ii == $startdayofweek)) {
3319
                    $curday = 1;
3320
                }
3321
                if (($curday > 0) && ($curday <= $numberofdays[$month])) {
3322
                    $bgcolor = $class = 'class="days_week"';
3323
                    $dayheader = Display::div(
3324
                        $curday,
3325
                        ['class' => 'agenda_day']
3326
                    );
3327
                    if (($curday == $today['mday']) && ($year == $today['year']) && ($month == $today['mon'])) {
3328
                        $class = "class=\"days_today\" style=\"width:10%;\"";
3329
                    }
3330
3331
                    $html .= "<td ".$class.">".$dayheader;
3332
3333
                    if (!empty($agendaitems[$curday])) {
3334
                        $items = $agendaitems[$curday];
3335
                        $items = msort($items, 'start_date_tms');
3336
3337
                        foreach ($items as $value) {
3338
                            $value['title'] = Security::remove_XSS(
3339
                                $value['title']
3340
                            );
3341
                            $start_time = api_format_date(
3342
                                $value['start_date'],
3343
                                TIME_NO_SEC_FORMAT
3344
                            );
3345
                            $end_time = '';
3346
3347
                            if (!empty($value['end_date'])) {
3348
                                $end_time = '-&nbsp;<i>'.api_format_date(
3349
                                        $value['end_date'],
3350
                                        DATE_TIME_FORMAT_LONG
3351
                                    ).'</i>';
3352
                            }
3353
                            $complete_time = '<i>'.api_format_date(
3354
                                    $value['start_date'],
3355
                                    DATE_TIME_FORMAT_LONG
3356
                                ).'</i>&nbsp;'.$end_time;
3357
                            $time = '<i>'.$start_time.'</i>';
3358
3359
                            switch ($value['calendar_type']) {
3360
                                case 'personal':
3361
                                    $bg_color = '#D0E7F4';
3362
                                    $icon = Display::return_icon(
3363
                                        'user.png',
3364
                                        get_lang('Personal agenda'),
3365
                                        [],
3366
                                        ICON_SIZE_SMALL
3367
                                    );
3368
                                    break;
3369
                                case 'global':
3370
                                    $bg_color = '#FFBC89';
3371
                                    $icon = Display::return_icon(
3372
                                        'view_remove.png',
3373
                                        get_lang('Platform event'),
3374
                                        [],
3375
                                        ICON_SIZE_SMALL
3376
                                    );
3377
                                    break;
3378
                                case 'course':
3379
                                    $bg_color = '#CAFFAA';
3380
                                    $icon_name = 'course.png';
3381
                                    if (!empty($value['session_id'])) {
3382
                                        $icon_name = 'session.png';
3383
                                    }
3384
                                    if ($show_content) {
3385
                                        $icon = Display::url(
3386
                                            Display::return_icon(
3387
                                                $icon_name,
3388
                                                $value['course_name'].' '.get_lang(
3389
                                                    'Course'
3390
                                                ),
3391
                                                [],
3392
                                                ICON_SIZE_SMALL
3393
                                            ),
3394
                                            $value['url']
3395
                                        );
3396
                                    } else {
3397
                                        $icon = Display::return_icon(
3398
                                            $icon_name,
3399
                                            $value['course_name'].' '.get_lang(
3400
                                                'Course'
3401
                                            ),
3402
                                            [],
3403
                                            ICON_SIZE_SMALL
3404
                                        );
3405
                                    }
3406
                                    break;
3407
                                default:
3408
                                    break;
3409
                            }
3410
3411
                            $result = '<div class="rounded_div_agenda" style="background-color:'.$bg_color.';">';
3412
3413
                            if ($show_content) {
3414
                                //Setting a personal event to green
3415
                                $icon = Display::div(
3416
                                    $icon,
3417
                                    ['style' => 'float:right']
3418
                                );
3419
3420
                                $link = $value['calendar_type'].'_'.$value['id'].'_'.$value['course_id'].'_'.$value['session_id'];
3421
3422
                                //Link to bubble
3423
                                $url = Display::url(
3424
                                    cut($value['title'], 40),
3425
                                    '#',
3426
                                    ['id' => $link, 'class' => 'opener']
3427
                                );
3428
                                $result .= $time.' '.$icon.' '.Display::div(
3429
                                        $url
3430
                                    );
3431
3432
                                //Hidden content
3433
                                $content = Display::div(
3434
                                    $icon.Display::tag(
3435
                                        'h2',
3436
                                        $value['course_name']
3437
                                    ).'<hr />'.Display::tag(
3438
                                        'h3',
3439
                                        $value['title']
3440
                                    ).$complete_time.'<hr />'.Security::remove_XSS(
3441
                                        $value['content']
3442
                                    )
3443
                                );
3444
3445
                                //Main div
3446
                                $result .= Display::div(
3447
                                    $content,
3448
                                    [
3449
                                        'id' => 'main_'.$link,
3450
                                        'class' => 'dialog',
3451
                                        'style' => 'display:none',
3452
                                    ]
3453
                                );
3454
                                $result .= '</div>';
3455
                                $html .= $result;
3456
                            } else {
3457
                                $html .= $result .= $icon.'</div>';
3458
                            }
3459
                        }
3460
                    }
3461
                    $html .= "</td>";
3462
                    $curday++;
3463
                } else {
3464
                    $html .= "<td></td>";
3465
                }
3466
            }
3467
            $html .= "</tr>";
3468
        }
3469
        $html .= "</table>";
3470
        echo $html;
3471
    }
3472
3473
    /**
3474
     * Get personal agenda items between two dates (=all events from all registered courses).
3475
     *
3476
     * @param int $user_id user ID of the user
3477
     * @param    string    Optional start date in datetime format (if no start date is given, uses today)
3478
     * @param    string    Optional end date in datetime format (if no date is given, uses one year from now)
3479
     *
3480
     * @return array array of events ordered by start date, in
3481
     *               [0]('datestart','dateend','title'),[1]('datestart','dateend','title','link','coursetitle') format,
3482
     *               where datestart and dateend are in yyyyMMddhhmmss format
3483
     *
3484
     * @deprecated use agenda events
3485
     */
3486
    public static function get_personal_agenda_items_between_dates($user_id, $date_start = '', $date_end = '')
3487
    {
3488
        throw new Exception('fix get_personal_agenda_items_between_dates');
3489
        /*
3490
        $items = [];
3491
        if ($user_id != strval(intval($user_id))) {
3492
            return $items;
3493
        }
3494
        if (empty($date_start)) {
3495
            $date_start = date('Y-m-d H:i:s');
3496
        }
3497
        if (empty($date_end)) {
3498
            $date_end = date(
3499
                'Y-m-d H:i:s',
3500
                mktime(0, 0, 0, date("m"), date("d"), date("Y") + 1)
3501
            );
3502
        }
3503
        $expr = '/\d{4}-\d{2}-\d{2}\ \d{2}:\d{2}:\d{2}/';
3504
        if (!preg_match($expr, $date_start)) {
3505
            return $items;
3506
        }
3507
        if (!preg_match($expr, $date_end)) {
3508
            return $items;
3509
        }
3510
3511
        // get agenda-items for every course
3512
        //$courses = api_get_user_courses($user_id, false);
3513
        $courses = CourseManager::get_courses_list_by_user_id($user_id, false);
3514
        foreach ($courses as $id => $course) {
3515
            $c = api_get_course_info_by_id($course['real_id']);
3516
            $t_a = Database::get_course_table(TABLE_AGENDA, $course['db']);
3517
            $t_ip = Database::get_course_table(
3518
                TABLE_ITEM_PROPERTY,
3519
                $course['db']
3520
            );
3521
            // get the groups to which the user belong
3522
            $group_memberships = GroupManager:: get_group_ids(
3523
                $course['db'],
3524
                $user_id
3525
            );
3526
            // if the user is administrator of that course we show all the agenda items
3527
            if ('1' == $course['status']) {
3528
                //echo "course admin";
3529
                $sqlquery = "SELECT ".
3530
                    " DISTINCT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref ".
3531
                    " FROM ".$t_a." agenda, ".
3532
                    $t_ip." ip ".
3533
                    " WHERE agenda.id = ip.ref ".
3534
                    " AND agenda.start_date>='$date_start' ".
3535
                    " AND agenda.end_date<='$date_end' ".
3536
                    " AND ip.tool='".TOOL_CALENDAR_EVENT."' ".
3537
                    " AND ip.visibility='1' ".
3538
                    " GROUP BY agenda.id ".
3539
                    " ORDER BY start_date ";
3540
            } else {
3541
                // if the user is not an administrator of that course, then...
3542
                if (is_array($group_memberships) && count(
3543
                        $group_memberships
3544
                    ) > 0
3545
                ) {
3546
                    $sqlquery = "SELECT ".
3547
                        "DISTINCT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref ".
3548
                        " FROM ".$t_a." agenda, ".
3549
                        $t_ip." ip ".
3550
                        " WHERE agenda.id = ip.ref ".
3551
                        " AND agenda.start_date>='$date_start' ".
3552
                        " AND agenda.end_date<='$date_end' ".
3553
                        " AND ip.tool='".TOOL_CALENDAR_EVENT."' ".
3554
                        " AND	( ip.to_user_id='".$user_id."' OR (ip.to_group_id IS NULL OR ip.to_group_id IN (0, ".implode(
3555
                            ", ",
3556
                            $group_memberships
3557
                        ).")) ) ".
3558
                        " AND ip.visibility='1' ".
3559
                        " ORDER BY start_date ";
3560
                } else {
3561
                    $sqlquery = "SELECT ".
3562
                        "DISTINCT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref ".
3563
                        " FROM ".$t_a." agenda, ".
3564
                        $t_ip." ip ".
3565
                        " WHERE agenda.id = ip.ref ".
3566
                        " AND agenda.start_date>='$date_start' ".
3567
                        " AND agenda.end_date<='$date_end' ".
3568
                        " AND ip.tool='".TOOL_CALENDAR_EVENT."' ".
3569
                        " AND ( ip.to_user_id='".$user_id."' OR ip.to_group_id='0' OR ip.to_group_id IS NULL) ".
3570
                        " AND ip.visibility='1' ".
3571
                        " ORDER BY start_date ";
3572
                }
3573
            }
3574
3575
            $result = Database::query($sqlquery);
3576
            while ($item = Database::fetch_array($result)) {
3577
                $agendaday = date("j", strtotime($item['start_date']));
3578
                $month = date("n", strtotime($item['start_date']));
3579
                $year = date("Y", strtotime($item['start_date']));
3580
                $URL = api_get_path(
3581
                        WEB_PATH
3582
                    )."main/calendar/agenda.php?cidReq=".urlencode(
3583
                        $course["code"]
3584
                    )."&day=$agendaday&month=$month&year=$year#$agendaday";
3585
                [$year, $month, $day, $hour, $min, $sec] = explode(
3586
                    '[-: ]',
3587
                    $item['start_date']
3588
                );
3589
                $start_date = $year.$month.$day.$hour.$min;
3590
                [$year, $month, $day, $hour, $min, $sec] = explode(
3591
                    '[-: ]',
3592
                    $item['end_date']
3593
                );
3594
                $end_date = $year.$month.$day.$hour.$min;
3595
3596
                $items[] = [
3597
                    'datestart' => $start_date,
3598
                    'dateend' => $end_date,
3599
                    'title' => $item['title'],
3600
                    'link' => $URL,
3601
                    'coursetitle' => $c['name'],
3602
                ];
3603
            }
3604
        }
3605
3606
        return $items;*/
3607
    }
3608
3609
    /**
3610
     * This function calculates the startdate of the week (monday)
3611
     * and the enddate of the week (sunday)
3612
     * and returns it as an array.
3613
     */
3614
    public static function calculate_start_end_of_week($week_number, $year)
3615
    {
3616
        // determine the start and end date
3617
        // step 1: we calculate a timestamp for a day in this week
3618
        $random_day_in_week = mktime(
3619
                0,
3620
                0,
3621
                0,
3622
                1,
3623
                1,
3624
                $year
3625
            ) + ($week_number) * (7 * 24 * 60 * 60); // we calculate a random day in this week
3626
        // step 2: we which day this is (0=sunday, 1=monday, ...)
3627
        $number_day_in_week = date('w', $random_day_in_week);
3628
        // step 3: we calculate the timestamp of the monday of the week we are in
3629
        $start_timestamp = $random_day_in_week - (($number_day_in_week - 1) * 24 * 60 * 60);
3630
        // step 4: we calculate the timestamp of the sunday of the week we are in
3631
        $end_timestamp = $random_day_in_week + ((7 - $number_day_in_week + 1) * 24 * 60 * 60) - 3600;
3632
        // step 5: calculating the start_day, end_day, start_month, end_month, start_year, end_year
3633
        $start_day = date('j', $start_timestamp);
3634
        $start_month = date('n', $start_timestamp);
3635
        $start_year = date('Y', $start_timestamp);
3636
        $end_day = date('j', $end_timestamp);
3637
        $end_month = date('n', $end_timestamp);
3638
        $end_year = date('Y', $end_timestamp);
3639
        $start_end_array['start']['day'] = $start_day;
3640
        $start_end_array['start']['month'] = $start_month;
3641
        $start_end_array['start']['year'] = $start_year;
3642
        $start_end_array['end']['day'] = $end_day;
3643
        $start_end_array['end']['month'] = $end_month;
3644
        $start_end_array['end']['year'] = $end_year;
3645
3646
        return $start_end_array;
3647
    }
3648
3649
    /**
3650
     * @return bool
3651
     */
3652
    public function getIsAllowedToEdit()
3653
    {
3654
        return $this->isAllowedToEdit;
3655
    }
3656
3657
    /**
3658
     * @param bool $isAllowedToEdit
3659
     */
3660
    public function setIsAllowedToEdit($isAllowedToEdit)
3661
    {
3662
        $this->isAllowedToEdit = $isAllowedToEdit;
3663
    }
3664
3665
    /**
3666
     * Format needed for the Fullcalendar js lib.
3667
     *
3668
     * @param string $utcTime
3669
     *
3670
     * @return bool|string
3671
     */
3672
    public function formatEventDate($utcTime)
3673
    {
3674
        $utcTimeZone = new DateTimeZone('UTC');
3675
        $platformTimeZone = new DateTimeZone(api_get_timezone());
3676
3677
        $eventDate = new DateTime($utcTime, $utcTimeZone);
3678
        $eventDate->setTimezone($platformTimeZone);
3679
3680
        return $eventDate->format(DateTime::ISO8601);
3681
    }
3682
}
3683