Passed
Push — preprodparkur ( fef38a...b36c1c )
by Angel Fernando Quiroz
11:45
created

Agenda::editEvent()   F

Complexity

Conditions 50
Paths 8248

Size

Total Lines 341
Code Lines 207

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 1
Metric Value
eloc 207
c 4
b 0
f 1
dl 0
loc 341
rs 0
cc 50
nc 8248
nop 17

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
                    return false;
921
                }
922
923
                $attributes = [
924
                    'title' => $title,
925
                    'start_date' => $start,
926
                    'end_date' => $end,
927
                    'all_day' => $allDay,
928
                    'comment' => $comment,
929
                ];
930
931
                if ($updateContent) {
932
                    $attributes['content'] = $content;
933
                }
934
935
                if (!empty($color)) {
936
                    $attributes['color'] = $color;
937
                }
938
939
                Database::update(
940
                    $this->tbl_course_agenda,
941
                    $attributes,
942
                    [
943
                        'id = ? AND c_id = ? AND session_id = ? ' => [
944
                            $id,
945
                            $courseId,
946
                            $this->sessionId,
947
                        ],
948
                    ]
949
                );
950
951
                if (!empty($usersToSend)) {
952
                    $sendTo = $this->parseSendToArray($usersToSend);
953
954
                    $usersToDelete = array_diff(
955
                        $eventInfo['send_to']['users'],
956
                        $sendTo['users']
957
                    );
958
                    $usersToAdd = array_diff(
959
                        $sendTo['users'],
960
                        $eventInfo['send_to']['users']
961
                    );
962
963
                    $groupsToDelete = array_diff(
964
                        $eventInfo['send_to']['groups'],
965
                        $sendTo['groups']
966
                    );
967
                    $groupToAdd = array_diff(
968
                        $sendTo['groups'],
969
                        $eventInfo['send_to']['groups']
970
                    );
971
972
                    if ($sendTo['everyone']) {
973
                        // Delete all from group
974
                        if (isset($eventInfo['send_to']['groups']) &&
975
                            !empty($eventInfo['send_to']['groups'])
976
                        ) {
977
                            foreach ($eventInfo['send_to']['groups'] as $group) {
978
                                $groupIidItem = 0;
979
                                if ($group) {
980
                                    $groupInfoItem = GroupManager::get_group_properties(
981
                                        $group
982
                                    );
983
                                    if ($groupInfoItem) {
984
                                        $groupIidItem = $groupInfoItem['iid'];
985
                                    }
986
                                }
987
988
                                api_item_property_delete(
989
                                    $this->course,
990
                                    TOOL_CALENDAR_EVENT,
991
                                    $id,
992
                                    0,
993
                                    $groupIidItem,
994
                                    $this->sessionId
995
                                );
996
                            }
997
                        }
998
999
                        // Storing the selected users.
1000
                        if (isset($eventInfo['send_to']['users']) &&
1001
                            !empty($eventInfo['send_to']['users'])
1002
                        ) {
1003
                            foreach ($eventInfo['send_to']['users'] as $userId) {
1004
                                api_item_property_delete(
1005
                                    $this->course,
1006
                                    TOOL_CALENDAR_EVENT,
1007
                                    $id,
1008
                                    $userId,
1009
                                    $groupIid,
1010
                                    $this->sessionId
1011
                                );
1012
                            }
1013
                        }
1014
1015
                        // Add to everyone only.
1016
                        api_item_property_update(
1017
                            $this->course,
1018
                            TOOL_CALENDAR_EVENT,
1019
                            $id,
1020
                            'visible',
1021
                            $authorId,
1022
                            $groupInfo,
1023
                            null,
1024
                            $start,
1025
                            $end,
1026
                            $this->sessionId
1027
                        );
1028
                    } else {
1029
                        // Delete "everyone".
1030
                        api_item_property_delete(
1031
                            $this->course,
1032
                            TOOL_CALENDAR_EVENT,
1033
                            $id,
1034
                            0,
1035
                            0,
1036
                            $this->sessionId
1037
                        );
1038
1039
                        // Add groups
1040
                        if (!empty($groupToAdd)) {
1041
                            foreach ($groupToAdd as $group) {
1042
                                $groupInfoItem = [];
1043
                                if ($group) {
1044
                                    $groupInfoItem = GroupManager::get_group_properties(
1045
                                        $group
1046
                                    );
1047
                                }
1048
1049
                                api_item_property_update(
1050
                                    $this->course,
1051
                                    TOOL_CALENDAR_EVENT,
1052
                                    $id,
1053
                                    'visible',
1054
                                    $authorId,
1055
                                    $groupInfoItem,
1056
                                    0,
1057
                                    $start,
1058
                                    $end,
1059
                                    $this->sessionId
1060
                                );
1061
                            }
1062
                        }
1063
1064
                        // Delete groups.
1065
                        if (!empty($groupsToDelete)) {
1066
                            foreach ($groupsToDelete as $group) {
1067
                                $groupIidItem = 0;
1068
                                $groupInfoItem = [];
1069
                                if ($group) {
1070
                                    $groupInfoItem = GroupManager::get_group_properties(
1071
                                        $group
1072
                                    );
1073
                                    if ($groupInfoItem) {
1074
                                        $groupIidItem = $groupInfoItem['iid'];
1075
                                    }
1076
                                }
1077
1078
                                api_item_property_delete(
1079
                                    $this->course,
1080
                                    TOOL_CALENDAR_EVENT,
1081
                                    $id,
1082
                                    0,
1083
                                    $groupIidItem,
1084
                                    $this->sessionId
1085
                                );
1086
                            }
1087
                        }
1088
1089
                        // Add users.
1090
                        if (!empty($usersToAdd)) {
1091
                            foreach ($usersToAdd as $userId) {
1092
                                api_item_property_update(
1093
                                    $this->course,
1094
                                    TOOL_CALENDAR_EVENT,
1095
                                    $id,
1096
                                    'visible',
1097
                                    $authorId,
1098
                                    $groupInfo,
1099
                                    $userId,
1100
                                    $start,
1101
                                    $end,
1102
                                    $this->sessionId
1103
                                );
1104
                            }
1105
                        }
1106
1107
                        // Delete users.
1108
                        if (!empty($usersToDelete)) {
1109
                            foreach ($usersToDelete as $userId) {
1110
                                api_item_property_delete(
1111
                                    $this->course,
1112
                                    TOOL_CALENDAR_EVENT,
1113
                                    $id,
1114
                                    $userId,
1115
                                    $groupInfo,
1116
                                    $this->sessionId
1117
                                );
1118
                            }
1119
                        }
1120
                    }
1121
                }
