Passed
Push — 1.11.x ( c15911...57c478 )
by Angel Fernando Quiroz
09:03
created

Agenda::loadSessionsAsEvents()   B

Complexity

Conditions 8

Size

Total Lines 30
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

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

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

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

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

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