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