1122
1123
                // Add announcement.
1124
                if (isset($addAnnouncement) && !empty($addAnnouncement)) {
1125
                    $this->storeAgendaEventAsAnnouncement(
1126
                        $id,
1127
                        $usersToSend
1128
                    );
1129
                }
1130
1131
                // Add attachment.
1132
                if (isset($attachmentArray) && !empty($attachmentArray)) {
1133
                    $counter = 0;
1134
                    foreach ($attachmentArray as $attachmentItem) {
1135
                        if (empty($attachmentItems['id'])) {
1136
                            continue;
1137
                        }
1138
1139
                        $this->updateAttachment(
1140
                            $attachmentItem['id'],
1141
                            $id,
1142
                            $attachmentItem,
1143
                            $attachmentCommentList[$counter],
1144
                            $this->course
1145
                        );
1146
                        $counter++;
1147
                    }
1148
                }
1149
                break;
1150
            case 'admin':
1151
            case 'platform':
1152
                if (api_is_platform_admin()) {
1153
                    $attributes = [
1154
                        'title' => $title,
1155
                        'start_date' => $start,
1156
                        'end_date' => $end,
1157
                        'all_day' => $allDay,
1158
                    ];
1159
1160
                    if ($updateContent) {
1161
                        $attributes['content'] = $content;
1162
                    }
1163
                    Database::update(
1164
                        $this->tbl_global_agenda,
1165
                        $attributes,
1166
                        ['id = ?' => $id]
1167
                    );
1168
                }
1169
                break;
1170
        }
1171
1172
        $this->editReminders($id, $remindersList);
1173
1174
        return true;
1175
    }
1176
1177
    /**
1178
     * @param int  $id
1179
     * @param bool $deleteAllItemsFromSerie
1180
     *
1181
     * @throws \Doctrine\ORM\ORMException
1182
     * @throws \Doctrine\ORM\OptimisticLockException
1183
     */
1184
    public function deleteEvent($id, $deleteAllItemsFromSerie = false)
