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

Agenda::editEvent()   F

Complexity

Conditions 46
Paths 8216

Size

Total Lines 319
Code Lines 197

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 46
eloc 197
nc 8216
nop 14
dl 0
loc 319
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity    Many Parameters   

Long Method

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

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

Commonly applied refactorings include:

Many Parameters

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

There are several approaches to avoid long parameter lists:

1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
use Chamilo\CoreBundle\Entity\PersonalAgenda;
6
use Chamilo\CoreBundle\Entity\Resource\ResourceLink;
7
use Chamilo\CoreBundle\Entity\SysCalendar;
8
use Chamilo\CoreBundle\Framework\Container;
9
use Chamilo\CourseBundle\Entity\CCalendarEvent;
10
11
/**
12
 * Class Agenda.
13
 *
14
 * @author: Julio Montoya <[email protected]>
15
 */
16
class Agenda
17
{
18
    public $events = [];
19
    /** @var string Current type */
20
    public $type = 'personal';
21
    public $types = ['personal', 'admin', 'course'];
22
    public $sessionId = 0;
23
    public $senderId;
24
    /** @var array */
25
    public $course;
26
    /** @var string */
27
    public $comment;
28
    public $eventStudentPublicationColor;
29
    /** @var array */
30
    private $sessionInfo;
31
    /** @var bool */
32
    private $isAllowedToEdit;
33
34
    /**
35
     * Constructor.
36
     *
37
     * @param string $type
38
     * @param int    $senderId  Optional The user sender ID
39
     * @param int    $courseId  Optional. The course ID
40
     * @param int    $sessionId Optional The session ID
41
     */
42
    public function __construct(
43
        $type,
44
        $senderId = 0,
45
        $courseId = 0,
46
        $sessionId = 0
47
    ) {
48
        // Table definitions
49
        $this->tbl_global_agenda = Database::get_main_table(TABLE_MAIN_SYSTEM_CALENDAR);
50
        $this->tbl_personal_agenda = Database::get_main_table(TABLE_PERSONAL_AGENDA);
51
        $this->tbl_course_agenda = Database::get_course_table(TABLE_AGENDA);
52
        $this->table_repeat = Database::get_course_table(TABLE_AGENDA_REPEAT);
53
54
        $this->setType($type);
55
        $this->setSenderId($senderId ?: api_get_user_id());
56
        $isAllowToEdit = false;
57
58
        switch ($type) {
59
            case 'course':
60
                $sessionId = $sessionId ?: api_get_session_id();
61
                $sessionInfo = api_get_session_info($sessionId);
62
                $this->setSessionId($sessionId);
63
                $this->setSessionInfo($sessionInfo);
64
65
                // Setting the course object if we are in a course
66
                $courseInfo = api_get_course_info_by_id($courseId);
67
                if (!empty($courseInfo)) {
68
                    $this->set_course($courseInfo);
69
                }
70
71
                // Check if teacher/admin rights.
72
                $isAllowToEdit = api_is_allowed_to_edit(false, true);
73
                // Check course setting.
74
                if (api_get_course_setting('allow_user_edit_agenda') === '1'
75
                    && api_is_allowed_in_course()
76
                ) {
77
                    $isAllowToEdit = true;
78
                }
79
80
                $groupId = api_get_group_id();
81
                if (!empty($groupId)) {
82
                    $groupInfo = GroupManager::get_group_properties($groupId);
83
                    $userHasAccess = GroupManager::user_has_access(
84
                        api_get_user_id(),
85
                        $groupInfo['iid'],
86
                        GroupManager::GROUP_TOOL_CALENDAR
87
                    );
88
                    $isTutor = GroupManager::is_tutor_of_group(
89
                        api_get_user_id(),
90
                        $groupInfo
91
                    );
92
93
                    $isGroupAccess = $userHasAccess || $isTutor;
94
                    $isAllowToEdit = false;
95
                    if ($isGroupAccess) {
96
                        $isAllowToEdit = true;
97
                    }
98
                }
99
100
                if (!empty($sessionId)) {
101
                    $allowDhrToEdit = api_get_configuration_value('allow_agenda_edit_for_hrm');
102
                    if ($allowDhrToEdit) {
103
                        $isHrm = SessionManager::isUserSubscribedAsHRM($sessionId, api_get_user_id());
104
                        if ($isHrm) {
105
                            $isAllowToEdit = true;
106
                        }
107
                    }
108
                }
109
                break;
110
            case 'admin':
111
                $isAllowToEdit = api_is_platform_admin();
112
                break;
113
            case 'personal':
114
                $isAllowToEdit = !api_is_anonymous();
115
                break;
116
        }
117
118
        $this->setIsAllowedToEdit($isAllowToEdit);
119
        $this->events = [];
120
        $agendaColors = array_merge(
121
            [
122
                'platform' => 'red', //red
123
                'course' => '#458B00', //green
124
                'group' => '#A0522D', //siena
125
                'session' => '#00496D', // kind of green
126
                'other_session' => '#999', // kind of green
127
                'personal' => 'steel blue', //steel blue
128
                'student_publication' => '#FF8C00', //DarkOrange
129
            ],
130
            api_get_configuration_value('agenda_colors') ?: []
131
        );
132
133
        // Event colors
134
        $this->event_platform_color = $agendaColors['platform'];
135
        $this->event_course_color = $agendaColors['course'];
136
        $this->event_group_color = $agendaColors['group'];
137
        $this->event_session_color = $agendaColors['session'];
138
        $this->eventOtherSessionColor = $agendaColors['other_session'];
139
        $this->event_personal_color = $agendaColors['personal'];
140
        $this->eventStudentPublicationColor = $agendaColors['student_publication'];
141
    }
142
143
    /**
144
     * @param int $senderId
145
     */
146
    public function setSenderId($senderId)
147
    {
148
        $this->senderId = (int) $senderId;
149
    }
150
151
    /**
152
     * @return int
153
     */
154
    public function getSenderId()
155
    {
156
        return $this->senderId;
157
    }
158
159
    /**
160
     * @param string $type can be 'personal', 'admin'  or  'course'
161
     */
162
    public function setType($type)
163
    {
164
        $typeList = $this->getTypes();
165
        if (in_array($type, $typeList)) {
166
            $this->type = $type;
167
        }
168
    }
169
170
    /**
171
     * Returns the type previously set (and filtered) through setType
172
     * If setType() was not called, then type defaults to "personal" as
173
     * set in the class definition.
174
     */
175
    public function getType()
176
    {
177
        if (isset($this->type)) {
178
            return $this->type;
179
        }
180
    }
181
182
    /**
183
     * @param int $id
184
     */
185
    public function setSessionId($id)
186
    {
187
        $this->sessionId = (int) $id;
188
    }
189
190
    /**
191
     * @param array $sessionInfo
192
     */
193
    public function setSessionInfo($sessionInfo)
194
    {
195
        $this->sessionInfo = $sessionInfo;
196
    }
197
198
    /**
199
     * @return int $id
200
     */
201
    public function getSessionId()
202
    {
203
        return $this->sessionId;
204
    }
205
206
    /**
207
     * @param array $courseInfo
208
     */
209
    public function set_course($courseInfo)
210
    {
211
        $this->course = $courseInfo;
212
    }
213
214
    /**
215
     * @return array
216
     */
217
    public function getTypes()
218
    {
219
        return $this->types;
220
    }
221
222
    /**
223
     * Adds an event to the calendar.
224
     *
225
     * @param string $start                 datetime format: 2012-06-14 09:00:00 in local time
226
     * @param string $end                   datetime format: 2012-06-14 09:00:00 in local time
227
     * @param string $allDay                (true, false)
228
     * @param string $title
229
     * @param string $content
230
     * @param array  $usersToSend           array('everyone') or a list of user/group ids
231
     * @param bool   $addAsAnnouncement     event as a *course* announcement
232
     * @param int    $parentEventId
233
     * @param array  $attachmentArray       array of $_FILES['']
234
     * @param array  $attachmentCommentList
235
     * @param string $eventComment
236
     * @param string $color
237
     *
238
     * @return int
239
     */
240
    public function addEvent(
241
        $start,
242
        $end,
243
        $allDay,
244
        $title,
245
        $content,
246
        $usersToSend = [],
247
        $addAsAnnouncement = false,
248
        $parentEventId = null,
249
        $attachmentArray = [],
250
        $attachmentCommentList = [],
251
        $eventComment = null,
252
        $color = ''
253
    ) {
254
        $start = api_get_utc_datetime($start, false, true);
255
        $end = api_get_utc_datetime($end, false, true);
256
        $allDay = isset($allDay) && $allDay === 'true' ? 1 : 0;
257
        $id = null;
258
259
        $em = Database::getManager();
260
        switch ($this->type) {
261
            case 'personal':
262
                $event = new PersonalAgenda();
263
                $event
264
                    ->setTitle($title)
265
                    ->setText($content)
266
                    ->setDate($start)
267
                    ->setEndDate($end)
268
                    ->setAllDay($allDay)
269
                    ->setColor($color)
270
                    ->setUser(api_get_user_id())
271
                ;
272
                $em->persist($event);
273
                $em->flush();
274
                $id = $event->getId();
275
                break;
276
            case 'course':
277
                $senderId = $this->getSenderId();
278
                $sessionId = $this->getSessionId();
279
                $userEntity = api_get_user_entity(api_get_user_id());
280
                $sessionEntity = api_get_session_entity($sessionId);
281
                $courseEntity = api_get_course_entity($this->course['real_id']);
282
                $groupEntity = api_get_group_entity(api_get_group_id());
283
284
                $event = new CCalendarEvent();
285
                $event
286
                    ->setTitle($title)
287
                    ->setContent($content)
288
                    ->setStartDate($start)
289
                    ->setEndDate($end)
290
                    ->setAllDay($allDay)
291
                    ->setColor($color)
292
                    ->setComment($eventComment)
293
                    ->setCId($this->course['real_id'])
294
                    ->setSessionId($this->getSessionId())
295
                ;
296
297
                if (!empty($parentEventId)) {
298
                    $event->setParentEventId($parentEventId);
299
                }
300
301
                $repo = Container::getCalendarEventRepository();
302
303
                // Node added.
304
                $resourceNode = $repo->createNodeForResource(
305
                    $event,
306
                    $userEntity,
307
                    $courseEntity->getResourceNode()
308
                );
309
310
                if (!empty($usersToSend)) {
311
                    $sendTo = $this->parseSendToArray($usersToSend);
312
                    if ($sendTo['everyone']) {
313
                        $repo->addResourceNodeToCourse(
314
                            $resourceNode,
315
                            ResourceLink::VISIBILITY_PUBLISHED,
316
                            $courseEntity,
317
                            $sessionEntity,
318
                            $groupEntity
319
                        );
320
321
                        /*api_item_property_update(
322
                            $this->course,
323
                            TOOL_CALENDAR_EVENT,
324
                            $id,
325
                            'AgendaAdded',
326
                            $senderId,
327
                            $groupInfo,
328
                            '',
329
                            $start,
330
                            $end,
331
                            $sessionId
332
                        );
333
                        api_item_property_update(
334
                            $this->course,
335
                            TOOL_CALENDAR_EVENT,
336
                            $id,
337
                            'visible',
338
                            $senderId,
339
                            $groupInfo,
340
                            '',
341
                            $start,
342
                            $end,
343
                            $sessionId
344
                        );*/
345
                    } else {
346
                        // Storing the selected groups
347
                        if (!empty($sendTo['groups'])) {
348
                            foreach ($sendTo['groups'] as $group) {
349
                                $groupInfo = null;
350
                                if ($group) {
351
                                    $groupInfo = api_get_group_entity($group);
352
                                }
353
354
                                $repo->addResourceNodeToCourse(
355
                                    $resourceNode,
356
                                    ResourceLink::VISIBILITY_PUBLISHED,
357
                                    $courseEntity,
358
                                    $sessionEntity,
359
                                    $groupInfo
360
                                );
361
362
                                /*api_item_property_update(
363
                                    $this->course,
364
                                    TOOL_CALENDAR_EVENT,
365
                                    $id,
366
                                    'AgendaAdded',
367
                                    $senderId,
368
                                    $groupInfoItem,
369
                                    0,
370
                                    $start,
371
                                    $end,
372
                                    $sessionId
373
                                );
374
375
                                api_item_property_update(
376
                                    $this->course,
377
                                    TOOL_CALENDAR_EVENT,
378
                                    $id,
379
                                    'visible',
380
                                    $senderId,
381
                                    $groupInfoItem,
382
                                    0,
383
                                    $start,
384
                                    $end,
385
                                    $sessionId
386
                                );*/
387
                            }
388
                        }
389
390
                        // storing the selected users
391
                        if (!empty($sendTo['users'])) {
392
                            foreach ($sendTo['users'] as $userId) {
393
                                $repo->addResourceNodeToCourse(
394
                                    $resourceNode,
395
                                    ResourceLink::VISIBILITY_PUBLISHED,
396
                                    $courseEntity,
397
                                    $sessionEntity,
398
                                    $groupEntity,
399
                                    api_get_user_entity($userId)
400
                                );
401
                                /*api_item_property_update(
402
                                    $this->course,
403
                                    TOOL_CALENDAR_EVENT,
404
                                    $id,
405
                                    'AgendaAdded',
406
                                    $senderId,
407
                                    $groupInfo,
408
                                    $userId,
409
                                    $start,
410
                                    $end,
411
                                    $sessionId
412
                                );
413
414
                                api_item_property_update(
415
                                    $this->course,
416
                                    TOOL_CALENDAR_EVENT,
417
                                    $id,
418
                                    'visible',
419
                                    $senderId,
420
                                    $groupInfo,
421
                                    $userId,
422
                                    $start,
423
                                    $end,
424
                                    $sessionId
425
                                );*/
426
                            }
427
                        }
428
                    }
429
                }
430
431
                $em->flush();
432
                $id = $event->getId();
433
434
                if ($id) {
435
                    $sql = "UPDATE ".$this->tbl_course_agenda." SET id = iid WHERE iid = $id";
436
                    Database::query($sql);
437
438
                    // Add announcement.
439
                    if ($addAsAnnouncement) {
440
                        $this->storeAgendaEventAsAnnouncement(
441
                            $id,
442
                            $usersToSend
443
                        );
444
                    }
445
446
                    // Add attachment.
447
                    if (isset($attachmentArray) && !empty($attachmentArray)) {
448
                        $counter = 0;
449
                        foreach ($attachmentArray as $attachmentItem) {
450
                            $this->addAttachment(
451
                                $id,
452
                                $attachmentItem,
453
                                $attachmentCommentList[$counter],
454
                                $this->course
455
                            );
456
                            $counter++;
457
                        }
458
                    }
459
                }
460
                break;
461
            case 'admin':
462
                if (api_is_platform_admin()) {
463
                    $event = new SysCalendar();
464
                    $event
465
                        ->setTitle($title)
466
                        ->setContent($content)
467
                        ->setStartDate($start)
468
                        ->setEndDate($end)
469
                        ->setAllDay($allDay)
470
                        ->setAccessUrlId(api_get_current_access_url_id())
471
                    ;
472
                    $em->persist($event);
473
                    $em->flush();
474
                    $id = $event->getId();
475
                }
476
                break;
477
        }
478
479
        return $id;
480
    }
481
482
    /**
483
     * @param int $eventId
484
     * @param int $courseId
485
     *
486
     * @return array
487
     */
488
    public function getRepeatedInfoByEvent($eventId, $courseId)
489
    {
490
        $repeatTable = Database::get_course_table(TABLE_AGENDA_REPEAT);
491
        $eventId = (int) $eventId;
492
        $courseId = (int) $courseId;
493
        $sql = "SELECT * FROM $repeatTable
494
                WHERE c_id = $courseId AND cal_id = $eventId";
495
        $res = Database::query($sql);
496
        $repeatInfo = [];
497
        if (Database::num_rows($res) > 0) {
498
            $repeatInfo = Database::fetch_array($res, 'ASSOC');
499
        }
500
501
        return $repeatInfo;
502
    }
503
504
    /**
505
     * @param string $type
506
     * @param string $startEvent      in UTC
507
     * @param string $endEvent        in UTC
508
     * @param string $repeatUntilDate in UTC
509
     *
510
     * @throws Exception
511
     *
512
     * @return array
513
     */
514
    public function generateDatesByType($type, $startEvent, $endEvent, $repeatUntilDate)
515
    {
516
        $continue = true;
517
        $repeatUntilDate = new DateTime($repeatUntilDate, new DateTimeZone('UTC'));
518
        $loopMax = 365;
519
        $counter = 0;
520
        $list = [];
521
522
        switch ($type) {
523
            case 'daily':
524
                $interval = 'P1D';
525
                break;
526
            case 'weekly':
527
                $interval = 'P1W';
528
                break;
529
            case 'monthlyByDate':
530
                $interval = 'P1M';
531
                break;
532
            case 'monthlyByDay':
533
            case 'monthlyByDayR':
534
                // not yet implemented
535
                break;
536
            case 'yearly':
537
                $interval = 'P1Y';
538
                break;
539
        }
540
541
        if (empty($interval)) {
542
            return [];
543
        }
544
        $timeZone = api_get_timezone();
545
546
        while ($continue) {
547
            $startDate = new DateTime($startEvent, new DateTimeZone('UTC'));
548
            $endDate = new DateTime($endEvent, new DateTimeZone('UTC'));
549
550
            $startDate->add(new DateInterval($interval));
551
            $endDate->add(new DateInterval($interval));
552
553
            $newStartDate = $startDate->format('Y-m-d H:i:s');
554
            $newEndDate = $endDate->format('Y-m-d H:i:s');
555
556
            $startEvent = $newStartDate;
557
            $endEvent = $newEndDate;
558
559
            if ($endDate > $repeatUntilDate) {
560
                break;
561
            }
562
563
            // @todo remove comment code
564
            $startDateInLocal = new DateTime($newStartDate, new DateTimeZone($timeZone));
565
            if ($startDateInLocal->format('I') == 0) {
566
                // Is saving time? Then fix UTC time to add time
567
                $seconds = $startDateInLocal->getOffset();
568
                $startDate->add(new DateInterval("PT".$seconds."S"));
569
                $startDateFixed = $startDate->format('Y-m-d H:i:s');
570
                $startDateInLocalFixed = new DateTime($startDateFixed, new DateTimeZone($timeZone));
571
                $newStartDate = $startDateInLocalFixed->format('Y-m-d H:i:s');
572
            }
573
574
            $endDateInLocal = new DateTime($newEndDate, new DateTimeZone($timeZone));
575
            if ($endDateInLocal->format('I') == 0) {
576
                // Is saving time? Then fix UTC time to add time
577
                $seconds = $endDateInLocal->getOffset();
578
                $endDate->add(new DateInterval("PT".$seconds."S"));
579
                $endDateFixed = $endDate->format('Y-m-d H:i:s');
580
                $endDateInLocalFixed = new DateTime($endDateFixed, new DateTimeZone($timeZone));
581
                $newEndDate = $endDateInLocalFixed->format('Y-m-d H:i:s');
582
            }
583
            $list[] = ['start' => $newStartDate, 'end' => $newEndDate, 'i' => $startDateInLocal->format('I')];
584
            $counter++;
585
586
            // just in case stop if more than $loopMax
587
            if ($counter > $loopMax) {
588
                break;
589
            }
590
        }
591
592
        return $list;
593
    }
594
595
    /**
596
     * @param int    $eventId
597
     * @param string $type
598
     * @param string $end     in UTC
599
     * @param array  $sentTo
600
     *
601
     * @return bool
602
     */
603
    public function addRepeatedItem($eventId, $type, $end, $sentTo = [])
604
    {
605
        $t_agenda = Database::get_course_table(TABLE_AGENDA);
606
        $t_agenda_r = Database::get_course_table(TABLE_AGENDA_REPEAT);
607
608
        if (empty($this->course)) {
609
            return false;
610
        }
611
612
        $courseId = $this->course['real_id'];
613
        $eventId = (int) $eventId;
614
615
        $sql = "SELECT title, content, start_date, end_date, all_day
616
                FROM $t_agenda
617
                WHERE c_id = $courseId AND id = $eventId";
618
        $res = Database::query($sql);
619
620
        if (Database::num_rows($res) !== 1) {
621
            return false;
622
        }
623
624
        $typeList = [
625
            'daily',
626
            'weekly',
627
            'monthlyByDate',
628
            'monthlyByDay',
629
            'monthlyByDayR',
630
            'yearly',
631
        ];
632
633
        if (!in_array($type, $typeList)) {
634
            return false;
635
        }
636
637
        $now = time();
638
639
        // The event has to repeat *in the future*. We don't allow repeated
640
        // events in the past
641
        if ($end > $now) {
642
            return false;
643
        }
644
645
        $row = Database::fetch_array($res);
646
647
        $title = $row['title'];
648
        $content = $row['content'];
649
        $allDay = $row['all_day'];
650
651
        $type = Database::escape_string($type);
652
        $end = Database::escape_string($end);
653
        $endTimeStamp = api_strtotime($end, 'UTC');
654
        $sql = "INSERT INTO $t_agenda_r (c_id, cal_id, cal_type, cal_end)
655
                VALUES ($courseId, '$eventId', '$type', '$endTimeStamp')";
656
        Database::query($sql);
657
658
        $generatedDates = $this->generateDatesByType($type, $row['start_date'], $row['end_date'], $end);
659
660
        if (empty($generatedDates)) {
661
            return false;
662
        }
663
664
        foreach ($generatedDates as $dateInfo) {
665
            $start = api_get_local_time($dateInfo['start']);
666
            $end = api_get_local_time($dateInfo['end']);
667
            $this->addEvent(
668
                $start,
669
                $end,
670
                $allDay,
671
                $title,
672
                $content,
673
                $sentTo,
674
                false,
675
                $eventId
676
            );
677
        }
678
679
        return true;
680
    }
681
682
    /**
683
     * @param int   $item_id
684
     * @param array $sentTo
685
     *
686
     * @return int
687
     */
688
    public function storeAgendaEventAsAnnouncement($item_id, $sentTo = [])
689
    {
690
        $table_agenda = Database::get_course_table(TABLE_AGENDA);
691
        $courseId = api_get_course_int_id();
692
693
        // Get the agenda item.
694
        $item_id = (int) $item_id;
695
        $sql = "SELECT * FROM $table_agenda
696
                WHERE c_id = $courseId AND id = ".$item_id;
697
        $res = Database::query($sql);
698
699
        if (Database::num_rows($res) > 0) {
700
            $row = Database::fetch_array($res, 'ASSOC');
701
702
            // Sending announcement
703
            if (!empty($sentTo)) {
704
                $id = AnnouncementManager::add_announcement(
705
                    api_get_course_info(),
706
                    api_get_session_id(),
707
                    $row['title'],
708
                    $row['content'],
709
                    $sentTo,
710
                    null,
711
                    null,
712
                    $row['end_date']
713
                );
714
715
                AnnouncementManager::sendEmail(
716
                    api_get_course_info(),
717
                    api_get_session_id(),
718
                    $id
719
                );
720
721
                return $id;
722
            }
723
        }
724
725
        return -1;
726
    }
727
728
    /**
729
     * Edits an event.
730
     *
731
     * @param int    $id
732
     * @param string $start                 datetime format: 2012-06-14 09:00:00
733
     * @param string $end                   datetime format: 2012-06-14 09:00:00
734
     * @param int    $allDay                is all day 'true' or 'false'
735
     * @param string $title
736
     * @param string $content
737
     * @param array  $usersToSend
738
     * @param array  $attachmentArray
739
     * @param array  $attachmentCommentList
740
     * @param string $comment
741
     * @param string $color
742
     * @param bool   $addAnnouncement
743
     * @param bool   $updateContent
744
     * @param int    $authorId
745
     *
746
     * @return bool
747
     */
748
    public function editEvent(
749
        $id,
750
        $start,
751
        $end,
752
        $allDay,
753
        $title,
754
        $content,
755
        $usersToSend = [],
756
        $attachmentArray = [],
757
        $attachmentCommentList = [],
758
        $comment = null,
759
        $color = '',
760
        $addAnnouncement = false,
761
        $updateContent = true,
762
        $authorId = 0
763
    ) {
764
        $start = api_get_utc_datetime($start);
765
        $end = api_get_utc_datetime($end);
766
        $allDay = isset($allDay) && $allDay == 'true' ? 1 : 0;
767
        $authorId = empty($authorId) ? api_get_user_id() : (int) $authorId;
768
769
        switch ($this->type) {
770
            case 'personal':
771
                $eventInfo = $this->get_event($id);
772
                if ($eventInfo['user'] != api_get_user_id()) {
773
                    break;
774
                }
775
                $attributes = [
776
                    'title' => $title,
777
                    'date' => $start,
778
                    'enddate' => $end,
779
                    'all_day' => $allDay,
780
                ];
781
782
                if ($updateContent) {
783
                    $attributes['text'] = $content;
784
                }
785
786
                if (!empty($color)) {
787
                    $attributes['color'] = $color;
788
                }
789
790
                Database::update(
791
                    $this->tbl_personal_agenda,
792
                    $attributes,
793
                    ['id = ?' => $id]
794
                );
795
                break;
796
            case 'course':
797
                $eventInfo = $this->get_event($id);
798
799
                if (empty($eventInfo)) {
800
                    return false;
801
                }
802
803
                $groupId = api_get_group_id();
804
                $groupIid = 0;
805
                $groupInfo = [];
806
                if ($groupId) {
807
                    $groupInfo = GroupManager::get_group_properties($groupId);
808
                    if ($groupInfo) {
809
                        $groupIid = $groupInfo['iid'];
810
                    }
811
                }
812
813
                $courseId = $this->course['real_id'];
814
815
                if (empty($courseId)) {
816
                    return false;
817
                }
818
819
                if ($this->getIsAllowedToEdit()) {
820
                    $attributes = [
821
                        'title' => $title,
822
                        'start_date' => $start,
823
                        'end_date' => $end,
824
                        'all_day' => $allDay,
825
                        'comment' => $comment,
826
                    ];
827
828
                    if ($updateContent) {
829
                        $attributes['content'] = $content;
830
                    }
831
832
                    if (!empty($color)) {
833
                        $attributes['color'] = $color;
834
                    }
835
836
                    Database::update(
837
                        $this->tbl_course_agenda,
838
                        $attributes,
839
                        [
840
                            'id = ? AND c_id = ? AND session_id = ? ' => [
841
                                $id,
842
                                $courseId,
843
                                $this->sessionId,
844
                            ],
845
                        ]
846
                    );
847
848
                    if (!empty($usersToSend)) {
849
                        $sendTo = $this->parseSendToArray($usersToSend);
850
851
                        $usersToDelete = array_diff(
852
                            $eventInfo['send_to']['users'],
853
                            $sendTo['users']
854
                        );
855
                        $usersToAdd = array_diff(
856
                            $sendTo['users'],
857
                            $eventInfo['send_to']['users']
858
                        );
859
860
                        $groupsToDelete = array_diff(
861
                            $eventInfo['send_to']['groups'],
862
                            $sendTo['groups']
863
                        );
864
                        $groupToAdd = array_diff(
865
                            $sendTo['groups'],
866
                            $eventInfo['send_to']['groups']
867
                        );
868
869
                        if ($sendTo['everyone']) {
870
                            // Delete all from group
871
                            if (isset($eventInfo['send_to']['groups']) &&
872
                                !empty($eventInfo['send_to']['groups'])
873
                            ) {
874
                                foreach ($eventInfo['send_to']['groups'] as $group) {
875
                                    $groupIidItem = 0;
876
                                    if ($group) {
877
                                        $groupInfoItem = GroupManager::get_group_properties(
878
                                            $group
879
                                        );
880
                                        if ($groupInfoItem) {
881
                                            $groupIidItem = $groupInfoItem['iid'];
882
                                        }
883
                                    }
884
885
                                    api_item_property_delete(
886
                                        $this->course,
887
                                        TOOL_CALENDAR_EVENT,
888
                                        $id,
889
                                        0,
890
                                        $groupIidItem,
891
                                        $this->sessionId
892
                                    );
893
                                }
894
                            }
895
896
                            // Storing the selected users.
897
                            if (isset($eventInfo['send_to']['users']) &&
898
                                !empty($eventInfo['send_to']['users'])
899
                            ) {
900
                                foreach ($eventInfo['send_to']['users'] as $userId) {
901
                                    api_item_property_delete(
902
                                        $this->course,
903
                                        TOOL_CALENDAR_EVENT,
904
                                        $id,
905
                                        $userId,
906
                                        $groupIid,
907
                                        $this->sessionId
908
                                    );
909
                                }
910
                            }
911
912
                            // Add to everyone only.
913
                            api_item_property_update(
914
                                $this->course,
915
                                TOOL_CALENDAR_EVENT,
916
                                $id,
917
                                'visible',
918
                                $authorId,
919
                                $groupInfo,
920
                                null,
921
                                $start,
922
                                $end,
923
                                $this->sessionId
924
                            );
925
                        } else {
926
                            // Delete "everyone".
927
                            api_item_property_delete(
928
                                $this->course,
929
                                TOOL_CALENDAR_EVENT,
930
                                $id,
931
                                0,
932
                                0,
933
                                $this->sessionId
934
                            );
935
936
                            // Add groups
937
                            if (!empty($groupToAdd)) {
938
                                foreach ($groupToAdd as $group) {
939
                                    $groupInfoItem = [];
940
                                    if ($group) {
941
                                        $groupInfoItem = GroupManager::get_group_properties(
942
                                            $group
943
                                        );
944
                                    }
945
946
                                    api_item_property_update(
947
                                        $this->course,
948
                                        TOOL_CALENDAR_EVENT,
949
                                        $id,
950
                                        'visible',
951
                                        $authorId,
952
                                        $groupInfoItem,
953
                                        0,
954
                                        $start,
955
                                        $end,
956
                                        $this->sessionId
957
                                    );
958
                                }
959
                            }
960
961
                            // Delete groups.
962
                            if (!empty($groupsToDelete)) {
963
                                foreach ($groupsToDelete as $group) {
964
                                    $groupIidItem = 0;
965
                                    if ($group) {
966
                                        $groupInfoItem = GroupManager::get_group_properties(
967
                                            $group
968
                                        );
969
                                        if ($groupInfoItem) {
970
                                            $groupIidItem = $groupInfoItem['iid'];
971
                                        }
972
                                    }
973
974
                                    api_item_property_delete(
975
                                        $this->course,
976
                                        TOOL_CALENDAR_EVENT,
977
                                        $id,
978
                                        0,
979
                                        $groupIidItem,
980
                                        $this->sessionId
981
                                    );
982
                                }
983
                            }
984
985
                            // Add users.
986
                            if (!empty($usersToAdd)) {
987
                                foreach ($usersToAdd as $userId) {
988
                                    api_item_property_update(
989
                                        $this->course,
990
                                        TOOL_CALENDAR_EVENT,
991
                                        $id,
992
                                        'visible',
993
                                        $authorId,
994
                                        $groupInfo,
995
                                        $userId,
996
                                        $start,
997
                                        $end,
998
                                        $this->sessionId
999
                                    );
1000
                                }
1001
                            }
1002
1003
                            // Delete users.
1004
                            if (!empty($usersToDelete)) {
1005
                                foreach ($usersToDelete as $userId) {
1006
                                    api_item_property_delete(
1007
                                        $this->course,
1008
                                        TOOL_CALENDAR_EVENT,
1009
                                        $id,
1010
                                        $userId,
1011
                                        $groupInfo,
1012
                                        $this->sessionId
1013
                                    );
1014
                                }
1015
                            }
1016
                        }
1017
                    }
1018
1019
                    // Add announcement.
1020
                    if (isset($addAnnouncement) && !empty($addAnnouncement)) {
1021
                        $this->storeAgendaEventAsAnnouncement(
1022
                            $id,
1023
                            $usersToSend
1024
                        );
1025
                    }
1026
1027
                    // Add attachment.
1028
                    if (isset($attachmentArray) && !empty($attachmentArray)) {
1029
                        $counter = 0;
1030
                        foreach ($attachmentArray as $attachmentItem) {
1031
                            $this->updateAttachment(
1032
                                $attachmentItem['id'],
1033
                                $id,
1034
                                $attachmentItem,
1035
                                $attachmentCommentList[$counter],
1036
                                $this->course
1037
                            );
1038
                            $counter++;
1039
                        }
1040
                    }
1041
1042
                    return true;
1043
                } else {
1044
                    return false;
1045
                }
1046
                break;
1047
            case 'admin':
1048
            case 'platform':
1049
                if (api_is_platform_admin()) {
1050
                    $attributes = [
1051
                        'title' => $title,
1052
                        'start_date' => $start,
1053
                        'end_date' => $end,
1054
                        'all_day' => $allDay,
1055
                    ];
1056
1057
                    if ($updateContent) {
1058
                        $attributes['content'] = $content;
1059
                    }
1060
                    Database::update(
1061
                        $this->tbl_global_agenda,
1062
                        $attributes,
1063
                        ['id = ?' => $id]
1064
                    );
1065
                }
1066
                break;
1067
        }
1068
    }
1069
1070
    /**
1071
     * @param int  $id
1072
     * @param bool $deleteAllItemsFromSerie
1073
     */
1074
    public function deleteEvent($id, $deleteAllItemsFromSerie = false)
1075
    {
1076
        switch ($this->type) {
1077
            case 'personal':
1078
                $eventInfo = $this->get_event($id);
1079
                if ($eventInfo['user'] == api_get_user_id()) {
1080
                    Database::delete(
1081
                        $this->tbl_personal_agenda,
1082
                        ['id = ?' => $id]
1083
                    );
1084
                }
1085
                break;
1086
            case 'course':
1087
                $courseId = api_get_course_int_id();
1088
                $sessionId = api_get_session_id();
1089
                $isAllowToEdit = api_is_allowed_to_edit(null, true);
1090
1091
                if ($isAllowToEdit == false && !empty($sessionId)) {
1092
                    $allowDhrToEdit = api_get_configuration_value('allow_agenda_edit_for_hrm');
1093
                    if ($allowDhrToEdit) {
1094
                        $isHrm = SessionManager::isUserSubscribedAsHRM(
1095
                            $sessionId,
1096
                            api_get_user_id()
1097
                        );
1098
                        if ($isHrm) {
1099
                            $isAllowToEdit = true;
1100
                        }
1101
                    }
1102
                }
1103
1104
                if (!empty($courseId) && $isAllowToEdit) {
1105
                    // Delete
1106
                    $eventInfo = $this->get_event($id);
1107
                    if ($deleteAllItemsFromSerie) {
1108
                        /* This is one of the children.
1109
                           Getting siblings and delete 'Em all + the father! */
1110
                        if (isset($eventInfo['parent_event_id']) && !empty($eventInfo['parent_event_id'])) {
1111
                            // Removing items.
1112
                            $events = $this->getAllRepeatEvents(
1113
                                $eventInfo['parent_event_id']
1114
                            );
1115
                            if (!empty($events)) {
1116
                                foreach ($events as $event) {
1117
                                    $this->deleteEvent($event['id']);
1118
                                }
1119
                            }
1120
                            // Removing parent.
1121
                            $this->deleteEvent($eventInfo['parent_event_id']);
1122
                        } else {
1123
                            // This is the father looking for the children.
1124
                            $events = $this->getAllRepeatEvents($id);
1125
                            if (!empty($events)) {
1126
                                foreach ($events as $event) {
1127
                                    $this->deleteEvent($event['id']);
1128
                                }
1129
                            }
1130
                        }
1131
                    }
1132
1133
                    // Removing from events.
1134
                    Database::delete(
1135
                        $this->tbl_course_agenda,
1136
                        ['id = ? AND c_id = ?' => [$id, $courseId]]
1137
                    );
1138
1139
                    api_item_property_update(
1140
                        $this->course,
1141
                        TOOL_CALENDAR_EVENT,
1142
                        $id,
1143
                        'delete',
1144
                        api_get_user_id()
1145
                    );
1146
1147
                    // Removing from series.
1148
                    Database::delete(
1149
                        $this->table_repeat,
1150
                        [
1151
                            'cal_id = ? AND c_id = ?' => [
1152
                                $id,
1153
                                $courseId,
1154
                            ],
1155
                        ]
1156
                    );
1157
1158
                    if (isset($eventInfo['attachment']) && !empty($eventInfo['attachment'])) {
1159
                        foreach ($eventInfo['attachment'] as $attachment) {
1160
                            self::deleteAttachmentFile(
1161
                                $attachment['id'],
1162
                                $this->course
1163
                            );
1164
                        }
1165
                    }
1166
                }
1167
                break;
1168
            case 'admin':
1169
                if (api_is_platform_admin()) {
1170
                    Database::delete(
1171
                        $this->tbl_global_agenda,
1172
                        ['id = ?' => $id]
1173
                    );
1174
                }
1175
                break;
1176
        }
1177
    }
1178
1179
    /**
1180
     * Get agenda events.
1181
     *
1182
     * @param int    $start
1183
     * @param int    $end
1184
     * @param int    $courseId
1185
     * @param int    $groupId
1186
     * @param int    $user_id
1187
     * @param string $format
1188
     *
1189
     * @return array|string
1190
     */
1191
    public function getEvents(
1192
        $start,
1193
        $end,
1194
        $courseId = null,
1195
        $groupId = null,
1196
        $user_id = 0,
1197
        $format = 'json'
1198
    ) {
1199
        switch ($this->type) {
1200
            case 'admin':
1201
                $this->getPlatformEvents($start, $end);
1202
                break;
1203
            case 'course':
1204
                $courseInfo = api_get_course_info_by_id($courseId);
1205
1206
                // Session coach can see all events inside a session.
1207
                if (api_is_coach()) {
1208
                    // Own course
1209
                    $this->getCourseEvents(
1210
                        $start,
1211
                        $end,
1212
                        $courseInfo,
1213
                        $groupId,
1214
                        $this->sessionId,
1215
                        $user_id
1216
                    );
1217
1218
                    // Others
1219
                    $this->getSessionEvents(
1220
                        $start,
1221
                        $end,
1222
                        $this->sessionId,
1223
                        $user_id,
1224
                        $this->eventOtherSessionColor
1225
                    );
1226
                } else {
1227
                    $this->getCourseEvents(
1228
                        $start,
1229
                        $end,
1230
                        $courseInfo,
1231
                        $groupId,
1232
                        $this->sessionId,
1233
                        $user_id
1234
                    );
1235
                }
1236
                break;
1237
            case 'personal':
1238
            default:
1239
                $sessionFilterActive = false;
1240
                if (!empty($this->sessionId)) {
1241
                    $sessionFilterActive = true;
1242
                }
1243
1244
                if ($sessionFilterActive == false) {
1245
                    // Getting personal events
1246
                    $this->getPersonalEvents($start, $end);
1247
1248
                    // Getting platform/admin events
1249
                    $this->getPlatformEvents($start, $end);
1250
                }
1251
1252
                $ignoreVisibility = api_get_configuration_value('personal_agenda_show_all_session_events');
1253
1254
                // Getting course events
1255
                $my_course_list = [];
1256
                if (!api_is_anonymous()) {
1257
                    $session_list = SessionManager::get_sessions_by_user(
1258
                        api_get_user_id(),
1259
                        $ignoreVisibility
1260
                    );
1261
                    $my_course_list = CourseManager::get_courses_list_by_user_id(
1262
                        api_get_user_id(),
1263
                        false
1264
                    );
1265
                }
1266
1267
                if (api_is_drh()) {
1268
                    if (api_drh_can_access_all_session_content()) {
1269
                        $session_list = [];
1270
                        $sessionList = SessionManager::get_sessions_followed_by_drh(
1271
                            api_get_user_id(),
1272
                            null,
1273
                            null,
1274
                            null,
1275
                            true,
1276
                            false
1277
                        );
1278
1279
                        if (!empty($sessionList)) {
1280
                            foreach ($sessionList as $sessionItem) {
1281
                                $sessionId = $sessionItem['id'];
1282
                                $courses = SessionManager::get_course_list_by_session_id(
1283
                                    $sessionId
1284
                                );
1285
                                $sessionInfo = [
1286
                                    'session_id' => $sessionId,
1287
                                    'courses' => $courses,
1288
                                ];
1289
                                $session_list[] = $sessionInfo;
1290
                            }
1291
                        }
1292
                    }
1293
                }
1294
1295
                if (!empty($session_list)) {
1296
                    foreach ($session_list as $session_item) {
1297
                        if ($sessionFilterActive) {
1298
                            if ($this->sessionId != $session_item['session_id']) {
1299
                                continue;
1300
                            }
1301
                        }
1302
1303
                        $my_courses = $session_item['courses'];
1304
                        $my_session_id = $session_item['session_id'];
1305
1306
                        if (!empty($my_courses)) {
1307
                            foreach ($my_courses as $course_item) {
1308
                                $courseInfo = api_get_course_info_by_id(
1309
                                    $course_item['real_id']
1310
                                );
1311
                                $this->getCourseEvents(
1312
                                    $start,
1313
                                    $end,
1314
                                    $courseInfo,
1315
                                    0,
1316
                                    $my_session_id
1317
                                );
1318
                            }
1319
                        }
1320
                    }
1321
                }
1322
1323
                if (!empty($my_course_list) && $sessionFilterActive == false) {
1324
                    foreach ($my_course_list as $courseInfoItem) {
1325
                        $courseInfo = api_get_course_info_by_id(
1326
                            $courseInfoItem['real_id']
1327
                        );
1328
                        if (isset($courseId) && !empty($courseId)) {
1329
                            if ($courseInfo['real_id'] == $courseId) {
1330
                                $this->getCourseEvents(
1331
                                    $start,
1332
                                    $end,
1333
                                    $courseInfo,
1334
                                    0,
1335
                                    0,
1336
                                    $user_id
1337
                                );
1338
                            }
1339
                        } else {
1340
                            $this->getCourseEvents(
1341
                                $start,
1342
                                $end,
1343
                                $courseInfo,
1344
                                0,
1345
                                0,
1346
                                $user_id
1347
                            );
1348
                        }
1349
                    }
1350
                }
1351
                break;
1352
        }
1353
1354
        $this->cleanEvents();
1355
1356
        switch ($format) {
1357
            case 'json':
1358
                if (empty($this->events)) {
1359
                    return '[]';
1360
                }
1361
1362
                return json_encode($this->events);
1363
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
1364
            case 'array':
1365
                if (empty($this->events)) {
1366
                    return [];
1367
                }
1368
1369
                return $this->events;
1370
                break;
1371
        }
1372
    }
1373
1374
    /**
1375
     * Clean events.
1376
     *
1377
     * @return bool
1378
     */
1379
    public function cleanEvents()
1380
    {
1381
        if (empty($this->events)) {
1382
            return false;
1383
        }
1384
1385
        foreach ($this->events as &$event) {
1386
            $event['description'] = Security::remove_XSS($event['description']);
1387
            $event['title'] = Security::remove_XSS($event['title']);
1388
        }
1389
1390
        return true;
1391
    }
1392
1393
    /**
1394
     * @param int $id
1395
     * @param int $minute_delta
1396
     *
1397
     * @return int
1398
     */
1399
    public function resizeEvent($id, $minute_delta)
1400
    {
1401
        $id = (int) $id;
1402
        $delta = (int) $minute_delta;
1403
        $event = $this->get_event($id);
1404
        if (!empty($event)) {
1405
            switch ($this->type) {
1406
                case 'personal':
1407
                    $sql = "UPDATE $this->tbl_personal_agenda SET
1408
                            enddate = DATE_ADD(enddate, INTERVAL $delta MINUTE)
1409
							WHERE id = ".$id;
1410
                    Database::query($sql);
1411
                    break;
1412
                case 'course':
1413
                    $sql = "UPDATE $this->tbl_course_agenda SET
1414
                            end_date = DATE_ADD(end_date, INTERVAL $delta MINUTE)
1415
							WHERE
1416
							    c_id = ".$this->course['real_id']." AND
1417
							    id = ".$id;
1418
                    Database::query($sql);
1419
                    break;
1420
                case 'admin':
1421
                    $sql = "UPDATE $this->tbl_global_agenda SET
1422
                            end_date = DATE_ADD(end_date, INTERVAL $delta MINUTE)
1423
							WHERE id = ".$id;
1424
                    Database::query($sql);
1425
                    break;
1426
            }
1427
        }
1428
1429
        return 1;
1430
    }
1431
1432
    /**
1433
     * @param int $id
1434
     * @param int $minute_delta minutes
1435
     * @param int $allDay
1436
     *
1437
     * @return int
1438
     */
1439
    public function move_event($id, $minute_delta, $allDay)
1440
    {
1441
        $id = (int) $id;
1442
        $event = $this->get_event($id);
1443
1444
        if (empty($event)) {
1445
            return false;
1446
        }
1447
1448
        // we convert the hour delta into minutes and add the minute delta
1449
        $delta = (int) $minute_delta;
1450
        $allDay = (int) $allDay;
1451
1452
        if (!empty($event)) {
1453
            switch ($this->type) {
1454
                case 'personal':
1455
                    $sql = "UPDATE $this->tbl_personal_agenda SET
1456
                            all_day = $allDay, date = DATE_ADD(date, INTERVAL $delta MINUTE),
1457
                            enddate = DATE_ADD(enddate, INTERVAL $delta MINUTE)
1458
							WHERE id=".$id;
1459
                    Database::query($sql);
1460
                    break;
1461
                case 'course':
1462
                    $sql = "UPDATE $this->tbl_course_agenda SET
1463
                            all_day = $allDay,
1464
                            start_date = DATE_ADD(start_date, INTERVAL $delta MINUTE),
1465
                            end_date = DATE_ADD(end_date, INTERVAL $delta MINUTE)
1466
							WHERE
1467
							    c_id = ".$this->course['real_id']." AND
1468
							    id=".$id;
1469
                    Database::query($sql);
1470
                    break;
1471
                case 'admin':
1472
                    $sql = "UPDATE $this->tbl_global_agenda SET
1473
                            all_day = $allDay,
1474
                            start_date = DATE_ADD(start_date,INTERVAL $delta MINUTE),
1475
                            end_date = DATE_ADD(end_date, INTERVAL $delta MINUTE)
1476
							WHERE id=".$id;
1477
                    Database::query($sql);
1478
                    break;
1479
            }
1480
        }
1481
1482
        return 1;
1483
    }
1484
1485
    /**
1486
     * Gets a single event.
1487
     *
1488
     * @param int $id event id
1489
     *
1490
     * @return array
1491
     */
1492
    public function get_event($id)
1493
    {
1494
        // make sure events of the personal agenda can only be seen by the user himself
1495
        $id = (int) $id;
1496
        $event = null;
1497
        switch ($this->type) {
1498
            case 'personal':
1499
                $sql = "SELECT * FROM ".$this->tbl_personal_agenda."
1500
                        WHERE id = $id AND user = ".api_get_user_id();
1501
                $result = Database::query($sql);
1502
                if (Database::num_rows($result)) {
1503
                    $event = Database::fetch_array($result, 'ASSOC');
1504
                    $event['description'] = $event['text'];
1505
                    $event['content'] = $event['text'];
1506
                    $event['start_date'] = $event['date'];
1507
                    $event['end_date'] = $event['enddate'];
1508
                }
1509
                break;
1510
            case 'course':
1511
                if (!empty($this->course['real_id'])) {
1512
                    $sql = "SELECT * FROM ".$this->tbl_course_agenda."
1513
                            WHERE c_id = ".$this->course['real_id']." AND id = ".$id;
1514
                    $result = Database::query($sql);
1515
                    if (Database::num_rows($result)) {
1516
                        $event = Database::fetch_array($result, 'ASSOC');
1517
                        $event['description'] = $event['content'];
1518
1519
                        // Getting send to array
1520
                        $event['send_to'] = $this->getUsersAndGroupSubscribedToEvent(
1521
                            $id,
1522
                            $this->course['real_id'],
1523
                            $this->sessionId
1524
                        );
1525
1526
                        // Getting repeat info
1527
                        $event['repeat_info'] = $this->getRepeatedInfoByEvent(
1528
                            $id,
1529
                            $this->course['real_id']
1530
                        );
1531
1532
                        if (!empty($event['parent_event_id'])) {
1533
                            $event['parent_info'] = $this->get_event(
1534
                                $event['parent_event_id']
1535
                            );
1536
                        }
1537
1538
                        $event['attachment'] = $this->getAttachmentList(
1539
                            $id,
1540
                            $this->course
1541
                        );
1542
                    }
1543
                }
1544
                break;
1545
            case 'admin':
1546
            case 'platform':
1547
                $sql = "SELECT * FROM ".$this->tbl_global_agenda."
1548
                        WHERE id = $id";
1549
                $result = Database::query($sql);
1550
                if (Database::num_rows($result)) {
1551
                    $event = Database::fetch_array($result, 'ASSOC');
1552
                    $event['description'] = $event['content'];
1553
                }
1554
                break;
1555
        }
1556
1557
        return $event;
1558
    }
1559
1560
    /**
1561
     * Gets personal events.
1562
     *
1563
     * @param int $start
1564
     * @param int $end
1565
     *
1566
     * @return array
1567
     */
1568
    public function getPersonalEvents($start, $end)
1569
    {
1570
        $start = (int) $start;
1571
        $end = (int) $end;
1572
        $startCondition = '';
1573
        $endCondition = '';
1574
1575
        if ($start !== 0) {
1576
            $startCondition = "AND date >= '".api_get_utc_datetime($start)."'";
1577
        }
1578
        if ($start !== 0) {
1579
            $endCondition = "AND (enddate <= '".api_get_utc_datetime($end)."' OR enddate IS NULL)";
1580
        }
1581
        $user_id = api_get_user_id();
1582
1583
        $sql = "SELECT * FROM ".$this->tbl_personal_agenda."
1584
                WHERE user = $user_id $startCondition $endCondition";
1585
1586
        $result = Database::query($sql);
1587
        $my_events = [];
1588
        if (Database::num_rows($result)) {
1589
            while ($row = Database::fetch_array($result, 'ASSOC')) {
1590
                $event = [];
1591
                $event['id'] = 'personal_'.$row['id'];
1592
                $event['title'] = $row['title'];
1593
                $event['className'] = 'personal';
1594
                $event['borderColor'] = $event['backgroundColor'] = $this->event_personal_color;
1595
                $event['editable'] = true;
1596
                $event['sent_to'] = get_lang('Me');
1597
                $event['type'] = 'personal';
1598
1599
                if (!empty($row['date'])) {
1600
                    $event['start'] = $this->formatEventDate($row['date']);
1601
                    $event['start_date_localtime'] = api_get_local_time($row['date']);
1602
                }
1603
1604
                if (!empty($row['enddate'])) {
1605
                    $event['end'] = $this->formatEventDate($row['enddate']);
1606
                    $event['end_date_localtime'] = api_get_local_time($row['enddate']);
1607
                }
1608
1609
                $event['description'] = $row['text'];
1610
                $event['allDay'] = isset($row['all_day']) && $row['all_day'] == 1 ? $row['all_day'] : 0;
1611
                $event['parent_event_id'] = 0;
1612
                $event['has_children'] = 0;
1613
1614
                $my_events[] = $event;
1615
                $this->events[] = $event;
1616
            }
1617
        }
1618
1619
        // Add plugin personal events
1620
        $this->plugin = new AppPlugin();
1621
        $plugins = $this->plugin->getInstalledPluginListObject();
1622
        /** @var Plugin $plugin */
1623
        foreach ($plugins as $plugin) {
1624
            if ($plugin->hasPersonalEvents && method_exists($plugin, 'getPersonalEvents')) {
1625
                $pluginEvents = $plugin->getPersonalEvents($this, $start, $end);
1626
1627
                if (!empty($pluginEvents)) {
1628
                    $this->events = array_merge($this->events, $pluginEvents);
1629
                }
1630
            }
1631
        }
1632
1633
        return $my_events;
1634
    }
1635
1636
    /**
1637
     * Get user/group list per event.
1638
     *
1639
     * @param int $eventId
1640
     * @param int $courseId
1641
     * @param int $sessionId
1642
     * @paraù int $sessionId
1643
     *
1644
     * @return array
1645
     */
1646
    public function getUsersAndGroupSubscribedToEvent(
1647
        $eventId,
1648
        $courseId,
1649
        $sessionId
1650
    ) {
1651
        $eventId = (int) $eventId;
1652
        $courseId = (int) $courseId;
1653
        $sessionId = (int) $sessionId;
1654
1655
        $sessionCondition = "ip.session_id = $sessionId";
1656
        if (empty($sessionId)) {
1657
            $sessionCondition = " (ip.session_id = 0 OR ip.session_id IS NULL) ";
1658
        }
1659
1660
        $tlb_course_agenda = Database::get_course_table(TABLE_AGENDA);
1661
        $tbl_property = Database::get_course_table(TABLE_ITEM_PROPERTY);
1662
1663
        // Get sent_tos
1664
        $sql = "SELECT DISTINCT to_user_id, to_group_id
1665
                FROM $tbl_property ip
1666
                INNER JOIN $tlb_course_agenda agenda
1667
                ON (
1668
                  ip.ref = agenda.id AND
1669
                  ip.c_id = agenda.c_id AND
1670
                  ip.tool = '".TOOL_CALENDAR_EVENT."'
1671
                )
1672
                WHERE
1673
                    ref = $eventId AND
1674
                    ip.visibility = '1' AND
1675
                    ip.c_id = $courseId AND
1676
                    $sessionCondition
1677
                ";
1678
1679
        $result = Database::query($sql);
1680
        $users = [];
1681
        $groups = [];
1682
        $everyone = false;
1683
1684
        while ($row = Database::fetch_array($result, 'ASSOC')) {
1685
            if (!empty($row['to_group_id'])) {
1686
                $groups[] = $row['to_group_id'];
1687
            }
1688
            if (!empty($row['to_user_id'])) {
1689
                $users[] = $row['to_user_id'];
1690
            }
1691
1692
            if (empty($groups) && empty($users)) {
1693
                if ($row['to_group_id'] == 0) {
1694
                    $everyone = true;
1695
                }
1696
            }
1697
        }
1698
1699
        return [
1700
            'everyone' => $everyone,
1701
            'users' => $users,
1702
            'groups' => $groups,
1703
        ];
1704
    }
1705
1706
    /**
1707
     * @param int    $start
1708
     * @param int    $end
1709
     * @param int    $sessionId
1710
     * @param int    $userId
1711
     * @param string $color
1712
     *
1713
     * @return array
1714
     */
1715
    public function getSessionEvents(
1716
        $start,
1717
        $end,
1718
        $sessionId = 0,
1719
        $userId = 0,
1720
        $color = ''
1721
    ) {
1722
        $courses = SessionManager::get_course_list_by_session_id($sessionId);
1723
1724
        if (!empty($courses)) {
1725
            foreach ($courses as $course) {
1726
                $this->getCourseEvents(
1727
                    $start,
1728
                    $end,
1729
                    $course,
1730
                    0,
1731
                    $sessionId,
1732
                    0,
1733
                    $color
1734
                );
1735
            }
1736
        }
1737
    }
1738
1739
    /**
1740
     * @param int    $start
1741
     * @param int    $end
1742
     * @param array  $courseInfo
1743
     * @param int    $groupId
1744
     * @param int    $sessionId
1745
     * @param int    $user_id
1746
     * @param string $color
1747
     *
1748
     * @return array
1749
     */
1750
    public function getCourseEvents(
1751
        $start,
1752
        $end,
1753
        $courseInfo,
1754
        $groupId = 0,
1755
        $sessionId = 0,
1756
        $user_id = 0,
1757
        $color = ''
1758
    ) {
1759
        $start = (int) $start;
1760
        $end = (int) $end;
1761
1762
        $start = !empty($start) ? api_get_utc_datetime($start) : null;
1763
        $end = !empty($end) ? api_get_utc_datetime($end) : null;
1764
1765
        if (empty($courseInfo)) {
1766
            return [];
1767
        }
1768
        $courseId = $courseInfo['real_id'];
1769
1770
        if (empty($courseId)) {
1771
            return [];
1772
        }
1773
1774
        $sessionId = (int) $sessionId;
1775
        $user_id = (int) $user_id;
1776
1777
        $groupList = GroupManager::get_group_list(
1778
            null,
1779
            $courseInfo,
1780
            null,
1781
            $sessionId
1782
        );
1783
1784
        $groupNameList = [];
1785
        if (!empty($groupList)) {
1786
            foreach ($groupList as $group) {
1787
                $groupNameList[$group['iid']] = $group['name'];
1788
            }
1789
        }
1790
1791
        if (api_is_platform_admin() || api_is_allowed_to_edit()) {
1792
            $isAllowToEdit = true;
1793
        } else {
1794
            $isAllowToEdit = CourseManager::is_course_teacher(
1795
                api_get_user_id(),
1796
                $courseInfo['code']
1797
            );
1798
        }
1799
1800
        $isAllowToEditByHrm = false;
1801
        if (!empty($sessionId)) {
1802
            $allowDhrToEdit = api_get_configuration_value('allow_agenda_edit_for_hrm');
1803
            if ($allowDhrToEdit) {
1804
                $isHrm = SessionManager::isUserSubscribedAsHRM($sessionId, api_get_user_id());
1805
                if ($isHrm) {
1806
                    $isAllowToEdit = $isAllowToEditByHrm = true;
1807
                }
1808
            }
1809
        }
1810
1811
        $groupMemberships = [];
1812
        if (!empty($groupId)) {
1813
            $groupMemberships = [$groupId];
1814
        } else {
1815
            if ($isAllowToEdit) {
1816
                if (!empty($groupList)) {
1817
                    // c_item_property.to_group_id field was migrated to use
1818
                    // c_group_info.iid
1819
                    $groupMemberships = array_column($groupList, 'iid');
1820
                }
1821
            } else {
1822
                // get only related groups from user
1823
                $groupMemberships = GroupManager::get_group_ids(
1824
                    $courseId,
1825
                    api_get_user_id()
1826
                );
1827
            }
1828
        }
1829
1830
        $repo = Container::getCalendarEventRepository();
1831
        $courseEntity = api_get_course_entity($courseId);
1832
        $session = api_get_session_entity($sessionId);
1833
1834
        $qb = $repo->getResourcesByCourseOnly($courseEntity, $courseEntity->getResourceNode());
1835
        $userCondition = '';
1836
1837
        if ($isAllowToEdit) {
1838
            // No group filter was asked
1839
            if (empty($groupId)) {
1840
                if (empty($user_id)) {
1841
                    // Show all events not added in group
1842
                    $userCondition = ' (links.group IS NULL) ';
1843
                    // admin see only his stuff
1844
                    if ($this->type === 'personal') {
1845
                        $userCondition = " (links.user = ".api_get_user_id()." AND (links.group IS NULL) ";
1846
                        //$userCondition = " (ip.to_user_id = ".api_get_user_id()." AND (ip.to_group_id IS NULL OR ip.to_group_id = 0) ) ";
1847
                        $userCondition .= " OR ( (links.user IS NULL)  AND (links.group IS NULL ))) ";
1848
                        //$userCondition .= " OR ( (ip.to_user_id = 0 OR ip.to_user_id is NULL)  AND (ip.to_group_id IS NULL OR ip.to_group_id = 0) ) ";
1849
                    }
1850
1851
                    if (!empty($groupMemberships)) {
1852
                        // Show events sent to selected groups
1853
                        $userCondition .= " OR (links.user IS NULL) AND (links.group IN (".implode(", ", $groupMemberships).")) ";
1854
                    }
1855
                } else {
1856
                    // Show events of requested user in no group
1857
                    $userCondition = " (links.user = $user_id AND links.group IS NULL) ";
1858
                    // Show events sent to selected groups
1859
                    if (!empty($groupMemberships)) {
1860
                        $userCondition .= " OR (links.user = $user_id) AND (links.group IN (".implode(", ", $groupMemberships).")) ";
1861
                    }
1862
                }
1863
            } else {
1864
                // Show only selected groups (depending of user status)
1865
                $userCondition = " (links.user is NULL) AND (links.group IN (".implode(", ", $groupMemberships).")) ";
1866
1867
                if (!empty($groupMemberships)) {
1868
                    // Show send to $user_id in selected groups
1869
                    $userCondition .= " OR (links.user = $user_id) AND (links.group IN (".implode(", ", $groupMemberships).")) ";
1870
                }
1871
            }
1872
        } else {
1873
            // No group filter was asked
1874
            if (empty($groupId)) {
1875
                // Show events sent to everyone and no group
1876
                $userCondition = ' ( (links.user is NULL) AND (links.group IS NULL) ';
1877
1878
                // Show events sent to selected groups
1879
                if (!empty($groupMemberships)) {
1880
                    $userCondition .= " OR (links.user is NULL) AND (links.group IN (".implode(", ", $groupMemberships)."))) ";
1881
                } else {
1882
                    $userCondition .= " ) ";
1883
                }
1884
                $userCondition .= " OR (links.user = ".api_get_user_id()." AND (links.group IS NULL )) ";
1885
1886
            } else {
1887
                if (!empty($groupMemberships)) {
1888
                    // Show send to everyone - and only selected groups
1889
                    $userCondition = " (links.user is NULL) AND (links.group IN (".implode(", ", $groupMemberships).")) ";
1890
                }
1891
            }
1892
1893
            // Show sent to only me and no group
1894
            if (!empty($groupMemberships)) {
1895
                $userCondition .= " OR (links.user = ".api_get_user_id().") AND (links.group IN (".implode(", ", $groupMemberships).")) ";
1896
            }
1897
        }
1898
1899
        if (!empty($userCondition)) {
1900
            $qb->andWhere($userCondition);
1901
        }
1902
1903
        /*if (!empty($groupMemberships)) {
1904
            $orX = $qb->expr()->orX();
1905
            foreach ($groupMemberships as $groupId) {
1906
                $group = api_get_group_entity($groupId);
1907
                $orX->add("links.group = :group$groupId");
1908
                $qb->setParameter("group$groupId", $group);
1909
            }
1910
            $qb->andWhere($orX);
1911
        }*/
1912
1913
        //$dateCondition = '';
1914
        if (!empty($start) && !empty($end)) {
1915
            $qb->andWhere(
1916
                $qb->expr()->orX(
1917
                    'resource.startDate BETWEEN :start AND :end',
1918
                    'resource.endDate BETWEEN :start AND :end',
1919
                    $qb->expr()->orX(
1920
                        'resource.startDate IS NOT NULL AND resource.endDate IS NOT NULL AND
1921
                            YEAR(resource.startDate) = YEAR(resource.endDate) AND
1922
                            MONTH(:start) BETWEEN MONTH(resource.startDate) AND MONTH(resource.endDate)
1923
                        '
1924
                    )
1925
                )
1926
            )
1927
            ->setParameter('start', $start)
1928
            ->setParameter('end', $end);
1929
1930
            /*
1931
            $dateCondition .= "AND (
1932
                 agenda.start_date BETWEEN '".$start."' AND '".$end."' OR
1933
                 agenda.end_date BETWEEN '".$start."' AND '".$end."' OR
1934
                 (
1935
                     agenda.start_date IS NOT NULL AND agenda.end_date IS NOT NULL AND
1936
                     YEAR(agenda.start_date) = YEAR(agenda.end_date) AND
1937
                     MONTH('$start') BETWEEN MONTH(agenda.start_date) AND MONTH(agenda.end_date)
1938
                 )
1939
            )";*/
1940
        }
1941
1942
        /*
1943
        if (empty($sessionId)) {
1944
            $sessionCondition = "
1945
            (
1946
                agenda.session_id = 0 AND (ip.session_id IS NULL OR ip.session_id = 0)
1947
            ) ";
1948
        } else {
1949
            $sessionCondition = "
1950
            (
1951
                agenda.session_id = $sessionId AND
1952
                ip.session_id = $sessionId
1953
            ) ";
1954
        }
1955
1956
        if (api_is_allowed_to_edit()) {
1957
            $visibilityCondition = " (ip.visibility IN ('1', '0'))  ";
1958
        } else {
1959
            $visibilityCondition = " (ip.visibility = '1') ";
1960
        }
1961
1962
        $sql = "SELECT DISTINCT
1963
                    agenda.*,
1964
                    ip.visibility,
1965
                    ip.to_group_id,
1966
                    ip.insert_user_id,
1967
                    ip.ref,
1968
                    to_user_id
1969
                FROM $tlb_course_agenda agenda
1970
                INNER JOIN $tbl_property ip
1971
                ON (
1972
                    agenda.id = ip.ref AND
1973
                    agenda.c_id = ip.c_id AND
1974
                    ip.tool = '".TOOL_CALENDAR_EVENT."'
1975
                )
1976
                WHERE
1977
                    $sessionCondition AND
1978
                    ($userCondition) AND
1979
                    $visibilityCondition AND
1980
                    agenda.c_id = $courseId
1981
        ";
1982
        $dateCondition = '';
1983
        if (!empty($start) && !empty($end)) {
1984
            $dateCondition .= "AND (
1985
                 agenda.start_date BETWEEN '".$start."' AND '".$end."' OR
1986
                 agenda.end_date BETWEEN '".$start."' AND '".$end."' OR
1987
                 (
1988
                     agenda.start_date IS NOT NULL AND agenda.end_date IS NOT NULL AND
1989
                     YEAR(agenda.start_date) = YEAR(agenda.end_date) AND
1990
                     MONTH('$start') BETWEEN MONTH(agenda.start_date) AND MONTH(agenda.end_date)
1991
                 )
1992
            )";
1993
        }
1994
1995
        $sql .= $dateCondition;
1996
        $result = Database::query($sql);*/
1997
1998
        $coachCanEdit = false;
1999
        if (!empty($sessionId)) {
2000
            $coachCanEdit = api_is_coach($sessionId, $courseId) || api_is_platform_admin();
2001
        }
2002
        //var_dump($courseId);        echo $qb->getQuery()->getSQL();exit;
2003
2004
        $events = $qb->getQuery()->getResult();
2005
        //$eventsAdded = array_column($this->events, 'unique_id');
2006
        /** @var CCalendarEvent $row */
2007
        foreach ($events as $row) {
2008
            $eventId = $row->getIid();
2009
            $event = [];
2010
            $event['id'] = 'course_'.$eventId;
2011
            $event['unique_id'] = $eventId;
2012
            // To avoid doubles
2013
            /*if (in_array($event['unique_id'], $eventsAdded)) {
2014
                continue;
2015
            }*/
2016
2017
            $eventsAdded[] = $eventId;
2018
            //$eventId = $row['ref'];
2019
            /*$items = $this->getUsersAndGroupSubscribedToEvent(
2020
                $eventId,
2021
                $courseId,
2022
                $this->sessionId
2023
            );
2024
            $group_to_array = $items['groups'];
2025
            $user_to_array = $items['users'];*/
2026
            $attachmentList = $this->getAttachmentList(
2027
                $eventId,
2028
                $courseInfo
2029
            );
2030
            $event['attachment'] = '';
2031
            if (!empty($attachmentList)) {
2032
                foreach ($attachmentList as $attachment) {
2033
                    $has_attachment = Display::return_icon(
2034
                        'attachment.gif',
2035
                        get_lang('Attachment')
2036
                    );
2037
                    $user_filename = $attachment['filename'];
2038
                    $url = api_get_path(WEB_CODE_PATH).'calendar/download.php?file='.$attachment['path'].'&course_id='.$courseId.'&'.api_get_cidreq();
2039
                    $event['attachment'] .= $has_attachment.
2040
                        Display::url(
2041
                            $user_filename,
2042
                            $url
2043
                        ).'<br />';
2044
                }
2045
            }
2046
2047
            $event['title'] = $row->getTitle();
2048
            $event['className'] = 'course';
2049
            $event['allDay'] = 'false';
2050
            $event['course_id'] = $courseId;
2051
            $event['borderColor'] = $event['backgroundColor'] = $this->event_course_color;
2052
2053
            $sessionInfo = [];
2054
            if (!empty($row->getSessionId())) {
2055
                $sessionInfo = api_get_session_info($row->getSessionId());
2056
                $event['borderColor'] = $event['backgroundColor'] = $this->event_session_color;
2057
            }
2058
2059
            $event['session_name'] = $sessionInfo['name'] ?? '';
2060
            $event['course_name'] = $courseInfo['title'] ?? '';
2061
2062
            /*if (isset($row['to_group_id']) && !empty($row['to_group_id'])) {
2063
                $event['borderColor'] = $event['backgroundColor'] = $this->event_group_color;
2064
            }*/
2065
2066
            if (!empty($color)) {
2067
                $event['borderColor'] = $event['backgroundColor'] = $color;
2068
            }
2069
2070
            if ($row->getColor()) {
2071
                $event['borderColor'] = $event['backgroundColor'] = $row->getColor();
2072
            }
2073
2074
            $event['editable'] = false;
2075
            if ($this->getIsAllowedToEdit() && $this->type === 'course') {
2076
                $event['editable'] = true;
2077
                if (!empty($sessionId)) {
2078
                    if ($coachCanEdit == false) {
2079
                        $event['editable'] = false;
2080
                    }
2081
                    if ($isAllowToEditByHrm) {
2082
                        $event['editable'] = true;
2083
                    }
2084
                }
2085
                // if user is author then he can edit the item
2086
                if (api_get_user_id() == $row->getResourceNode()->getCreator()->getId()) {
2087
                    $event['editable'] = true;
2088
                }
2089
            }
2090
2091
            if (!empty($row->getStartDate())) {
2092
                $event['start'] = $this->formatEventDate($row->getStartDate()->format('Y-m-d H:i:s'));
2093
                $event['start_date_localtime'] = api_get_local_time($row->getStartDate()->format('Y-m-d H:i:s'));
2094
            }
2095
            if (!empty($row->getEndDate())) {
2096
                $event['end'] = $this->formatEventDate($row->getEndDate()->format('Y-m-d H:i:s'));
2097
                $event['end_date_localtime'] = api_get_local_time($row->getEndDate()->format('Y-m-d H:i:s'));
2098
            }
2099
2100
            $event['sent_to'] = '';
2101
            $event['type'] = 'course';
2102
            if ($row->getSessionId() != 0) {
2103
                $event['type'] = 'session';
2104
            }
2105
2106
            // Event Sent to a group?
2107
            /*if (isset($row['to_group_id']) && !empty($row['to_group_id'])) {
2108
                $sent_to = [];
2109
                if (!empty($group_to_array)) {
2110
                    foreach ($group_to_array as $group_item) {
2111
                        $sent_to[] = $groupNameList[$group_item];
2112
                    }
2113
                }
2114
                $sent_to = implode('@@', $sent_to);
2115
                $sent_to = str_replace(
2116
                    '@@',
2117
                    '</div><div class="label_tag notice">',
2118
                    $sent_to
2119
                );
2120
                $event['sent_to'] = '<div class="label_tag notice">'.$sent_to.'</div>';
2121
                $event['type'] = 'group';
2122
            }*/
2123
2124
            // Event sent to a user?
2125
            /*if (isset($row['to_user_id'])) {
2126
                $sent_to = [];
2127
                if (!empty($user_to_array)) {
2128
                    foreach ($user_to_array as $item) {
2129
                        $user_info = api_get_user_info($item);
2130
                        // Add username as tooltip for $event['sent_to'] - ref #4226
2131
                        $username = api_htmlentities(
2132
                            sprintf(
2133
                                get_lang('Login: %s'),
2134
                                $user_info['username']
2135
                            ),
2136
                            ENT_QUOTES
2137
                        );
2138
                        $sent_to[] = "<span title='".$username."'>".$user_info['complete_name']."</span>";
2139
                    }
2140
                }
2141
                $sent_to = implode('@@', $sent_to);
2142
                $sent_to = str_replace(
2143
                    '@@',
2144
                    '</div><div class="label_tag notice">',
2145
                    $sent_to
2146
                );
2147
                $event['sent_to'] = '<div class="label_tag notice">'.$sent_to.'</div>';
2148
            }*/
2149
2150
            //Event sent to everyone!
2151
            /*if (empty($event['sent_to'])) {
2152
                $event['sent_to'] = '<div class="label_tag notice">'.get_lang('Everyone').'</div>';
2153
            }*/
2154
2155
            $event['description'] = $row->getContent();
2156
            $event['visibility'] = 1;
2157
            $event['real_id'] = $eventId;
2158
            $event['allDay'] = $row->getAllDay();
2159
            $event['parent_event_id'] = $row->getParentEventId();
2160
            $event['has_children'] = $this->hasChildren($eventId, $courseId) ? 1 : 0;
2161
            $event['comment'] = $row->getComment();
2162
            $this->events[] = $event;
2163
        }
2164
2165
        return $this->events;
2166
    }
2167
2168
    /**
2169
     * @param int $start tms
2170
     * @param int $end   tms
2171
     *
2172
     * @return array
2173
     */
2174
    public function getPlatformEvents($start, $end)
2175
    {
2176
        $start = isset($start) && !empty($start) ? api_get_utc_datetime(intval($start)) : null;
2177
        $end = isset($end) && !empty($end) ? api_get_utc_datetime(intval($end)) : null;
2178
        $dateCondition = '';
2179
2180
        if (!empty($start) && !empty($end)) {
2181
            $dateCondition .= "AND (
2182
                 start_date BETWEEN '".$start."' AND '".$end."' OR
2183
                 end_date BETWEEN '".$start."' AND '".$end."' OR
2184
                 (
2185
                     start_date IS NOT NULL AND end_date IS NOT NULL AND
2186
                     YEAR(start_date) = YEAR(end_date) AND
2187
                     MONTH('$start') BETWEEN MONTH(start_date) AND MONTH(end_date)
2188
                 )
2189
            )";
2190
        }
2191
2192
        $access_url_id = api_get_current_access_url_id();
2193
2194
        $sql = "SELECT *
2195
                FROM ".$this->tbl_global_agenda."
2196
                WHERE access_url_id = $access_url_id
2197
                $dateCondition";
2198
        $result = Database::query($sql);
2199
        $my_events = [];
2200
        if (Database::num_rows($result)) {
2201
            while ($row = Database::fetch_array($result, 'ASSOC')) {
2202
                $event = [];
2203
                $event['id'] = 'platform_'.$row['id'];
2204
                $event['title'] = $row['title'];
2205
                $event['className'] = 'platform';
2206
                $event['allDay'] = 'false';
2207
                $event['borderColor'] = $event['backgroundColor'] = $this->event_platform_color;
2208
                $event['editable'] = false;
2209
                $event['type'] = 'admin';
2210
2211
                if (api_is_platform_admin() && $this->type === 'admin') {
2212
                    $event['editable'] = true;
2213
                }
2214
2215
                if (!empty($row['start_date'])) {
2216
                    $event['start'] = $this->formatEventDate($row['start_date']);
2217
                    $event['start_date_localtime'] = api_get_local_time($row['start_date']);
2218
                }
2219
2220
                if (!empty($row['end_date'])) {
2221
                    $event['end'] = $this->formatEventDate($row['end_date']);
2222
                    $event['end_date_localtime'] = api_get_local_time($row['end_date']);
2223
                }
2224
                $event['allDay'] = isset($row['all_day']) && $row['all_day'] == 1 ? $row['all_day'] : 0;
2225
                $event['parent_event_id'] = 0;
2226
                $event['has_children'] = 0;
2227
                $event['description'] = $row['content'];
2228
2229
                $my_events[] = $event;
2230
                $this->events[] = $event;
2231
            }
2232
        }
2233
2234
        return $my_events;
2235
    }
