Passed
Push — preprodparkur ( 6dd898...74c0c7 )
by Angel Fernando Quiroz
09:38
created

Agenda::getTypes()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

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