1185
    {
1186
        $em = Database::getManager();
1187
1188
        switch ($this->type) {
1189
            case 'personal':
1190
                $eventInfo = $this->get_event($id);
1191
                if ($eventInfo['user'] == api_get_user_id()) {
1192
                    Database::delete(
1193
                        $this->tbl_personal_agenda,
1194
                        ['id = ?' => $id]
1195
                    );
1196
                } elseif (api_get_configuration_value('agenda_collective_invitations')) {
1197
                    $currentUser = api_get_user_entity(api_get_user_id());
1198
1199
                    $eventRepo = $em->getRepository('ChamiloCoreBundle:PersonalAgenda');
1200
                    $event = $eventRepo->findOneByIdAndInvitee($id, $currentUser);
1201
                    $invitation = $event ? $event->getInvitation() : null;
1202
1203
                    if ($invitation) {
1204
                        $invitation->removeInviteeUser($currentUser);
1205
1206
                        $em->persist($invitation);
1207
                        $em->flush();
1208
                    }
1209
                }
1210
                break;
1211
            case 'course':
1212
                $courseId = api_get_course_int_id();
1213
                $isAllowToEdit = $this->getIsAllowedToEdit();
1214
1215
                if (!empty($courseId) && $isAllowToEdit) {
1216
                    $eventInfo = $this->get_event($id);
1217
                    if ($deleteAllItemsFromSerie) {
1218
                        /* This is one of the children.
1219
                           Getting siblings and delete 'Em all + the father! */
1220
                        if (isset($eventInfo['parent_event_id']) && !empty($eventInfo['parent_event_id'])) {
1221
                            // Removing items.
1222
                            $events = $this->getAllRepeatEvents($eventInfo['parent_event_id']);
1223
                            if (!empty($events)) {
1224
                                foreach ($events as $event) {
1225
                                    $this->deleteEvent($event['id']);
1226
                                }
1227
                            }
1228
                            // Removing parent.
1229
                            $this->deleteEvent($eventInfo['parent_event_id']);
1230
                        } else {
1231
                            // This is the father looking for the children.
1232
                            $events = $this->getAllRepeatEvents($id);
1233
                            if (!empty($events)) {
1234
                                foreach ($events as $event) {
1235
                                    $this->deleteEvent($event['id']);
1236
                                }
1237
                            }
1238
                        }
1239
                    }
1240
1241
                    // Removing from events.
1242
                    Database::delete(
1243
                        $this->tbl_course_agenda,
1244
                        ['id = ? AND c_id = ?' => [$id, $courseId]]
1245
                    );
1246
1247
                    api_item_property_update(
1248
                        $this->course,
1249
                        TOOL_CALENDAR_EVENT,
1250
                        $id,
1251
                        'delete',
1252
                        api_get_user_id()
1253
                    );
1254
1255
                    // Removing from series.
1256
                    Database::delete(
1257
                        $this->table_repeat,
1258
                        [
1259
                            'cal_id = ? AND c_id = ?' => [
1260
                                $id,
1261
                                $courseId,
1262
                            ],
1263
                        ]
1264
                    );
1265
1266
                    if (isset($eventInfo['attachment']) && !empty($eventInfo['attachment'])) {
1267
                        foreach ($eventInfo['attachment'] as $attachment) {
1268
                            self::deleteAttachmentFile(
1269
                                $attachment['id'],
1270
                                $this->course
1271
                            );
1272
                        }
1273
                    }
1274
                }
1275
                break;
1276
            case 'admin':
1277
                if (api_is_platform_admin()) {
1278
                    Database::delete(
1279
                        $this->tbl_global_agenda,
1280
                        ['id = ?' => $id]
1281
                    );
1282
                }
1283
                break;
1284
        }
1285
    }
1286
1287
    /**
1288
     * Get agenda events.
1289
     *
1290
     * @param int    $start
1291
     * @param int    $end
1292
     * @param int    $courseId
1293
     * @param int    $groupId
1294
     * @param int    $user_id
1295
     * @param string $format
1296
     *
1297
     * @return array|string
1298
     */
