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

Agenda::addEvent()   F

Complexity

Conditions 23
Paths 618

Size

Total Lines 217
Code Lines 147

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 147
c 1
b 0
f 1
dl 0
loc 217
rs 0.4244
cc 23
nc 618
nop 14

How to fix   Long Method    Complexity    Many Parameters   

Long Method

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

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

Commonly applied refactorings include:

Many Parameters

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

There are several approaches to avoid long parameter lists:

1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
use Chamilo\CoreBundle\Entity\AgendaEventInvitation;
6
use Chamilo\CoreBundle\Entity\AgendaEventInvitee;
7
use Chamilo\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