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

Agenda::display_mymonthcalendar()   F

Complexity

Conditions 30

Size

Total Lines 249
Code Lines 171

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 30
eloc 171
nop 7
dl 0
loc 249
rs 3.3333
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

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