Passed
Push — preprodparkur ( f4828c...eec125 )
by Angel Fernando Quiroz
13:34
created

Agenda::editEvent()   F

Complexity

Conditions 49
Paths 8248

Size

Total Lines 333
Code Lines 205

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 205
c 1
b 0
f 1
dl 0
loc 333
rs 0
cc 49
nc 8248
nop 16

How to fix   Long Method    Complexity    Many Parameters   

Long Method

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

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

Commonly applied refactorings include:

Many Parameters

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

There are several approaches to avoid long parameter lists:

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