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

Agenda::editEvent()   F

Complexity

Conditions 54
Paths 8344

Size

Total Lines 365
Code Lines 218

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 218
dl 0
loc 365
rs 0
c 0
b 0
f 0
cc 54
nc 8344
nop 21

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