2236
2237
    /**
2238
     * @param FormValidator $form
2239
     * @param array         $groupList
2240
     * @param array         $userList
2241
     * @param array         $sendTo               array('users' => [1, 2], 'groups' => [3, 4])
2242
     * @param array         $attributes
2243
     * @param bool          $addOnlyItemsInSendTo
2244
     * @param bool          $required
2245
     */
2246
    public function setSendToSelect(
2247
        $form,
2248
        $groupList = [],
2249
        $userList = [],
2250
        $sendTo = [],
2251
        $attributes = [],
2252
        $addOnlyItemsInSendTo = false,
2253
        $required = false
2254
    ) {
2255
        $params = [
2256
            'id' => 'users_to_send_id',
2257
            'data-placeholder' => get_lang('Select'),
2258
            'multiple' => 'multiple',
2259
            'class' => 'multiple-select',
2260
        ];
2261
2262
        if (!empty($attributes)) {
2263
            $params = array_merge($params, $attributes);
2264
            if (empty($params['multiple'])) {
2265
                unset($params['multiple']);
2266
            }
2267
        }
2268
2269
        $sendToGroups = isset($sendTo['groups']) ? $sendTo['groups'] : [];
2270
        $sendToUsers = isset($sendTo['users']) ? $sendTo['users'] : [];
2271
2272
        /** @var HTML_QuickForm_select $select */
2273
        $select = $form->addSelect(
2274
            'users_to_send',
2275
            get_lang('To'),
2276
            null,
2277
            $params
2278
        );
2279
2280
        if ($required) {
2281
            $form->setRequired($select);
2282
        }
2283
2284
        $selectedEveryoneOptions = [];
2285
        if (isset($sendTo['everyone']) && $sendTo['everyone']) {
2286
            $selectedEveryoneOptions = ['selected'];
2287
            $sendToUsers = [];
2288
        }
2289
2290
        $select->addOption(
2291
            get_lang('Everyone'),
2292
            'everyone',
2293
            $selectedEveryoneOptions
2294
        );
2295
2296
        $options = [];
2297
        if (is_array($groupList)) {
2298
            foreach ($groupList as $group) {
2299
                $count_users = isset($group['count_users']) ? $group['count_users'] : $group['userNb'];
2300
                $count_users = " &ndash; $count_users ".get_lang('Users');
2301
                $option = [
2302
                    'text' => $group['name'].$count_users,
2303
                    'value' => "GROUP:".$group['id'],
2304
                ];
2305
                $selected = in_array(
2306
                    $group['id'],
2307
                    $sendToGroups
2308
                ) ? true : false;
2309
                if ($selected) {
2310
                    $option['selected'] = 'selected';
2311
                }
2312
2313
                if ($addOnlyItemsInSendTo) {
2314
                    if ($selected) {
2315
                        $options[] = $option;
2316
                    }
2317
                } else {
2318
                    $options[] = $option;
2319
                }
2320
            }
2321
            $select->addOptGroup($options, get_lang('Groups'));
2322
        }
2323
2324
        // adding the individual users to the select form
2325
        if (is_array($userList)) {
2326
            $options = [];
2327
            foreach ($userList as $user) {
2328
                if ($user['status'] == ANONYMOUS) {
2329
                    continue;
2330
                }
2331
                $option = [
2332
                    'text' => api_get_person_name(
2333
                            $user['firstname'],
2334
                            $user['lastname']
2335
                        ).' ('.$user['username'].')',
2336
                    'value' => "USER:".$user['user_id'],
2337
                ];
2338
2339
                $selected = in_array(
2340
                    $user['user_id'],
2341
                    $sendToUsers
2342
                ) ? true : false;
2343
2344
                if ($selected) {
2345
                    $option['selected'] = 'selected';
2346
                }
2347
2348
                if ($addOnlyItemsInSendTo) {
2349
                    if ($selected) {
2350
                        $options[] = $option;
2351
                    }
2352
                } else {
2353
                    $options[] = $option;
2354
                }
2355
            }
2356
2357
            $select->addOptGroup($options, get_lang('Users'));
2358
        }
2359
    }
