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

Agenda::addEvent()   F

Complexity

Conditions 25
Paths 1236

Size

Total Lines 224
Code Lines 150

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 150
c 1
b 0
f 1
dl 0
loc 224
rs 0
cc 25
nop 15
nc 1236

How to fix   Long Method    Complexity    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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

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

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

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

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