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

Agenda::get_event()   C

Complexity

Conditions 14
Paths 17

Size

Total Lines 98
Code Lines 70

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 70
c 0
b 0
f 0
dl 0
loc 98
rs 5.6678
cc 14
nc 17
nop 1

How to fix   Long Method    Complexity   

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:

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