2360
2361
    /**
2362
     * Separates the users and groups array
2363
     * users have a value USER:XXX (with XXX the user id
2364
     * groups have a value GROUP:YYY (with YYY the group id)
2365
     * use the 'everyone' key.
2366
     *
2367
     * @author Julio Montoya based in separate_users_groups in agenda.inc.php
2368
     *
2369
     * @param array $to
2370
     *
2371
     * @return array
2372
     */
2373
    public function parseSendToArray($to)
2374
    {
2375
        $groupList = [];
2376
        $userList = [];
2377
        $sendTo = null;
2378
2379
        $sendTo['everyone'] = false;
2380
        if (is_array($to) && count($to) > 0) {
2381
            foreach ($to as $item) {
2382
                if ($item == 'everyone') {
2383
                    $sendTo['everyone'] = true;
2384
                } else {
2385
                    list($type, $id) = explode(':', $item);
2386
                    switch ($type) {
2387
                        case 'GROUP':
2388
                            $groupList[] = $id;
2389
                            break;
2390
                        case 'USER':
2391
                            $userList[] = $id;
2392
                            break;
2393
                    }
2394
                }
2395
            }
2396
            $sendTo['groups'] = $groupList;
2397
            $sendTo['users'] = $userList;
2398
        }
2399
2400
        return $sendTo;
2401
    }
