Passed
Push — master ( cc68cc...50453a )
by Julito
09:11
created

Agenda::editEvent()   F

Complexity

Conditions 53
Paths 2808

Size

Total Lines 219
Code Lines 123

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 53
eloc 123
c 0
b 0
f 0
nc 2808
nop 14
dl 0
loc 219
rs 0

How to fix   Long Method    Complexity    Many Parameters   

Long Method

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

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

Commonly applied refactorings include:

Many Parameters

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

There are several approaches to avoid long parameter lists:

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