Passed
Pull Request — 1.11.x (#4160)
by Angel Fernando Quiroz
16:08 queued 03:42
created

Agenda::editEvent()   F

Complexity

Conditions 50
Paths 8248

Size

Total Lines 341
Code Lines 207

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 1
Metric Value
eloc 207
c 4
b 0
f 1
dl 0
loc 341
rs 0
cc 50
nc 8248
nop 17

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