2402
2403
    /**
2404
     * @param array $params
2405
     *
2406
     * @return FormValidator
2407
     */
2408
    public function getForm($params = [])
2409
    {
2410
        $action = isset($params['action']) ? Security::remove_XSS($params['action']) : null;
2411
        $id = isset($params['id']) ? (int) $params['id'] : 0;
2412
2413
        $url = api_get_self().'?action='.$action.'&id='.$id.'&type='.$this->type;
2414
        if ($this->type == 'course') {
2415
            $url = api_get_self().'?'.api_get_cidreq().'&action='.$action.'&id='.$id.'&type='.$this->type;
2416
        }
2417
2418
        $form = new FormValidator(
2419
            'add_event',
2420
            'post',
2421
            $url,
2422
            null,
2423
            ['enctype' => 'multipart/form-data']
2424
        );
2425
2426
        $idAttach = isset($params['id_attach']) ? (int) $params['id_attach'] : null;
2427
        $groupId = api_get_group_id();
2428
        $form_Title = get_lang('Add event to agenda');
2429
        if (!empty($id)) {
2430
            $form_Title = get_lang('Edit event');
2431
        }
2432
2433
        $form->addHeader($form_Title);
2434
        $form->addElement('hidden', 'id', $id);
2435
        $form->addElement('hidden', 'action', $action);
2436
        $form->addElement('hidden', 'id_attach', $idAttach);
2437
2438
        $isSubEventEdition = false;
2439
        $isParentFromSerie = false;
2440
        $showAttachmentForm = true;
2441
2442
        if ($this->type == 'course') {
2443
            // Edition mode.
2444
            if (!empty($id)) {
2445
                $showAttachmentForm = false;
2446
                if (isset($params['parent_event_id']) && !empty($params['parent_event_id'])) {
2447
                    $isSubEventEdition = true;
2448
                }
2449
                if (!empty($params['repeat_info'])) {
2450
                    $isParentFromSerie = true;
2451
                }
2452
            }
2453
        }
2454
2455
        if ($isSubEventEdition) {
2456
            $form->addElement(
2457
                'label',
2458
                null,
2459
                Display::return_message(
2460
                    get_lang('Editing this event will remove it from the serie of events it is currently part of'),
2461
                    'warning'
2462
                )
2463
            );
2464
        }
2465
2466
        $form->addElement('text', 'title', get_lang('Event name'));
2467
2468
        if (isset($groupId) && !empty($groupId)) {
2469
            $form->addElement(
2470
                'hidden',
2471
                'users_to_send[]',
2472
                "GROUP:$groupId"
2473
            );
2474
            $form->addElement('hidden', 'to', 'true');
2475
        } else {
2476
            $sendTo = isset($params['send_to']) ? $params['send_to'] : ['everyone' => true];
2477
            if ($this->type == 'course') {
2478
                $this->showToForm($form, $sendTo, [], false, true);
2479
            }
2480
        }
2481
2482
        $form->addDateRangePicker(
2483
            'date_range',
2484
            get_lang('Date range'),
2485
            false,
2486
            ['id' => 'date_range']
2487
        );
2488
        $form->addElement('checkbox', 'all_day', null, get_lang('All day'));
2489
2490
        if ($this->type == 'course') {
2491
            $repeat = $form->addElement(
2492
                'checkbox',
2493
                'repeat',
2494
                null,
2495
                get_lang('Repeat event'),
2496
                ['onclick' => 'return plus_repeated_event();']
2497
            );
2498
            $form->addElement(
2499
                'html',
2500
                '<div id="options2" style="display:none">'
2501
            );
2502
            $form->addElement(
2503
                'select',
2504
                'repeat_type',
2505
                get_lang('Repeat type'),
2506
                self::getRepeatTypes()
2507
            );
2508
            $form->addElement(
2509
                'date_picker',
2510
                'repeat_end_day',
2511
                get_lang('Repeat end date'),
2512
                ['id' => 'repeat_end_date_form']
2513
            );
2514
2515
            if ($isSubEventEdition || $isParentFromSerie) {
2516
                $repeatInfo = $params['repeat_info'];
2517
                if ($isSubEventEdition) {
2518
                    $parentEvent = $params['parent_info'];
2519
                    $repeatInfo = $parentEvent['repeat_info'];
2520
                }
2521
                $params['repeat'] = 1;
2522
                $params['repeat_type'] = $repeatInfo['cal_type'];
2523
                $params['repeat_end_day'] = substr(
2524
                    api_get_local_time($repeatInfo['cal_end']),
2525
                    0,
2526
                    10
2527
                );
2528
2529
                $form->freeze(['repeat_type', 'repeat_end_day']);
2530
                $repeat->_attributes['disabled'] = 'disabled';
2531
            }
2532
            $form->addElement('html', '</div>');
2533
        }
2534
2535
        if (!empty($id)) {
2536
            if (empty($params['end_date'])) {
2537
                $params['date_range'] = $params['end_date'];
2538
            }
2539
2540
            $params['date_range'] =
2541
                substr(api_get_local_time($params['start_date']), 0, 16).' / '.
2542
                substr(api_get_local_time($params['end_date']), 0, 16);
2543
        }
2544
2545
        $toolbar = 'Agenda';
2546
        if (!api_is_allowed_to_edit(null, true)) {
2547
            $toolbar = 'AgendaStudent';
2548
        }
2549
2550
        $form->addElement(
2551
            'html_editor',
2552
            'content',
2553
            get_lang('Description'),
2554
            null,
2555
            [
2556
                'ToolbarSet' => $toolbar,
2557
                'Width' => '100%',
2558
                'Height' => '200',
2559
            ]
2560
        );
2561
2562
        if ($this->type == 'course') {
2563
            $form->addElement('textarea', 'comment', get_lang('Comment'));
2564
            $form->addLabel(
2565
                get_lang('Files attachments'),
2566
                '<div id="filepaths" class="file-upload-event">
2567
2568
                        <div id="filepath_1">
2569
                            <input type="file" name="attach_1"/>
2570
2571
                            <label>'.get_lang('Description').'</label>
2572
                            <input class="form-control" type="text" name="legend[]" />
2573
                        </div>
2574
2575
                    </div>'
2576
            );
2577
2578
            $form->addLabel(
2579
                '',
2580
                '<span id="link-more-attach">
2581
                    <a href="javascript://" onclick="return add_image_form()">'.
2582
                get_lang('Add one more file').'</a>
2583
                 </span>&nbsp;('.sprintf(
2584
                    get_lang('Maximun file size: %s'),
2585
                    format_file_size(
2586
                        api_get_setting('message_max_upload_filesize')
2587
                    )
2588
                ).')'
2589
            );
2590
2591
            if (isset($params['attachment']) && !empty($params['attachment'])) {
2592
                $attachmentList = $params['attachment'];
2593
                foreach ($attachmentList as $attachment) {
2594
                    $params['file_comment'] = $attachment['comment'];
2595
                    if (!empty($attachment['path'])) {
2596
                        $form->addElement(
2597
                            'checkbox',
2598
                            'delete_attachment['.$attachment['id'].']',
2599
                            null,
2600
                            get_lang(
2601
                                'DeleteAttachment'
2602
                            ).': '.$attachment['filename']
2603
                        );
2604
                    }
2605
                }
2606
            }
2607
2608
            $form->addElement(
2609
                'textarea',
2610
                'file_comment',
2611
                get_lang('File comment')
2612
            );
2613
        }
2614
2615
        if (empty($id)) {
2616
            $form->addElement(
2617
                'checkbox',
2618
                'add_announcement',
2619
                null,
2620
                get_lang('Add an announcement').'&nbsp('.get_lang('Send mail').')'
2621
            );
2622
        }
2623
2624
        if ($id) {
2625
            $form->addButtonUpdate(get_lang('Edit event'));
2626
        } else {
2627
            $form->addButtonSave(get_lang('Add event'));
2628
        }
2629
2630
        $form->setDefaults($params);
2631
        $form->addRule(
2632
            'date_range',
2633
            get_lang('Required field'),
2634
            'required'
2635
        );
2636
        $form->addRule('title', get_lang('Required field'), 'required');
2637
2638
        return $form;
2639
    }
