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

Agenda::addEvent()   F

Complexity

Conditions 25
Paths 1236

Size

Total Lines 224
Code Lines 150

Duplication

Lines 0
Ratio 0 %

Importance

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

How to fix   Long Method    Complexity    Many Parameters   

Long Method

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

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

Commonly applied refactorings include:

Many Parameters

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

There are several approaches to avoid long parameter lists:

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

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

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

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

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