Passed
Pull Request — 1.11.x (#4109)
by Angel Fernando Quiroz
13:44
created

Agenda::resizeEvent()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 31
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

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