2640
2641
    /**
2642
     * @param FormValidator $form
2643
     * @param array         $sendTo               array('everyone' => false, 'users' => [1, 2], 'groups' => [3, 4])
2644
     * @param array         $attributes
2645
     * @param bool          $addOnlyItemsInSendTo
2646
     * @param bool          $required
2647
     *
2648
     * @return bool
2649
     */
2650
    public function showToForm(
2651
        $form,
2652
        $sendTo = [],
2653
        $attributes = [],
2654
        $addOnlyItemsInSendTo = false,
2655
        $required = false
2656
    ) {
2657
        if ($this->type != 'course') {
2658
            return false;
2659
        }
2660
2661
        $order = 'lastname';
2662
        if (api_is_western_name_order()) {
2663
            $order = 'firstname';
2664
        }
2665
2666
        $userList = CourseManager::get_user_list_from_course_code(
2667
            api_get_course_id(),
2668
            $this->sessionId,
2669
            null,
2670
            $order
2671
        );
2672
2673
        $groupList = CourseManager::get_group_list_of_course(
2674
            api_get_course_id(),
2675
            $this->sessionId
2676
        );
2677
2678
        $this->setSendToSelect(
2679
            $form,
2680
            $groupList,
2681
            $userList,
2682
            $sendTo,
2683
            $attributes,
2684
            $addOnlyItemsInSendTo,
2685
            $required
2686
        );
2687
2688
        return true;
2689
    }
2690
2691
    /**
2692
     * @param int   $id
2693
     * @param int   $visibility 0= invisible, 1 visible
2694
     * @param array $courseInfo
2695
     * @param int   $userId
2696
     */
2697
    public static function changeVisibility(
2698
        $id,
2699
        $visibility,
2700
        $courseInfo,
2701
        $userId = null
2702
    ) {
2703
        $id = intval($id);
2704
        if (empty($userId)) {
2705
            $userId = api_get_user_id();
2706
        } else {
2707
            $userId = intval($userId);
2708
        }
2709
2710
        if ($visibility == 0) {
2711
            api_item_property_update(
2712
                $courseInfo,
2713
                TOOL_CALENDAR_EVENT,
2714
                $id,
2715
                'invisible',
2716
                $userId
2717
            );
2718
        } else {
2719
            api_item_property_update(
2720
                $courseInfo,
2721
                TOOL_CALENDAR_EVENT,
2722
                $id,
2723
                'visible',
2724
                $userId
2725
            );
2726
        }
2727
    }
2728
2729
    /**
2730
     * Get repeat types.
2731
     *
2732
     * @return array
2733
     */
2734
    public static function getRepeatTypes()
2735
    {
2736
        return [
2737
            'daily' => get_lang('Daily'),
2738
            'weekly' => get_lang('Weekly'),
2739
            'monthlyByDate' => get_lang('Monthly, by date'),
2740
            //monthlyByDay"> get_lang('Monthly, by day');
2741
            //monthlyByDayR' => get_lang('Monthly, by dayR'),
2742
            'yearly' => get_lang('Yearly'),
2743
        ];
2744
    }
