Passed
Pull Request — 1.11.x (#4204)
by Angel Fernando Quiroz
09:04
created

Agenda::addEvent()   F

Complexity

Conditions 26
Paths 1248

Size

Total Lines 231
Code Lines 153

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 153
c 1
b 0
f 1
dl 0
loc 231
rs 0
cc 26
nop 17
nc 1248

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