Passed
Push — preprodparkur ( 99feeb...8b68ba )
by Angel Fernando Quiroz
09:25
created

Agenda::editReminders()   A

Complexity

Conditions 6

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

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