2745
2746
    /**
2747
     * Show a list with all the attachments according to the post's id.
2748
     *
2749
     * @param int   $eventId
2750
     * @param array $courseInfo
2751
     *
2752
     * @return array with the post info
2753
     */
2754
    public function getAttachmentList($eventId, $courseInfo)
2755
    {
2756
        $tableAttachment = Database::get_course_table(TABLE_AGENDA_ATTACHMENT);
2757
        $courseId = (int) $courseInfo['real_id'];
2758
        $eventId = (int) $eventId;
2759
2760
        $sql = "SELECT id, path, filename, comment
2761
                FROM $tableAttachment
2762
                WHERE
2763
                    c_id = $courseId AND
2764
                    agenda_id = $eventId";
2765
        $result = Database::query($sql);
2766
        $list = [];
2767
        if (Database::num_rows($result) != 0) {
2768
            $list = Database::store_result($result, 'ASSOC');
2769
        }
2770
2771
        return $list;
2772
    }
2773
2774
    /**
2775
     * Show a list with all the attachments according to the post's id.
2776
     *
2777
     * @param int   $attachmentId
2778
     * @param int   $eventId
2779
     * @param array $courseInfo
2780
     *
2781
     * @return array with the post info
2782
     */
2783
    public function getAttachment($attachmentId, $eventId, $courseInfo)
2784
    {
2785
        if (empty($courseInfo) || empty($attachmentId) || empty($eventId)) {
2786
            return [];
2787
        }
2788
2789
        $tableAttachment = Database::get_course_table(TABLE_AGENDA_ATTACHMENT);
2790
        $courseId = (int) $courseInfo['real_id'];
2791
        $eventId = (int) $eventId;
2792
        $attachmentId = (int) $attachmentId;
2793
2794
        $row = [];
2795
        $sql = "SELECT id, path, filename, comment
2796
                FROM $tableAttachment
2797
                WHERE
2798
                    c_id = $courseId AND
2799
                    agenda_id = $eventId AND
2800
                    id = $attachmentId
2801
                ";
2802
        $result = Database::query($sql);
2803
        if (Database::num_rows($result) != 0) {
2804
            $row = Database::fetch_array($result, 'ASSOC');
2805
        }
2806
2807
        return $row;
2808
    }
2809
2810
    /**
2811
     * Add an attachment file into agenda.
2812
     *
2813
     * @param int    $eventId
2814
     * @param array  $fileUserUpload ($_FILES['user_upload'])
2815
     * @param string $comment        about file
2816
     * @param array  $courseInfo
2817
     *
2818
     * @return string
2819
     */
2820
    public function addAttachment(
2821
        $eventId,
2822
        $fileUserUpload,
2823
        $comment,
2824
        $courseInfo
2825
    ) {
2826
        $agenda_table_attachment = Database::get_course_table(TABLE_AGENDA_ATTACHMENT);
2827
        $eventId = (int) $eventId;
2828
2829
        // Storing the attachments
2830
        $upload_ok = false;
2831
        if (!empty($fileUserUpload['name'])) {
2832
            $upload_ok = process_uploaded_file($fileUserUpload);
2833
        }
2834
2835
        if (!empty($upload_ok)) {
2836
            $courseDir = $courseInfo['directory'].'/upload/calendar';
2837
            $sys_course_path = api_get_path(SYS_COURSE_PATH);
2838
            $uploadDir = $sys_course_path.$courseDir;
2839
2840
            // Try to add an extension to the file if it hasn't one
2841
            $new_file_name = add_ext_on_mime(
2842
                stripslashes($fileUserUpload['name']),
2843
                $fileUserUpload['type']
2844
            );
2845
2846
            // user's file name
2847
            $file_name = $fileUserUpload['name'];
2848
2849
            if (!filter_extension($new_file_name)) {
2850
                return Display::return_message(
2851
                    get_lang('File upload failed: this file extension or file type is prohibited'),
2852
                    'error'
2853
                );
2854
            } else {
2855
                $new_file_name = uniqid('');
2856
                $new_path = $uploadDir.'/'.$new_file_name;
2857
                $result = @move_uploaded_file(
2858
                    $fileUserUpload['tmp_name'],
2859
                    $new_path
2860
                );
2861
                $courseId = api_get_course_int_id();
2862
                $size = intval($fileUserUpload['size']);
2863
                // Storing the attachments if any
2864
                if ($result) {
2865
                    $params = [
2866
                        'c_id' => $courseId,
2867
                        'filename' => $file_name,
2868
                        'comment' => $comment,
2869
                        'path' => $new_file_name,
2870
                        'agenda_id' => $eventId,
2871
                        'size' => $size,
2872
                    ];
2873
                    $id = Database::insert($agenda_table_attachment, $params);
2874
                    if ($id) {
2875
                        $sql = "UPDATE $agenda_table_attachment
2876
                                SET id = iid WHERE iid = $id";
2877
                        Database::query($sql);
2878
2879
                        api_item_property_update(
2880
                            $courseInfo,
2881
                            'calendar_event_attachment',
2882
                            $id,
2883
                            'AgendaAttachmentAdded',
2884
                            api_get_user_id()
2885
                        );
2886
                    }
2887
                }
2888
            }
2889
        }
2890
    }
2891
2892
    /**
2893
     * @param int    $attachmentId
2894
     * @param int    $eventId
2895
     * @param array  $fileUserUpload
2896
     * @param string $comment
2897
     * @param array  $courseInfo
2898
     */
2899
    public function updateAttachment(
2900
        $attachmentId,
2901
        $eventId,
2902
        $fileUserUpload,
2903
        $comment,
2904
        $courseInfo
2905
    ) {
2906
        $attachment = $this->getAttachment(
2907
            $attachmentId,
2908
            $eventId,
2909
            $courseInfo
2910
        );
2911
        if (!empty($attachment)) {
2912
            $this->deleteAttachmentFile($attachmentId, $courseInfo);
2913
        }
2914
        $this->addAttachment($eventId, $fileUserUpload, $comment, $courseInfo);
2915
    }
2916
2917
    /**
2918
     * This function delete a attachment file by id.
2919
     *
2920
     * @param int   $attachmentId
2921
     * @param array $courseInfo
2922
     *
2923
     * @return string
2924
     */
2925
    public function deleteAttachmentFile($attachmentId, $courseInfo)
2926
    {
2927
        $table = Database::get_course_table(TABLE_AGENDA_ATTACHMENT);
2928
        $attachmentId = (int) $attachmentId;
2929
        $courseId = $courseInfo['real_id'];
2930
2931
        if (empty($courseId) || empty($attachmentId)) {
2932
            return false;
2933
        }
2934
2935
        $sql = "DELETE FROM $table
2936
                WHERE c_id = $courseId AND id = ".$attachmentId;
2937
        $result = Database::query($sql);
2938
2939
        // update item_property
2940
        api_item_property_update(
2941
            $courseInfo,
2942
            'calendar_event_attachment',
2943
            $attachmentId,
2944
            'AgendaAttachmentDeleted',
2945
            api_get_user_id()
2946
        );
2947
2948
        if (!empty($result)) {
2949
            return Display::return_message(
2950
                get_lang("The attached file has been deleted"),
2951
                'confirmation'
2952
            );
2953
        }
2954
    }
2955
2956
    /**
2957
     * @param int $eventId
2958
     *
2959
     * @return array
2960
     */
2961
    public function getAllRepeatEvents($eventId)
2962
    {
2963
        $events = [];
2964
        $eventId = (int) $eventId;
2965
2966
        switch ($this->type) {
2967
            case 'personal':
2968
                break;
2969
            case 'course':
2970
                if (!empty($this->course['real_id'])) {
2971
                    $sql = "SELECT * FROM ".$this->tbl_course_agenda."
2972
                            WHERE
2973
                                c_id = ".$this->course['real_id']." AND
2974
                                parent_event_id = ".$eventId;
2975
                    $result = Database::query($sql);
2976
                    if (Database::num_rows($result)) {
2977
                        while ($row = Database::fetch_array($result, 'ASSOC')) {
2978
                            $events[] = $row;
2979
                        }
2980
                    }
2981
                }
2982
                break;
2983
        }
2984
2985
        return $events;
2986
    }
2987
2988
    /**
2989
     * @param int $eventId
2990
     * @param int $courseId
2991
     *
2992
     * @return bool
2993
     */
2994
    public function hasChildren($eventId, $courseId)
2995
    {
2996
        $eventId = (int) $eventId;
2997
        $courseId = (int) $courseId;
2998
2999
        $sql = "SELECT count(DISTINCT(id)) as count
3000
                FROM ".$this->tbl_course_agenda."
3001
                WHERE
3002
                    c_id = $courseId AND
3003
                    parent_event_id = $eventId";
3004
        $result = Database::query($sql);
3005
        if (Database::num_rows($result)) {
3006
            $row = Database::fetch_array($result, 'ASSOC');
3007
3008
            return $row['count'] > 0;
3009
        }
3010
3011
        return false;
3012
    }
3013
3014
    /**
3015
     * @param int    $filter
3016
     * @param string $view
3017
     *
3018
     * @return string
3019
     */
3020
    public function displayActions($view, $filter = 0)
3021
    {
3022
        $groupInfo = GroupManager::get_group_properties(api_get_group_id());
3023
        $groupIid = isset($groupInfo['iid']) ? $groupInfo['iid'] : 0;
3024
3025
        $codePath = api_get_path(WEB_CODE_PATH);
3026
3027
        $currentUserId = api_get_user_id();
3028
        $cidReq = api_get_cidreq();
3029
3030
        $actionsLeft = '';
3031
        $actionsLeft .= Display::url(
3032
            Display::return_icon('calendar.png', get_lang('Calendar'), [], ICON_SIZE_MEDIUM),
3033
            $codePath."calendar/agenda_js.php?type={$this->type}&$cidReq"
3034
        );
3035
        $actionsLeft .= Display::url(
3036
            Display::return_icon('week.png', get_lang('Agenda list'), [], ICON_SIZE_MEDIUM),
3037
            $codePath."calendar/agenda_list.php?type={$this->type}&$cidReq"
3038
        );
3039
3040
        $form = '';
3041
        if (api_is_allowed_to_edit(false, true) ||
3042
            (api_get_course_setting('allow_user_edit_agenda') == '1' && !api_is_anonymous()) &&
3043
            api_is_allowed_to_session_edit(false, true)
3044
            || (
3045
                GroupManager::user_has_access($currentUserId, $groupIid, GroupManager::GROUP_TOOL_CALENDAR)
3046
                && GroupManager::is_tutor_of_group($currentUserId, $groupInfo)
3047
            )
3048
        ) {
3049
            $actionsLeft .= Display::url(
3050
                Display::return_icon('new_event.png', get_lang('Add event'), [], ICON_SIZE_MEDIUM),
3051
                $codePath."calendar/agenda.php?action=add&type={$this->type}&$cidReq"
3052
            );
3053
3054
            $actionsLeft .= Display::url(
3055
                Display::return_icon('import_calendar.png', get_lang('Outlook import'), [], ICON_SIZE_MEDIUM),
3056
                $codePath."calendar/agenda.php?action=importical&type={$this->type}&$cidReq"
3057
            );
3058
3059
            if ($this->type === 'course') {
3060
                if (!isset($_GET['action'])) {
3061
                    $form = new FormValidator(
3062
                        'form-search',
3063
                        'post',
3064
                        '',
3065
                        '',
3066
                        [],
3067
                        FormValidator::LAYOUT_INLINE
3068
                    );
3069
                    $attributes = [
3070
                        'multiple' => false,
3071
                        'id' => 'select_form_id_search',
3072
                    ];
3073
                    $selectedValues = $this->parseAgendaFilter($filter);
3074
                    $this->showToForm($form, $selectedValues, $attributes);
3075
                    $form = $form->returnForm();
3076
                }
3077
            }
3078
        }
3079
3080
        if ($this->type == 'personal' && !api_is_anonymous()) {
3081
            $actionsLeft .= Display::url(
3082
                Display::return_icon('1day.png', get_lang('Sessions plan calendar'), [], ICON_SIZE_MEDIUM),
3083
                $codePath."calendar/planification.php"
3084
            );
3085
        }
3086
3087
        if (api_is_platform_admin() ||
3088
            api_is_teacher() ||
3089
            api_is_student_boss() ||
3090
            api_is_drh() ||
3091
            api_is_session_admin() ||
3092
            api_is_coach()
3093
        ) {
3094
            if ($this->type == 'personal') {
3095
                $form = null;
3096
                if (!isset($_GET['action'])) {
3097
                    $form = new FormValidator(
3098
                        'form-search',
3099
                        'get',
3100
                        api_get_self().'?type=personal&',
3101
                        '',
3102
                        [],
3103
                        FormValidator::LAYOUT_INLINE
3104
                    );
3105
3106
                    $sessions = [];
3107
3108
                    if (api_is_drh()) {
3109
                        $sessionList = SessionManager::get_sessions_followed_by_drh($currentUserId);
3110
                        if (!empty($sessionList)) {
3111
                            foreach ($sessionList as $sessionItem) {
3112
                                $sessions[$sessionItem['id']] = strip_tags($sessionItem['name']);
3113
                            }
3114
                        }
3115
                    } else {
3116
                        $sessions = SessionManager::get_sessions_by_user($currentUserId);
3117
                        $sessions = array_column($sessions, 'session_name', 'session_id');
3118
                    }
3119
3120
                    $form->addHidden('type', 'personal');
3121
                    $sessions = ['0' => get_lang('Please select an option')] + $sessions;
3122
3123
                    $form->addSelect(
3124
                        'session_id',
3125
                        get_lang('Session'),
3126
                        $sessions,
3127
                        ['id' => 'session_id', 'onchange' => 'submit();']
3128
                    );
3129
3130
                    $form->addButtonReset(get_lang('Reset'));
3131
                    $form = $form->returnForm();
3132
                }
3133
            }
3134
        }
3135
3136
        $actionsRight = '';
3137
        if ($view == 'calendar') {
3138
            $actionsRight .= $form;
3139
        }
3140
3141
        $toolbar = Display::toolbarAction(
3142
            'toolbar-agenda',
3143
            [$actionsLeft, $actionsRight]
3144
        );
3145
3146
        return $toolbar;
3147
    }
3148
3149
    /**
3150
     * @return FormValidator
3151
     */
3152
    public function getImportCalendarForm()
3153
    {
3154
        $form = new FormValidator(
3155
            'frm_import_ical',
3156
            'post',
3157
            api_get_self().'?action=importical&type='.$this->type,
3158
            ['enctype' => 'multipart/form-data']
3159
        );
3160
        $form->addHeader(get_lang('Outlook import'));
3161
        $form->addElement('file', 'ical_import', get_lang('Outlook import'));
3162
        $form->addRule(
3163
            'ical_import',
3164
            get_lang('Required field'),
3165
            'required'
3166
        );
3167
        $form->addButtonImport(get_lang('Import'), 'ical_submit');
3168
3169
        return $form;
3170
    }
3171
3172
    /**
3173
     * @param array $courseInfo
3174
     * @param $file
3175
     *
3176
     * @return false|string
3177
     */
3178
    public function importEventFile($courseInfo, $file)
3179
    {
3180
        $charset = api_get_system_encoding();
3181
        $filepath = api_get_path(SYS_ARCHIVE_PATH).$file['name'];
3182
        $messages = [];
3183
3184
        if (!@move_uploaded_file($file['tmp_name'], $filepath)) {
3185
            error_log(
3186
                'Problem moving uploaded file: '.$file['error'].' in '.__FILE__.' line '.__LINE__
3187
            );
3188
3189
            return false;
3190
        }
3191
3192
        $data = file_get_contents($filepath);
3193
3194
        $trans = [
3195
            'DAILY' => 'daily',
3196
            'WEEKLY' => 'weekly',
3197
            'MONTHLY' => 'monthlyByDate',
3198
            'YEARLY' => 'yearly',
3199
        ];
3200
        $sentTo = ['everyone' => true];
3201
        $calendar = Sabre\VObject\Reader::read($data);
3202
        $currentTimeZone = api_get_timezone();
3203
        if (!empty($calendar->VEVENT)) {
3204
            foreach ($calendar->VEVENT as $event) {
3205
                $start = $event->DTSTART->getDateTime();
3206
                $end = $event->DTEND->getDateTime();
3207
                //Sabre\VObject\DateTimeParser::parseDateTime(string $dt, \Sabre\VObject\DateTimeZone $tz)
3208
3209
                $startDateTime = api_get_local_time(
3210
                    $start->format('Y-m-d H:i:s'),
3211
                    $currentTimeZone,
3212
                    $start->format('e')
3213
                );
3214
                $endDateTime = api_get_local_time(
3215
                    $end->format('Y-m-d H:i'),
3216
                    $currentTimeZone,
3217
                    $end->format('e')
3218
                );
3219
                $title = api_convert_encoding(
3220
                    (string) $event->summary,
3221
                    $charset,
3222
                    'UTF-8'
3223
                );
3224
                $description = api_convert_encoding(
3225
                    (string) $event->description,
3226
                    $charset,
3227
                    'UTF-8'
3228
                );
3229
3230
                $id = $this->addEvent(
3231
                    $startDateTime,
3232
                    $endDateTime,
3233
                    'false',
3234
                    $title,
3235
                    $description,
3236
                    $sentTo
3237
                );
3238
3239
                $messages[] = " $title - ".$startDateTime." - ".$endDateTime;
3240
3241
                //$attendee = (string)$event->attendee;
3242
                /** @var Sabre\VObject\Property\ICalendar\Recur $repeat */
3243
                $repeat = $event->RRULE;
3244
                if ($id && !empty($repeat)) {
3245
                    $repeat = $repeat->getParts();
3246
                    $freq = $trans[$repeat['FREQ']];
3247
3248
                    if (isset($repeat['UNTIL']) && !empty($repeat['UNTIL'])) {
3249
                        // Check if datetime or just date (strlen == 8)
3250
                        if (strlen($repeat['UNTIL']) == 8) {
3251
                            // Fix the datetime format to avoid exception in the next step
3252
                            $repeat['UNTIL'] .= 'T000000';
3253
                        }
3254
                        $until = Sabre\VObject\DateTimeParser::parseDateTime(
3255
                            $repeat['UNTIL'],
3256
                            new DateTimeZone($currentTimeZone)
3257
                        );
3258
                        $until = $until->format('Y-m-d H:i:s');
3259
                        $this->addRepeatedItem(
3260
                            $id,
3261
                            $freq,
3262
                            $until,
3263
                            $sentTo
3264
                        );
3265
                    }
3266
                }
3267
            }
3268
        }
3269
3270
        if (!empty($messages)) {
3271
            $messages = implode('<br /> ', $messages);
3272
        } else {
3273
            $messages = get_lang('There are no events');
3274
        }
3275
3276
        return $messages;
3277
    }
