Agenda   F
last analyzed

Complexity

Total Complexity 429

Size/Duplication

Total Lines 3595
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 1697
c 0
b 0
f 0
dl 0
loc 3595
rs 0.8
wmc 429

50 Methods

Rating   Name   Duplication   Size   Complexity  
A setSenderId() 0 3 1
A getType() 0 4 2
A setType() 0 6 2
A getSenderId() 0 3 1
A set_course() 0 3 1
A setSessionInfo() 0 3 1
A getTypes() 0 3 1
A getSessionId() 0 3 1
A setSessionId() 0 3 1
F getCourseEvents() 0 381 48
A parseAgendaFilter() 0 23 5
F getForm() 0 224 29
A move_event() 0 36 5
A getRepeatTypes() 0 9 1
F display_mymonthcalendar() 0 241 30
B parseSendToArray() 0 28 7
A deleteAttachmentFile() 0 16 2
C importEventFile() 0 99 10
A setIsAllowedToEdit() 0 3 1
A addAttachment() 0 35 3
B get_personal_agenda_items() 0 112 9
A getJsForReminders() 0 17 1
A storeAgendaEventAsAnnouncement() 0 25 2
F displayActions() 0 130 26
A resizeEvent() 0 25 4
A changeVisibility() 0 22 3
A calculate_start_end_of_week() 0 33 1
C getPlatformEvents() 0 61 15
F editEvent() 0 200 46
A cleanEvents() 0 12 3
F setSendToSelect() 0 113 19
A getIsAllowedToEdit() 0 3 1
A getImportCalendarForm() 0 18 1
C deleteEvent() 0 87 13
F getEvents() 0 163 26
B get_event() 0 51 6
C generateDatesByType() 0 79 13
B addRepeatedItem() 0 75 7
A getAllRepeatEvents() 0 25 6
A showToForm() 0 39 3
A formatEventDate() 0 9 1
A getSessionEvents() 0 20 3
F get_global_agenda_items() 0 122 13
A get_personal_agenda_items_between_dates() 0 3 1
C getPersonalEvents() 0 66 13
A get_myagendaitems() 0 118 1
A updateAttachment() 0 16 2
C __construct() 0 97 16
A getAttachment() 0 25 5
F addEvent() 0 119 17

How to fix   Complexity   

Complex Class

Complex classes like Agenda often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Agenda, and based on these observations, apply Extract Interface, too.

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