Passed
Pull Request — 1.11.x (#4088)
by Angel Fernando Quiroz
12:51 queued 17s
created

Agenda::getPersonalEvents()   C

Complexity

Conditions 16
Paths 64

Size

Total Lines 99
Code Lines 64

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 64
c 0
b 0
f 0
dl 0
loc 99
rs 5.5666
cc 16
nc 64
nop 2

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

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