3278
3279
    /**
3280
     * Parse filter turns USER:12 to ['users' => [12])] or G:1 ['groups' => [1]].
3281
     *
3282
     * @param int $filter
3283
     *
3284
     * @return array
3285
     */
3286
    public function parseAgendaFilter($filter)
3287
    {
3288
        $everyone = false;
3289
        $groupId = null;
3290
        $userId = null;
3291
3292
        if ($filter === 'everyone') {
3293
            $everyone = true;
3294
        } else {
3295
            if (substr($filter, 0, 1) === 'G') {
3296
                $groupId = str_replace('GROUP:', '', $filter);
3297
            } else {
3298
                $userId = str_replace('USER:', '', $filter);
3299
            }
3300
        }
3301
        if (empty($userId) && empty($groupId)) {
3302
            $everyone = true;
3303
        }
3304
3305
        return [
3306
            'everyone' => $everyone,
3307
            'users' => [$userId],
3308
            'groups' => [$groupId],
3309
        ];
3310
    }
3311
3312
    /**
3313
     *    This function retrieves all the agenda items of all the courses the user is subscribed to.
3314
     */
3315
    public static function get_myagendaitems(
3316
        $user_id,
3317
        $courses_dbs,
3318
        $month,
3319
        $year
3320
    ) {
3321
        $user_id = (int) $user_id;
3322
3323
        $items = [];
3324
        $my_list = [];
3325
3326
        // get agenda-items for every course
3327
        foreach ($courses_dbs as $key => $array_course_info) {
3328
            //databases of the courses
3329
            $TABLEAGENDA = Database::get_course_table(TABLE_AGENDA);
3330
            $TABLE_ITEMPROPERTY = Database::get_course_table(
3331
                TABLE_ITEM_PROPERTY
3332
            );
3333
3334
            $group_memberships = GroupManager::get_group_ids(
3335
                $array_course_info['real_id'],
3336
                $user_id
3337
            );
3338
            $course_user_status = CourseManager::getUserInCourseStatus(
3339
                $user_id,
3340
                $array_course_info['real_id']
3341
            );
3342
            // if the user is administrator of that course we show all the agenda items
3343
            if ($course_user_status == '1') {
3344
                //echo "course admin";
3345
                $sqlquery = "SELECT DISTINCT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref
3346
							FROM ".$TABLEAGENDA." agenda,
3347
								 ".$TABLE_ITEMPROPERTY." ip
3348
							WHERE agenda.id = ip.ref
3349
							AND MONTH(agenda.start_date)='".$month."'
3350
							AND YEAR(agenda.start_date)='".$year."'
3351
							AND ip.tool='".TOOL_CALENDAR_EVENT."'
3352
							AND ip.visibility='1'
3353
							GROUP BY agenda.id
3354
							ORDER BY start_date ";
3355
            } else {
3356
                // if the user is not an administrator of that course
3357
                if (is_array($group_memberships) && count(
3358
                        $group_memberships
3359
                    ) > 0
3360
                ) {
3361
                    $sqlquery = "SELECT	agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref
3362
								FROM ".$TABLEAGENDA." agenda,
3363
									".$TABLE_ITEMPROPERTY." ip
3364
								WHERE agenda.id = ip.ref
3365
								AND MONTH(agenda.start_date)='".$month."'
3366
								AND YEAR(agenda.start_date)='".$year."'
3367
								AND ip.tool='".TOOL_CALENDAR_EVENT."'
3368
								AND	( ip.to_user_id='".$user_id."' OR (ip.to_group_id IS NULL OR ip.to_group_id IN (0, ".implode(
3369
                            ", ",
3370
                            $group_memberships
3371
                        ).")) )
3372
								AND ip.visibility='1'
3373
								ORDER BY start_date ";
3374
                } else {
3375
                    $sqlquery = "SELECT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref
3376
								FROM ".$TABLEAGENDA." agenda,
3377
									".$TABLE_ITEMPROPERTY." ip
3378
								WHERE agenda.id = ip.ref
3379
								AND MONTH(agenda.start_date)='".$month."'
3380
								AND YEAR(agenda.start_date)='".$year."'
3381
								AND ip.tool='".TOOL_CALENDAR_EVENT."'
3382
								AND ( ip.to_user_id='".$user_id."' OR ip.to_group_id='0' OR ip.to_group_id IS NULL)
3383
								AND ip.visibility='1'
3384
								ORDER BY start_date ";
3385
                }
3386
            }
3387
            $result = Database::query($sqlquery);
3388
3389
            while ($item = Database::fetch_array($result, 'ASSOC')) {
3390
                $agendaday = -1;
3391
                if (!empty($item['start_date'])) {
3392
                    $item['start_date'] = api_get_local_time(
3393
                        $item['start_date']
3394
                    );
3395
                    $item['start_date_tms'] = api_strtotime(
3396
                        $item['start_date']
3397
                    );
3398
                    $agendaday = date("j", $item['start_date_tms']);
3399
                }
3400
                if (!empty($item['end_date'])) {
3401
                    $item['end_date'] = api_get_local_time($item['end_date']);
3402
                }
3403
3404
                $url = api_get_path(
3405
                        WEB_CODE_PATH
3406
                    )."calendar/agenda.php?cidReq=".urlencode(
3407
                        $array_course_info["code"]
3408
                    )."&day=$agendaday&month=$month&year=$year#$agendaday";
3409
3410
                $item['url'] = $url;
3411
                $item['course_name'] = $array_course_info['title'];
3412
                $item['calendar_type'] = 'course';
3413
                $item['course_id'] = $array_course_info['course_id'];
3414
3415
                $my_list[$agendaday][] = $item;
3416
            }
3417
        }
3418
3419
        // sorting by hour for every day
3420
        $agendaitems = [];
3421
        foreach ($items as $agendaday => $tmpitems) {
3422
            if (!isset($agendaitems[$agendaday])) {
3423
                $agendaitems[$agendaday] = '';
3424
            }
3425
            sort($tmpitems);
3426
            foreach ($tmpitems as $val) {
3427
                $agendaitems[$agendaday] .= $val;
3428
            }
3429
        }
3430
3431
        return $my_list;
3432
    }
3433
3434
    /**
3435
     * This function retrieves one personal agenda item returns it.
3436
     *
3437
     * @param    array    The array containing existing events. We add to this array.
3438
     * @param    int        Day
3439
     * @param    int        Month
3440
     * @param    int        Year (4 digits)
3441
     * @param    int        Week number
3442
     * @param    string    Type of view (month_view, week_view, day_view)
3443
     *
3444
     * @return array The results of the database query, or null if not found
3445
     */
3446
    public static function get_global_agenda_items(
3447
        $agendaitems,
3448
        $day = "",
3449
        $month = "",
3450
        $year = "",
3451
        $week = "",
3452
        $type
3453
    ) {
3454
        $tbl_global_agenda = Database::get_main_table(
3455
            TABLE_MAIN_SYSTEM_CALENDAR
3456
        );
3457
        $month = intval($month);
3458
        $year = intval($year);
3459
        $week = intval($week);
3460
        $day = intval($day);
3461
        // 1. creating the SQL statement for getting the personal agenda items in MONTH view
3462
3463
        $current_access_url_id = api_get_current_access_url_id();
3464
3465
        if ($type == "month_view" or $type == "") {
3466
            // We are in month view
3467
            $sql = "SELECT * FROM ".$tbl_global_agenda." WHERE MONTH(start_date) = ".$month." AND YEAR(start_date) = ".$year."  AND access_url_id = $current_access_url_id ORDER BY start_date ASC";
3468
        }
3469
        // 2. creating the SQL statement for getting the personal agenda items in WEEK view
3470
        if ($type == "week_view") { // we are in week view
3471
            $start_end_day_of_week = self::calculate_start_end_of_week(
3472
                $week,
3473
                $year
3474
            );
3475
            $start_day = $start_end_day_of_week['start']['day'];
3476
            $start_month = $start_end_day_of_week['start']['month'];
3477
            $start_year = $start_end_day_of_week['start']['year'];
3478
            $end_day = $start_end_day_of_week['end']['day'];
3479
            $end_month = $start_end_day_of_week['end']['month'];
3480
            $end_year = $start_end_day_of_week['end']['year'];
3481
            // in sql statements you have to use year-month-day for date calculations
3482
            $start_filter = $start_year."-".$start_month."-".$start_day." 00:00:00";
3483
            $start_filter = api_get_utc_datetime($start_filter);
3484
3485
            $end_filter = $end_year."-".$end_month."-".$end_day." 23:59:59";
3486
            $end_filter = api_get_utc_datetime($end_filter);
3487
            $sql = " SELECT * FROM ".$tbl_global_agenda." WHERE start_date>='".$start_filter."' AND start_date<='".$end_filter."' AND  access_url_id = $current_access_url_id ";
3488
        }
3489
        // 3. creating the SQL statement for getting the personal agenda items in DAY view
3490
        if ($type == "day_view") { // we are in day view
3491
            // we could use mysql date() function but this is only available from 4.1 and higher
3492
            $start_filter = $year."-".$month."-".$day." 00:00:00";
3493
            $start_filter = api_get_utc_datetime($start_filter);
3494
3495
            $end_filter = $year."-".$month."-".$day." 23:59:59";
3496
            $end_filter = api_get_utc_datetime($end_filter);
3497
            $sql = " SELECT * FROM ".$tbl_global_agenda." WHERE start_date>='".$start_filter."' AND start_date<='".$end_filter."'  AND  access_url_id = $current_access_url_id";
3498
        }
3499
3500
        $result = Database::query($sql);
3501
3502
        while ($item = Database::fetch_array($result)) {
3503
            if (!empty($item['start_date'])) {
3504
                $item['start_date'] = api_get_local_time($item['start_date']);
3505
                $item['start_date_tms'] = api_strtotime($item['start_date']);
3506
            }
3507
            if (!empty($item['end_date'])) {
3508
                $item['end_date'] = api_get_local_time($item['end_date']);
3509
            }
3510
3511
            // we break the date field in the database into a date and a time part
3512
            $agenda_db_date = explode(" ", $item['start_date']);
3513
            $date = $agenda_db_date[0];
3514
            $time = $agenda_db_date[1];
3515
            // we divide the date part into a day, a month and a year
3516
            $agendadate = explode("-", $date);
3517
            $year = intval($agendadate[0]);
3518
            $month = intval($agendadate[1]);
3519
            $day = intval($agendadate[2]);
3520
            // we divide the time part into hour, minutes, seconds
3521
            $agendatime = explode(":", $time);
3522
            $hour = $agendatime[0];
3523
            $minute = $agendatime[1];
3524
            $second = $agendatime[2];
3525
3526
            if ($type == 'month_view') {
3527
                $item['calendar_type'] = 'global';
3528
                $agendaitems[$day][] = $item;
3529
                continue;
3530
            }
3531
3532
            $start_time = api_format_date(
3533
                $item['start_date'],
3534
                TIME_NO_SEC_FORMAT
3535
            );
3536
            $end_time = '';
3537
            if (!empty($item['end_date'])) {
3538
                $end_time = ' - '.api_format_date(
3539
                        $item['end_date'],
3540
                        DATE_TIME_FORMAT_LONG
3541
                    );
3542
            }
3543
3544
            // Creating the array that will be returned. If we have week or month view we have an array with the date as the key
3545
            // if we have a day_view we use a half hour as index => key 33 = 16h30
3546
            if ($type !== "day_view") {
3547
                // This is the array construction for the WEEK or MONTH view
3548
                //Display the Agenda global in the tab agenda (administrator)
3549
                $agendaitems[$day] .= "<i>$start_time $end_time</i>&nbsp;-&nbsp;";
3550
                $agendaitems[$day] .= "<b>".get_lang('Platform event')."</b>";
3551
                $agendaitems[$day] .= "<div>".$item['title']."</div><br>";
3552
            } else {
3553
                // this is the array construction for the DAY view
3554
                $halfhour = 2 * $agendatime['0'];
3555
                if ($agendatime['1'] >= '30') {
3556
                    $halfhour = $halfhour + 1;
3557
                }
3558
                if (!is_array($agendaitems[$halfhour])) {
3559
                    $content = $agendaitems[$halfhour];
3560
                }
3561
                $agendaitems[$halfhour] = $content."<div><i>$hour:$minute</i> <b>".get_lang(
3562
                        'Platform event'
3563
                    ).":  </b>".$item['title']."</div>";
3564
            }
3565
        }
3566
3567
        return $agendaitems;
3568
    }
3569
3570
    /**
3571
     * This function retrieves all the personal agenda items and add them to the agenda items found by the other
3572
     * functions.
3573
     */
3574
    public static function get_personal_agenda_items(
3575
        $user_id,
3576
        $agendaitems,
3577
        $day = "",
3578
        $month = "",
3579
        $year = "",
3580
        $week = "",
3581
        $type
3582
    ) {
3583
        $tbl_personal_agenda = Database::get_main_table(TABLE_PERSONAL_AGENDA);
3584
        $user_id = intval($user_id);
3585
3586
        // 1. creating the SQL statement for getting the personal agenda items in MONTH view
3587
        if ($type == "month_view" or $type == "") {
3588
            // we are in month view
3589
            $sql = "SELECT * FROM ".$tbl_personal_agenda." WHERE user='".$user_id."' and MONTH(date)='".$month."' AND YEAR(date) = '".$year."'  ORDER BY date ASC";
3590
        }
3591
3592
        // 2. creating the SQL statement for getting the personal agenda items in WEEK view
3593
        // we are in week view
3594
        if ($type == "week_view") {
3595
            $start_end_day_of_week = self::calculate_start_end_of_week(
3596
                $week,
3597
                $year
3598
            );
3599
            $start_day = $start_end_day_of_week['start']['day'];
3600
            $start_month = $start_end_day_of_week['start']['month'];
3601
            $start_year = $start_end_day_of_week['start']['year'];
3602
            $end_day = $start_end_day_of_week['end']['day'];
3603
            $end_month = $start_end_day_of_week['end']['month'];
3604
            $end_year = $start_end_day_of_week['end']['year'];
3605
            // in sql statements you have to use year-month-day for date calculations
3606
            $start_filter = $start_year."-".$start_month."-".$start_day." 00:00:00";
3607
            $start_filter = api_get_utc_datetime($start_filter);
3608
            $end_filter = $end_year."-".$end_month."-".$end_day." 23:59:59";
3609
            $end_filter = api_get_utc_datetime($end_filter);
3610
            $sql = " SELECT * FROM ".$tbl_personal_agenda." WHERE user='".$user_id."' AND date>='".$start_filter."' AND date<='".$end_filter."'";
3611
        }
3612
        // 3. creating the SQL statement for getting the personal agenda items in DAY view
3613
        if ($type == "day_view") {
3614
            // we are in day view
3615
            // we could use mysql date() function but this is only available from 4.1 and higher
3616
            $start_filter = $year."-".$month."-".$day." 00:00:00";
3617
            $start_filter = api_get_utc_datetime($start_filter);
3618
            $end_filter = $year."-".$month."-".$day." 23:59:59";
3619
            $end_filter = api_get_utc_datetime($end_filter);
3620
            $sql = " SELECT * FROM ".$tbl_personal_agenda." WHERE user='".$user_id."' AND date>='".$start_filter."' AND date<='".$end_filter."'";
3621
        }
3622
3623
        $result = Database::query($sql);
3624
        while ($item = Database::fetch_array($result, 'ASSOC')) {
3625
            $time_minute = api_convert_and_format_date(
3626
                $item['date'],
3627
                TIME_NO_SEC_FORMAT
3628
            );
3629
            $item['date'] = api_get_local_time($item['date']);
3630
            $item['start_date_tms'] = api_strtotime($item['date']);
3631
            $item['content'] = $item['text'];
3632
3633
            // we break the date field in the database into a date and a time part
3634
            $agenda_db_date = explode(" ", $item['date']);
3635
            $date = $agenda_db_date[0];
3636
            $time = $agenda_db_date[1];
3637
            // we divide the date part into a day, a month and a year
3638
            $agendadate = explode("-", $item['date']);
3639
            $year = intval($agendadate[0]);
3640
            $month = intval($agendadate[1]);
3641
            $day = intval($agendadate[2]);
3642
            // we divide the time part into hour, minutes, seconds
3643
            $agendatime = explode(":", $time);
3644
3645
            $hour = $agendatime[0];
3646
            $minute = $agendatime[1];
3647
            $second = $agendatime[2];
3648
3649
            if ($type == 'month_view') {
3650
                $item['calendar_type'] = 'personal';
3651
                $item['start_date'] = $item['date'];
3652
                $agendaitems[$day][] = $item;
3653
                continue;
3654
            }
3655
3656
            // Creating the array that will be returned. If we have week or month view we have an array with the date as the key
3657
            // if we have a day_view we use a half hour as index => key 33 = 16h30
3658
            if ($type !== "day_view") {
3659
                // This is the array construction for the WEEK or MONTH view
3660
3661
                //Display events in agenda
3662
                $agendaitems[$day] .= "<div><i>$time_minute</i> $course_link <a href=\"myagenda.php?action=view&view=personal&day=$day&month=$month&year=$year&id=".$item['id']."#".$item['id']."\" class=\"personal_agenda\">".$item['title']."</a></div><br />";
3663
            } else {
3664
                // this is the array construction for the DAY view
3665
                $halfhour = 2 * $agendatime['0'];
3666
                if ($agendatime['1'] >= '30') {
3667
                    $halfhour = $halfhour + 1;
3668
                }
3669
3670
                //Display events by list
3671
                $agendaitems[$halfhour] .= "<div><i>$time_minute</i> $course_link <a href=\"myagenda.php?action=view&view=personal&day=$day&month=$month&year=$year&id=".$item['id']."#".$item['id']."\" class=\"personal_agenda\">".$item['title']."</a></div>";
3672
            }
3673
        }
3674
3675
        return $agendaitems;
3676
    }
3677
3678
    /**
3679
     * Show the monthcalender of the given month.
3680
     *
3681
     * @param    array    Agendaitems
3682
     * @param    int    Month number
3683
     * @param    int    Year number
3684
     * @param    array    Array of strings containing long week day names (deprecated, you can send an empty array
3685
     *                          instead)
3686
     * @param    string    The month name
3687
     */
3688
    public static function display_mymonthcalendar(
3689
        $user_id,
3690
        $agendaitems,
3691
        $month,
3692
        $year,
3693
        $weekdaynames = [],
3694
        $monthName,
3695
        $show_content = true
3696
    ) {
3697
        global $DaysShort, $course_path;
3698
        //Handle leap year
3699
        $numberofdays = [
3700
            0,
3701
            31,
3702
            28,
3703
            31,
3704
            30,
3705
            31,
3706
            30,
3707
            31,
3708
            31,
3709
            30,
3710
            31,
3711
            30,
3712
            31,
3713
        ];
3714
        if (($year % 400 == 0) or ($year % 4 == 0 and $year % 100 != 0)) {
3715
            $numberofdays[2] = 29;
3716
        }
3717
        //Get the first day of the month
3718
        $dayone = getdate(mktime(0, 0, 0, $month, 1, $year));
3719
        //Start the week on monday
3720
        $startdayofweek = $dayone['wday'] != 0 ? ($dayone['wday'] - 1) : 6;
3721
        $g_cc = (isset($_GET['courseCode']) ? $_GET['courseCode'] : '');
3722
3723
        $next_month = ($month == 1 ? 12 : $month - 1);
3724
        $prev_month = ($month == 12 ? 1 : $month + 1);
3725
3726
        $next_year = ($month == 1 ? $year - 1 : $year);
3727
        $prev_year = ($month == 12 ? $year + 1 : $year);
3728
3729
        if ($show_content) {
3730
            $back_url = Display::url(
3731
                get_lang('Previous'),
3732
                api_get_self()."?coursePath=".urlencode(
3733
                    $course_path
3734
                )."&courseCode=".Security::remove_XSS(
3735
                    $g_cc
3736
                )."&action=view&view=month&month=".$next_month."&year=".$next_year
3737
            );
3738
            $next_url = Display::url(
3739
                get_lang('Next'),
3740
                api_get_self()."?coursePath=".urlencode(
3741
                    $course_path
3742
                )."&courseCode=".Security::remove_XSS(
3743
                    $g_cc
3744
                )."&action=view&view=month&month=".$prev_month."&year=".$prev_year
3745
            );
3746
        } else {
3747
            $back_url = Display::url(
3748
                get_lang('Previous'),
3749
                '',
3750
                [
3751
                    'onclick' => "load_calendar('".$user_id."','".$next_month."', '".$next_year."'); ",
3752
                    'class' => 'btn ui-button ui-widget ui-state-default',
3753
                ]
3754
            );
3755
            $next_url = Display::url(
3756
                get_lang('Next'),
3757
                '',
3758
                [
3759
                    'onclick' => "load_calendar('".$user_id."','".$prev_month."', '".$prev_year."'); ",
3760
                    'class' => 'pull-right btn ui-button ui-widget ui-state-default',
3761
                ]
3762
            );
3763
        }
3764
        $html = '';
3765
        $html .= '<div class="actions">';
3766
        $html .= '<div class="row">';
3767
        $html .= '<div class="col-md-4">'.$back_url.'</div>';
3768
        $html .= '<div class="col-md-4"><p class="agenda-title text-center">'.$monthName." ".$year.'</p></div>';
3769
        $html .= '<div class="col-md-4">'.$next_url.'</div>';
3770
        $html .= '</div>';
3771
        $html .= '</div>';
3772
        $html .= '<table id="agenda_list2" class="table table-bordered">';
3773
        $html .= '<tr>';
3774
        for ($ii = 1; $ii < 8; $ii++) {
3775
            $html .= '<td class="weekdays">'.$DaysShort[$ii % 7].'</td>';
3776
        }
3777
        $html .= '</tr>';
3778
3779
        $curday = -1;
3780
        $today = getdate();
3781
        while ($curday <= $numberofdays[$month]) {
3782
            $html .= "<tr>";
3783
            for ($ii = 0; $ii < 7; $ii++) {
3784
                if (($curday == -1) && ($ii == $startdayofweek)) {
3785
                    $curday = 1;
3786
                }
3787
                if (($curday > 0) && ($curday <= $numberofdays[$month])) {
3788
                    $bgcolor = $class = 'class="days_week"';
3789
                    $dayheader = Display::div(
3790
                        $curday,
3791
                        ['class' => 'agenda_day']
3792
                    );
3793
                    if (($curday == $today['mday']) && ($year == $today['year']) && ($month == $today['mon'])) {
3794
                        $class = "class=\"days_today\" style=\"width:10%;\"";
3795
                    }
3796
3797
                    $html .= "<td ".$class.">".$dayheader;
3798
3799
                    if (!empty($agendaitems[$curday])) {
3800
                        $items = $agendaitems[$curday];
3801
                        $items = msort($items, 'start_date_tms');
3802
3803
                        foreach ($items as $value) {
3804
                            $value['title'] = Security::remove_XSS(
3805
                                $value['title']
3806
                            );
3807
                            $start_time = api_format_date(
3808
                                $value['start_date'],
3809
                                TIME_NO_SEC_FORMAT
3810
                            );
3811
                            $end_time = '';
3812
3813
                            if (!empty($value['end_date'])) {
3814
                                $end_time = '-&nbsp;<i>'.api_format_date(
3815
                                        $value['end_date'],
3816
                                        DATE_TIME_FORMAT_LONG
3817
                                    ).'</i>';
3818
                            }
3819
                            $complete_time = '<i>'.api_format_date(
3820
                                    $value['start_date'],
3821
                                    DATE_TIME_FORMAT_LONG
3822
                                ).'</i>&nbsp;'.$end_time;
3823
                            $time = '<i>'.$start_time.'</i>';
3824
3825
                            switch ($value['calendar_type']) {
3826
                                case 'personal':
3827
                                    $bg_color = '#D0E7F4';
3828
                                    $icon = Display::return_icon(
3829
                                        'user.png',
3830
                                        get_lang('Personal agenda'),
3831
                                        [],
3832
                                        ICON_SIZE_SMALL
3833
                                    );
3834
                                    break;
3835
                                case 'global':
3836
                                    $bg_color = '#FFBC89';
3837
                                    $icon = Display::return_icon(
3838
                                        'view_remove.png',
3839
                                        get_lang('Platform event'),
3840
                                        [],
3841
                                        ICON_SIZE_SMALL
3842
                                    );
3843
                                    break;
3844
                                case 'course':
3845
                                    $bg_color = '#CAFFAA';
3846
                                    $icon_name = 'course.png';
3847
                                    if (!empty($value['session_id'])) {
3848
                                        $icon_name = 'session.png';
3849
                                    }
3850
                                    if ($show_content) {
3851
                                        $icon = Display::url(
3852
                                            Display::return_icon(
3853
                                                $icon_name,
3854
                                                $value['course_name'].' '.get_lang(
3855
                                                    'Course'
3856
                                                ),
3857
                                                [],
3858
                                                ICON_SIZE_SMALL
3859
                                            ),
3860
                                            $value['url']
3861
                                        );
3862
                                    } else {
3863
                                        $icon = Display::return_icon(
3864
                                            $icon_name,
3865
                                            $value['course_name'].' '.get_lang(
3866
                                                'Course'
3867
                                            ),
3868
                                            [],
3869
                                            ICON_SIZE_SMALL
3870
                                        );
3871
                                    }
3872
                                    break;
3873
                                default:
3874
                                    break;
3875
                            }
3876
3877
                            $result = '<div class="rounded_div_agenda" style="background-color:'.$bg_color.';">';
3878
3879
                            if ($show_content) {
3880
                                //Setting a personal event to green
3881
                                $icon = Display::div(
3882
                                    $icon,
3883
                                    ['style' => 'float:right']
3884
                                );
3885
3886
                                $link = $value['calendar_type'].'_'.$value['id'].'_'.$value['course_id'].'_'.$value['session_id'];
3887
3888
                                //Link to bubble
3889
                                $url = Display::url(
3890
                                    cut($value['title'], 40),
3891
                                    '#',
3892
                                    ['id' => $link, 'class' => 'opener']
3893
                                );
3894
                                $result .= $time.' '.$icon.' '.Display::div(
3895
                                        $url
3896
                                    );
3897
3898
                                //Hidden content
3899
                                $content = Display::div(
3900
                                    $icon.Display::tag(
3901
                                        'h2',
3902
                                        $value['course_name']
3903
                                    ).'<hr />'.Display::tag(
3904
                                        'h3',
3905
                                        $value['title']
3906
                                    ).$complete_time.'<hr />'.Security::remove_XSS(
3907
                                        $value['content']
3908
                                    )
3909
                                );
3910
3911
                                //Main div
3912
                                $result .= Display::div(
3913
                                    $content,
3914
                                    [
3915
                                        'id' => 'main_'.$link,
3916
                                        'class' => 'dialog',
3917
                                        'style' => 'display:none',
3918
                                    ]
3919
                                );
3920
                                $result .= '</div>';
3921
                                $html .= $result;
3922
                            } else {
3923
                                $html .= $result .= $icon.'</div>';
3924
                            }
3925
                        }
3926
                    }
3927
                    $html .= "</td>";
3928
                    $curday++;
3929
                } else {
3930
                    $html .= "<td></td>";
3931
                }
3932
            }
3933
            $html .= "</tr>";
3934
        }
3935
        $html .= "</table>";
3936
        echo $html;
3937
    }
3938
3939
    /**
3940
     * Get personal agenda items between two dates (=all events from all registered courses).
3941
     *
3942
     * @param int $user_id user ID of the user
3943
     * @param    string    Optional start date in datetime format (if no start date is given, uses today)
3944
     * @param    string    Optional end date in datetime format (if no date is given, uses one year from now)
3945
     *
3946
     * @return array array of events ordered by start date, in
3947
     *               [0]('datestart','dateend','title'),[1]('datestart','dateend','title','link','coursetitle') format,
3948
     *               where datestart and dateend are in yyyyMMddhhmmss format
3949
     *
3950
     * @deprecated use agenda events
3951
     */
3952
    public static function get_personal_agenda_items_between_dates(
3953
        $user_id,
3954
        $date_start = '',
3955
        $date_end = ''
3956
    ) {
3957
        $items = [];
3958
        if ($user_id != strval(intval($user_id))) {
3959
            return $items;
3960
        }
3961
        if (empty($date_start)) {
3962
            $date_start = date('Y-m-d H:i:s');
3963
        }
3964
        if (empty($date_end)) {
3965
            $date_end = date(
3966
                'Y-m-d H:i:s',
3967
                mktime(0, 0, 0, date("m"), date("d"), date("Y") + 1)
3968
            );
3969
        }
3970
        $expr = '/\d{4}-\d{2}-\d{2}\ \d{2}:\d{2}:\d{2}/';
3971
        if (!preg_match($expr, $date_start)) {
3972
            return $items;
3973
        }
3974
        if (!preg_match($expr, $date_end)) {
3975
            return $items;
3976
        }
3977
3978
        // get agenda-items for every course
3979
        $courses = api_get_user_courses($user_id, false);
3980
        foreach ($courses as $id => $course) {
3981
            $c = api_get_course_info_by_id($course['real_id']);
3982
            //databases of the courses
3983
            $t_a = Database::get_course_table(TABLE_AGENDA, $course['db']);
3984
            $t_ip = Database::get_course_table(
3985
                TABLE_ITEM_PROPERTY,
3986
                $course['db']
3987
            );
3988
            // get the groups to which the user belong
3989
            $group_memberships = GroupManager:: get_group_ids(
3990
                $course['db'],
3991
                $user_id
3992
            );
3993
            // if the user is administrator of that course we show all the agenda items
3994
            if ($course['status'] == '1') {
3995
                //echo "course admin";
3996
                $sqlquery = "SELECT ".
3997
                    " DISTINCT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref ".
3998
                    " FROM ".$t_a." agenda, ".
3999
                    $t_ip." ip ".
4000
                    " WHERE agenda.id = ip.ref ".
4001
                    " AND agenda.start_date>='$date_start' ".
4002
                    " AND agenda.end_date<='$date_end' ".
4003
                    " AND ip.tool='".TOOL_CALENDAR_EVENT."' ".
4004
                    " AND ip.visibility='1' ".
4005
                    " GROUP BY agenda.id ".
4006
                    " ORDER BY start_date ";
4007
            } else {
4008
                // if the user is not an administrator of that course, then...
4009
                if (is_array($group_memberships) && count(
4010
                        $group_memberships
4011
                    ) > 0
4012
                ) {
4013
                    $sqlquery = "SELECT ".
4014
                        "DISTINCT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref ".
4015
                        " FROM ".$t_a." agenda, ".
4016
                        $t_ip." ip ".
4017
                        " WHERE agenda.id = ip.ref ".
4018
                        " AND agenda.start_date>='$date_start' ".
4019
                        " AND agenda.end_date<='$date_end' ".
4020
                        " AND ip.tool='".TOOL_CALENDAR_EVENT."' ".
4021
                        " AND	( ip.to_user_id='".$user_id."' OR (ip.to_group_id IS NULL OR ip.to_group_id IN (0, ".implode(
4022
                            ", ",
4023
                            $group_memberships
4024
                        ).")) ) ".
4025
                        " AND ip.visibility='1' ".
4026
                        " ORDER BY start_date ";
4027
                } else {
4028
                    $sqlquery = "SELECT ".
4029
                        "DISTINCT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref ".
4030
                        " FROM ".$t_a." agenda, ".
4031
                        $t_ip." ip ".
4032
                        " WHERE agenda.id = ip.ref ".
4033
                        " AND agenda.start_date>='$date_start' ".
4034
                        " AND agenda.end_date<='$date_end' ".
4035
                        " AND ip.tool='".TOOL_CALENDAR_EVENT."' ".
4036
                        " AND ( ip.to_user_id='".$user_id."' OR ip.to_group_id='0' OR ip.to_group_id IS NULL) ".
4037
                        " AND ip.visibility='1' ".
4038
                        " ORDER BY start_date ";
4039
                }
4040
            }
4041
4042
            $result = Database::query($sqlquery);
4043
            while ($item = Database::fetch_array($result)) {
4044
                $agendaday = date("j", strtotime($item['start_date']));
4045
                $month = date("n", strtotime($item['start_date']));
4046
                $year = date("Y", strtotime($item['start_date']));
4047
                $URL = api_get_path(
4048
                        WEB_PATH
4049
                    )."main/calendar/agenda.php?cidReq=".urlencode(
4050
                        $course["code"]
4051
                    )."&day=$agendaday&month=$month&year=$year#$agendaday";
4052
                list($year, $month, $day, $hour, $min, $sec) = explode(
4053
                    '[-: ]',
4054
                    $item['start_date']
4055
                );
4056
                $start_date = $year.$month.$day.$hour.$min;
4057
                list($year, $month, $day, $hour, $min, $sec) = explode(
4058
                    '[-: ]',
4059
                    $item['end_date']
4060
                );
4061
                $end_date = $year.$month.$day.$hour.$min;
4062
4063
                $items[] = [
4064
                    'datestart' => $start_date,
4065
                    'dateend' => $end_date,
4066
                    'title' => $item['title'],
4067
                    'link' => $URL,
4068
                    'coursetitle' => $c['name'],
4069
                ];
4070
            }
4071
        }
4072
4073
        return $items;
4074
    }
4075
4076
    /**
4077
     * This function calculates the startdate of the week (monday)
4078
     * and the enddate of the week (sunday)
4079
     * and returns it as an array.
4080
     */
4081
    public static function calculate_start_end_of_week($week_number, $year)
4082
    {
4083
        // determine the start and end date
4084
        // step 1: we calculate a timestamp for a day in this week
4085
        $random_day_in_week = mktime(
4086
                0,
4087
                0,
4088
                0,
4089
                1,
4090
                1,
4091
                $year
4092
            ) + ($week_number) * (7 * 24 * 60 * 60); // we calculate a random day in this week
4093
        // step 2: we which day this is (0=sunday, 1=monday, ...)
4094
        $number_day_in_week = date('w', $random_day_in_week);
4095
        // step 3: we calculate the timestamp of the monday of the week we are in
4096
        $start_timestamp = $random_day_in_week - (($number_day_in_week - 1) * 24 * 60 * 60);
4097
        // step 4: we calculate the timestamp of the sunday of the week we are in
4098
        $end_timestamp = $random_day_in_week + ((7 - $number_day_in_week + 1) * 24 * 60 * 60) - 3600;
4099
        // step 5: calculating the start_day, end_day, start_month, end_month, start_year, end_year
4100
        $start_day = date('j', $start_timestamp);
4101
        $start_month = date('n', $start_timestamp);
4102
        $start_year = date('Y', $start_timestamp);
4103
        $end_day = date('j', $end_timestamp);
4104
        $end_month = date('n', $end_timestamp);
4105
        $end_year = date('Y', $end_timestamp);
4106
        $start_end_array['start']['day'] = $start_day;
4107
        $start_end_array['start']['month'] = $start_month;
4108
        $start_end_array['start']['year'] = $start_year;
4109
        $start_end_array['end']['day'] = $end_day;
4110
        $start_end_array['end']['month'] = $end_month;
4111
        $start_end_array['end']['year'] = $end_year;
4112
4113
        return $start_end_array;
4114
    }
4115
4116
    /**
4117
     * @return bool
4118
     */
4119
    public function getIsAllowedToEdit()
4120
    {
4121
        return $this->isAllowedToEdit;
4122
    }
4123
4124
    /**
4125
     * @param bool $isAllowedToEdit
4126
     */
4127
    public function setIsAllowedToEdit($isAllowedToEdit)
4128
    {
4129
        $this->isAllowedToEdit = $isAllowedToEdit;
4130
    }
4131
4132
    /**
4133
     * Format needed for the Fullcalendar js lib.
4134
     *
4135
     * @param string $utcTime
4136
     *
4137
     * @return bool|string
4138
     */
4139
    public function formatEventDate($utcTime)
4140
    {
4141
        $utcTimeZone = new DateTimeZone('UTC');
4142
        $platformTimeZone = new DateTimeZone(api_get_timezone());
4143
4144
        $eventDate = new DateTime($utcTime, $utcTimeZone);
4145
        $eventDate->setTimezone($platformTimeZone);
4146
4147
        return $eventDate->format(DateTime::ISO8601);
4148
    }
4149
}
4150