1299
    public function getEvents(
1300
        $start,
1301
        $end,
1302
        $courseId = null,
1303
        $groupId = null,
1304
        $user_id = 0,
1305
        $format = 'json'
1306
    ) {
1307
        switch ($this->type) {
1308
            case 'admin':
1309
                $this->getPlatformEvents($start, $end);
1310
                break;
1311
            case 'course':
1312
                $courseInfo = api_get_course_info_by_id($courseId);
1313
1314
                // Session coach can see all events inside a session.
1315
                if (api_is_coach()) {
1316
                    // Own course
1317
                    $this->getCourseEvents(
1318
                        $start,
1319
                        $end,
1320
                        $courseInfo,
1321
                        $groupId,
1322
                        $this->sessionId,
1323
                        $user_id
1324
                    );
1325
1326
                    // Others
1327
                    $this->getSessionEvents(
1328
                        $start,
1329
                        $end,
1330
                        $this->sessionId,
1331
                        $user_id,
1332
                        $this->eventOtherSessionColor
1333
                    );
1334
                } else {
1335
                    $this->getCourseEvents(
1336
                        $start,
1337
                        $end,
1338
                        $courseInfo,
1339
                        $groupId,
1340
                        $this->sessionId,
1341
                        $user_id
1342
                    );
1343
                }
1344
                break;
1345
            case 'personal':
1346
            default:
1347
                $sessionFilterActive = false;
1348
                if (!empty($this->sessionId)) {
1349
                    $sessionFilterActive = true;
1350
                }
1351
1352
                if ($sessionFilterActive == false) {
1353
                    // Getting personal events
1354
                    $this->getPersonalEvents($start, $end);
1355
1356
                    // Getting platform/admin events
1357
                    $this->getPlatformEvents($start, $end);
1358
                }
1359
1360
                $ignoreVisibility = api_get_configuration_value('personal_agenda_show_all_session_events');
1361
1362
                $session_list = [];
1363
                // Getting course events
1364
                $my_course_list = [];
1365
                if (!api_is_anonymous()) {
1366
                    $session_list = SessionManager::get_sessions_by_user(
1367
                        api_get_user_id(),
1368
                        $ignoreVisibility
1369
                    );
1370
                    $my_course_list = CourseManager::get_courses_list_by_user_id(
1371
                        api_get_user_id(),
1372
                        false
1373
                    );
1374
                }
1375
1376
                if (api_is_drh()) {
1377
                    if (api_drh_can_access_all_session_content()) {
1378
                        $session_list = [];
1379
                        $sessionList = SessionManager::get_sessions_followed_by_drh(
1380
                            api_get_user_id(),
1381
                            null,
1382
                            null,
1383
                            null,
1384
                            true,
1385
                            false
1386
                        );
1387
1388
                        if (!empty($sessionList)) {
1389
                            foreach ($sessionList as $sessionItem) {
1390
                                $sessionId = $sessionItem['id'];
1391
                                $courses = SessionManager::get_course_list_by_session_id($sessionId);
1392
                                $sessionInfo = [
1393
                                    'session_id' => $sessionId,
1394
                                    'courses' => $courses,
1395
                                ];
1396
                                $session_list[] = $sessionInfo;
1397
                            }
1398
                        }
1399
                    }
1400
                }
1401
1402
                if (!empty($session_list)) {
1403
                    foreach ($session_list as $session_item) {
1404
                        if ($sessionFilterActive) {
1405
                            if ($this->sessionId != $session_item['session_id']) {
1406
                                continue;
1407
                            }
1408
                        }
1409
1410
                        $my_courses = $session_item['courses'];
1411
                        $my_session_id = $session_item['session_id'];
1412
1413
                        if (!empty($my_courses)) {
1414
                            foreach ($my_courses as $course_item) {
1415
                                $courseInfo = api_get_course_info_by_id(
1416
                                    $course_item['real_id']
1417
                                );
1418
                                $this->getCourseEvents(
1419
                                    $start,
1420
                                    $end,
1421
                                    $courseInfo,
1422
                                    0,
1423
                                    $my_session_id
1424
                                );
1425
                            }
1426
                        }
1427
                    }
1428
                }
1429
1430
                if (!empty($my_course_list) && $sessionFilterActive == false) {
1431
                    foreach ($my_course_list as $courseInfoItem) {
1432
                        $courseInfo = api_get_course_info_by_id(
1433
                            $courseInfoItem['real_id']
1434
                        );
1435
                        if (isset($courseId) && !empty($courseId)) {
1436
                            if ($courseInfo['real_id'] == $courseId) {
1437
                                $this->getCourseEvents(
1438
                                    $start,
1439
                                    $end,
1440
                                    $courseInfo,
1441
                                    0,
1442
                                    0,
1443
                                    $user_id
1444
                                );
1445
                            }
1446
                        } else {
1447
                            $this->getCourseEvents(
1448
                                $start,
1449
                                $end,
1450
                                $courseInfo,
1451
                                0,
1452
                                0,
1453
                                $user_id
1454
                            );
1455
                        }
1456
                    }
1457
                }
1458
1459
                $this->loadSessionsAsEvents($start, $end);
1460
1461
                break;
1462
        }
1463
1464
        if (api_get_configuration_value('agenda_reminders')) {
1465
            $this->events = array_map(
1466
                function (array $eventInfo) {
1467
                    $id = str_replace(['personal_', 'course_', 'session_'], '', $eventInfo['id']);
1468
1469
                    $eventInfo['reminders'] = $this->parseEventReminders(
1470
                        $this->getEventReminders(
1471
                            $id,
1472
                            'session' === $eventInfo['type'] ? 'course' : $eventInfo['type']
1473
                        )
1474
                    );
1475
1476
                    return $eventInfo;
1477
                },
1478
                $this->events
1479
            );
1480
        }
1481
1482
        $this->cleanEvents();
1483
1484
        switch ($format) {
1485
            case 'json':
1486
                if (empty($this->events)) {
1487
                    return '[]';
1488
                }
1489
1490
                return json_encode($this->events);
1491
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

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

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

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

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