Passed
Push — preprodparkur ( eec125...4fd884 )
by
unknown
11:05 queued 56s
created

Agenda::addEvent()   F

Complexity

Conditions 23
Paths 618

Size

Total Lines 217
Code Lines 147

Duplication

Lines 0
Ratio 0 %

Importance

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

How to fix   Long Method    Complexity    Many Parameters   

Long Method

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

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

Commonly applied refactorings include:

Many Parameters

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

There are several approaches to avoid long parameter lists:

1
<?php
2
/* 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
	$agendaCollectiveInvitations = api_get_configuration_value('agenda_collective_invitations');
1616
        if ($agendaCollectiveInvitations) {
1617
            $inviteeRepo = $em->getRepository('ChamiloCoreBundle:AgendaEventInvitee');
1618
        }
1619
        if ($start !== 0) {
1620
            $startDate = api_get_utc_datetime($start, true, true);
1621
            $startCondition = "AND date >= '".$startDate->format('Y-m-d H:i:s')."'";
1622
        }
1623
        if ($start !== 0) {
1624
            $endDate = api_get_utc_datetime($end, false, true);
1625
            $endCondition = "AND (enddate <= '".$endDate->format('Y-m-d H:i:s')."' OR enddate IS NULL)";
1626
        }
1627
        $user_id = api_get_user_id();
1628
1629
        $sql = "SELECT * FROM ".$this->tbl_personal_agenda."
1630
                WHERE user = $user_id $startCondition $endCondition";
1631
1632
        $result = Database::query($sql);
1633
        $my_events = [];
1634
        if (Database::num_rows($result)) {
1635
            while ($row = Database::fetch_array($result, 'ASSOC')) {
1636
                $event = [];
1637
                $event['id'] = 'personal_'.$row['id'];
1638
                $event['title'] = $row['title'];
1639
                $event['className'] = 'personal';
1640
                $event['borderColor'] = $event['backgroundColor'] = $this->event_personal_color;
1641
                $event['editable'] = true;
1642
                $event['sent_to'] = get_lang('Me');
1643
                $event['type'] = 'personal';
1644
1645
                if (!empty($row['date'])) {
1646
                    $event['start'] = $this->formatEventDate($row['date']);
1647
                    $event['start_date_localtime'] = api_get_local_time($row['date']);
1648
                }
1649
1650
                if (!empty($row['enddate'])) {
1651
                    $event['end'] = $this->formatEventDate($row['enddate']);
1652
                    $event['end_date_localtime'] = api_get_local_time($row['enddate']);
1653
                }
1654
1655
                $event['description'] = $row['text'];
1656
                $event['allDay'] = isset($row['all_day']) && $row['all_day'] == 1 ? $row['all_day'] : 0;
1657
                $event['parent_event_id'] = 0;
1658
                $event['has_children'] = 0;
1659
1660
                if ($agendaCollectiveInvitations) {
1661
                    $event['collective'] = (bool) $row['collective'];
1662
                    $event['invitees'] = [];
1663
1664
                    $invitees = $inviteeRepo->findBy(['invitation' => $row['agenda_event_invitation_id']]);
1665
1666
                    foreach ($invitees as $invitee) {
1667
                        $inviteeUser = $invitee->getUser();
1668
1669
                        $event['invitees'][] = [
1670
                            'id' => $inviteeUser->getId(),
1671
                            'name' => $inviteeUser->getCompleteNameWithUsername(),
1672
                        ];
1673
                    }
1674
                }
1675
1676
                $my_events[] = $event;
1677
                $this->events[] = $event;
1678
            }
1679
        }
1680
1681
        if ($agendaCollectiveInvitations) {
1682
            $this->loadEventsAsInvitee(
1683
                api_get_user_entity($user_id),
1684
                $startDate,
1685
                $endDate
1686
            );
1687
        }
1688
1689
        // Add plugin personal events
1690
1691
        $this->plugin = new AppPlugin();
1692
        $plugins = $this->plugin->getInstalledPluginListObject();
1693
        /** @var Plugin $plugin */
1694
        foreach ($plugins as $plugin) {
1695
            if ($plugin->hasPersonalEvents && method_exists($plugin, 'getPersonalEvents')) {
1696
                $pluginEvents = $plugin->getPersonalEvents($this, $start, $end);
1697
1698
                if (!empty($pluginEvents)) {
1699
                    $this->events = array_merge($this->events, $pluginEvents);
1700
                }
1701
            }
1702
        }
1703
1704
        return $my_events;
1705
    }
1706
1707
    /**
1708
     * Get user/group list per event.
1709
     *
1710
     * @param int $eventId
1711
     * @param int $courseId
1712
     * @param int $sessionId
1713
     * @paraù int $sessionId
1714
     *
1715
     * @return array
1716
     */
1717
    public function getUsersAndGroupSubscribedToEvent(
1718
        $eventId,
1719
        $courseId,
1720
        $sessionId
1721
    ) {
1722
        $eventId = (int) $eventId;
1723
        $courseId = (int) $courseId;
1724
        $sessionId = (int) $sessionId;
1725
1726
        $sessionCondition = "ip.session_id = $sessionId";
1727
        if (empty($sessionId)) {
1728
            $sessionCondition = " (ip.session_id = 0 OR ip.session_id IS NULL) ";
1729
        }
1730
1731
        $tlb_course_agenda = Database::get_course_table(TABLE_AGENDA);
1732
        $tbl_property = Database::get_course_table(TABLE_ITEM_PROPERTY);
1733
1734
        // Get sent_tos
1735
        $sql = "SELECT DISTINCT to_user_id, to_group_id
1736
                FROM $tbl_property ip
1737
                INNER JOIN $tlb_course_agenda agenda
1738
                ON (
1739
                  ip.ref = agenda.id AND
1740
                  ip.c_id = agenda.c_id AND
1741
                  ip.tool = '".TOOL_CALENDAR_EVENT."'
1742
                )
1743
                WHERE
1744
                    ref = $eventId AND
1745
                    ip.visibility = '1' AND
1746
                    ip.c_id = $courseId AND
1747
                    $sessionCondition
1748
                ";
1749
1750
        $result = Database::query($sql);
1751
        $users = [];
1752
        $groups = [];
1753
        $everyone = false;
1754
1755
        while ($row = Database::fetch_array($result, 'ASSOC')) {
1756
            if (!empty($row['to_group_id'])) {
1757
                $groups[] = $row['to_group_id'];
1758
            }
1759
            if (!empty($row['to_user_id'])) {
1760
                $users[] = $row['to_user_id'];
1761
            }
1762
1763
            if (empty($groups) && empty($users)) {
1764
                if ($row['to_group_id'] == 0) {
1765
                    $everyone = true;
1766
                }
1767
            }
1768
        }
1769
1770
        return [
1771
            'everyone' => $everyone,
1772
            'users' => $users,
1773
            'groups' => $groups,
1774
        ];
1775
    }
1776
1777
    /**
1778
     * @param int    $start
1779
     * @param int    $end
1780
     * @param int    $sessionId
1781
     * @param int    $userId
1782
     * @param string $color
1783
     *
1784
     * @return array
1785
     */
1786
    public function getSessionEvents(
1787
        $start,
1788
        $end,
1789
        $sessionId = 0,
1790
        $userId = 0,
1791
        $color = ''
1792
    ) {
1793
        $courses = SessionManager::get_course_list_by_session_id($sessionId);
1794
1795
        if (!empty($courses)) {
1796
            foreach ($courses as $course) {
1797
                $this->getCourseEvents(
1798
                    $start,
1799
                    $end,
1800
                    $course,
1801
                    0,
1802
                    $sessionId,
1803
                    0,
1804
                    $color
1805
                );
1806
            }
1807
        }
1808
    }
1809
1810
    /**
1811
     * @param int    $start
1812
     * @param int    $end
1813
     * @param array  $courseInfo
1814
     * @param int    $groupId
1815
     * @param int    $sessionId
1816
     * @param int    $user_id
1817
     * @param string $color
1818
     *
1819
     * @return array
1820
     */
1821
    public function getCourseEvents(
1822
        $start,
1823
        $end,
1824
        $courseInfo,
1825
        $groupId = 0,
1826
        $sessionId = 0,
1827
        $user_id = 0,
1828
        $color = ''
1829
    ) {
1830
        $start = isset($start) && !empty($start) ? api_get_utc_datetime(intval($start)) : null;
1831
        $end = isset($end) && !empty($end) ? api_get_utc_datetime(intval($end)) : null;
1832
1833
        if (empty($courseInfo)) {
1834
            return [];
1835
        }
1836
        $courseId = $courseInfo['real_id'];
1837
1838
        if (empty($courseId)) {
1839
            return [];
1840
        }
1841
1842
        $sessionId = (int) $sessionId;
1843
        $user_id = (int) $user_id;
1844
1845
        $groupList = GroupManager::get_group_list(
1846
            null,
1847
            $courseInfo,
1848
            null,
1849
            $sessionId
1850
        );
1851
1852
        $groupNameList = [];
1853
        if (!empty($groupList)) {
1854
            foreach ($groupList as $group) {
1855
                $groupNameList[$group['iid']] = $group['name'];
1856
            }
1857
        }
1858
1859
        if (api_is_platform_admin() || api_is_allowed_to_edit()) {
1860
            $isAllowToEdit = true;
1861
        } else {
1862
            $isAllowToEdit = CourseManager::is_course_teacher(
1863
                api_get_user_id(),
1864
                $courseInfo['code']
1865
            );
1866
        }
1867
1868
        $isAllowToEditByHrm = false;
1869
        if (!empty($sessionId)) {
1870
            $allowDhrToEdit = api_get_configuration_value('allow_agenda_edit_for_hrm');
1871
            if ($allowDhrToEdit) {
1872
                $isHrm = SessionManager::isUserSubscribedAsHRM($sessionId, api_get_user_id());
1873
                if ($isHrm) {
1874
                    $isAllowToEdit = $isAllowToEditByHrm = true;
1875
                }
1876
            }
1877
        }
1878
1879
        $groupMemberships = [];
1880
        if (!empty($groupId)) {
1881
            $groupMemberships = [$groupId];
1882
        } else {
1883
            if ($isAllowToEdit) {
1884
                if (!empty($groupList)) {
1885
                    // c_item_property.to_group_id field was migrated to use
1886
                    // c_group_info.iid
1887
                    $groupMemberships = array_column($groupList, 'iid');
1888
                }
1889
            } else {
1890
                // get only related groups from user
1891
                $groupMemberships = GroupManager::get_group_ids(
1892
                    $courseId,
1893
                    api_get_user_id()
1894
                );
1895
            }
1896
        }
1897
1898
        $tlb_course_agenda = Database::get_course_table(TABLE_AGENDA);
1899
        $tbl_property = Database::get_course_table(TABLE_ITEM_PROPERTY);
1900
1901
        if (empty($sessionId)) {
1902
            $sessionCondition = "
1903
            (
1904
                agenda.session_id = 0 AND (ip.session_id IS NULL OR ip.session_id = 0)
1905
            ) ";
1906
        } else {
1907
            $sessionCondition = "
1908
            (
1909
                agenda.session_id = $sessionId AND
1910
                ip.session_id = $sessionId
1911
            ) ";
1912
        }
1913
1914
        if ($isAllowToEdit) {
1915
            // No group filter was asked
1916
            if (empty($groupId)) {
1917
                if (empty($user_id)) {
1918
                    // Show all events not added in group
1919
                    $userCondition = ' (ip.to_group_id IS NULL OR ip.to_group_id = 0) ';
1920
                    // admin see only his stuff
1921
                    if ($this->type === 'personal') {
1922
                        $userCondition = " (ip.to_user_id = ".api_get_user_id()." AND (ip.to_group_id IS NULL OR ip.to_group_id = 0) ) ";
1923
                        $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) ) ";
1924
                    }
1925
1926
                    if (!empty($groupMemberships)) {
1927
                        // Show events sent to selected groups
1928
                        $userCondition .= " OR (ip.to_user_id = 0 OR ip.to_user_id is NULL) AND (ip.to_group_id IN (".implode(", ", $groupMemberships).")) ";
1929
                    }
1930
                } else {
1931
                    // Show events of requested user in no group
1932
                    $userCondition = " (ip.to_user_id = $user_id AND (ip.to_group_id IS NULL OR ip.to_group_id = 0)) ";
1933
                    // Show events sent to selected groups
1934
                    if (!empty($groupMemberships)) {
1935
                        $userCondition .= " OR (ip.to_user_id = $user_id) AND (ip.to_group_id IN (".implode(", ", $groupMemberships).")) ";
1936
                    }
1937
                }
1938
            } else {
1939
                // Show only selected groups (depending of user status)
1940
                $userCondition = " (ip.to_user_id = 0 OR ip.to_user_id is NULL) AND (ip.to_group_id IN (".implode(", ", $groupMemberships).")) ";
1941
1942
                if (!empty($groupMemberships)) {
1943
                    // Show send to $user_id in selected groups
1944
                    $userCondition .= " OR (ip.to_user_id = $user_id) AND (ip.to_group_id IN (".implode(", ", $groupMemberships).")) ";
1945
                }
1946
            }
1947
        } else {
1948
            // No group filter was asked
1949
            if (empty($groupId)) {
1950
                // Show events sent to everyone and no group
1951
                $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) ';
1952
1953
                // Show events sent to selected groups
1954
                if (!empty($groupMemberships)) {
1955
                    $userCondition .= " OR (ip.to_user_id = 0 OR ip.to_user_id is NULL) AND (ip.to_group_id IN (".implode(", ", $groupMemberships)."))) ";
1956
                } else {
1957
                    $userCondition .= " ) ";
1958
                }
1959
                $userCondition .= " OR (ip.to_user_id = ".api_get_user_id()." AND (ip.to_group_id IS NULL OR ip.to_group_id = 0)) ";
1960
            } else {
1961
                if (!empty($groupMemberships)) {
1962
                    // Show send to everyone - and only selected groups
1963
                    $userCondition = " (ip.to_user_id = 0 OR ip.to_user_id is NULL) AND (ip.to_group_id IN (".implode(", ", $groupMemberships).")) ";
1964
                }
1965
            }
1966
1967
            // Show sent to only me and no group
1968
            if (!empty($groupMemberships)) {
1969
                $userCondition .= " OR (ip.to_user_id = ".api_get_user_id().") AND (ip.to_group_id IN (".implode(", ", $groupMemberships).")) ";
1970
            } else {
1971
                // Show sent to only me and selected groups
1972
            }
1973
        }
1974
1975
        if (api_is_allowed_to_edit()) {
1976
            $visibilityCondition = " (ip.visibility IN ('1', '0'))  ";
1977
        } else {
1978
            $visibilityCondition = " (ip.visibility = '1') ";
1979
        }
1980
1981
        $sql = "SELECT DISTINCT
1982
                    agenda.*,
1983
                    ip.visibility,
1984
                    ip.to_group_id,
1985
                    ip.insert_user_id,
1986
                    ip.ref,
1987
                    to_user_id
1988
                FROM $tlb_course_agenda agenda
1989
                INNER JOIN $tbl_property ip
1990
                ON (
1991
                    agenda.id = ip.ref AND
1992
                    agenda.c_id = ip.c_id AND
1993
                    ip.tool = '".TOOL_CALENDAR_EVENT."'
1994
                )
1995
                WHERE
1996
                    $sessionCondition AND
1997
                    ($userCondition) AND
1998
                    $visibilityCondition AND
1999
                    agenda.c_id = $courseId
2000
        ";
2001
        $dateCondition = '';
2002
        if (!empty($start) && !empty($end)) {
2003
            $dateCondition .= "AND (
2004
                 agenda.start_date BETWEEN '".$start."' AND '".$end."' OR
2005
                 agenda.end_date BETWEEN '".$start."' AND '".$end."' OR
2006
                 (
2007
                     agenda.start_date IS NOT NULL AND agenda.end_date IS NOT NULL AND
2008
                     YEAR(agenda.start_date) = YEAR(agenda.end_date) AND
2009
                     MONTH('$start') BETWEEN MONTH(agenda.start_date) AND MONTH(agenda.end_date)
2010
                 )
2011
            )";
2012
        }
2013
2014
        $sql .= $dateCondition;
2015
        $result = Database::query($sql);
2016
2017
        $coachCanEdit = false;
2018
        if (!empty($sessionId)) {
2019
            $coachCanEdit = api_is_coach($sessionId, $courseId) || api_is_platform_admin();
2020
        }
2021
2022
        if (Database::num_rows($result)) {
2023
            $eventsAdded = array_column($this->events, 'unique_id');
2024
            while ($row = Database::fetch_array($result, 'ASSOC')) {
2025
                $event = [];
2026
                $event['id'] = 'course_'.$row['id'];
2027
                $event['unique_id'] = $row['iid'];
2028
                // To avoid doubles
2029
                if (in_array($event['unique_id'], $eventsAdded)) {
2030
                    continue;
2031
                }
2032
2033
                $eventsAdded[] = $event['unique_id'];
2034
                $eventId = $row['ref'];
2035
                $items = $this->getUsersAndGroupSubscribedToEvent(
2036
                    $eventId,
2037
                    $courseId,
2038
                    $this->sessionId
2039
                );
2040
                $group_to_array = $items['groups'];
2041
                $user_to_array = $items['users'];
2042
                $attachmentList = $this->getAttachmentList(
2043
                    $row['id'],
2044
                    $courseInfo
2045
                );
2046
                $event['attachment'] = '';
2047
                if (!empty($attachmentList)) {
2048
                    foreach ($attachmentList as $attachment) {
2049
                        $has_attachment = Display::return_icon(
2050
                            'attachment.gif',
2051
                            get_lang('Attachment')
2052
                        );
2053
                        $user_filename = $attachment['filename'];
2054
                        $url = api_get_path(WEB_CODE_PATH).'calendar/download.php?file='.$attachment['path'].'&course_id='.$courseId.'&'.api_get_cidreq();
2055
                        $event['attachment'] .= $has_attachment.
2056
                            Display::url(
2057
                                $user_filename,
2058
                                $url
2059
                            ).'<br />';
2060
                    }
2061
                }
2062
2063
                $event['title'] = $row['title'];
2064
                $event['className'] = 'course';
2065
                $event['allDay'] = 'false';
2066
                $event['course_id'] = $courseId;
2067
                $event['borderColor'] = $event['backgroundColor'] = $this->event_course_color;
2068
2069
                $sessionInfo = [];
2070
                if (isset($row['session_id']) && !empty($row['session_id'])) {
2071
                    $sessionInfo = api_get_session_info($sessionId);
2072
                    $event['borderColor'] = $event['backgroundColor'] = $this->event_session_color;
2073
                }
2074
2075
                $event['session_name'] = isset($sessionInfo['name']) ? $sessionInfo['name'] : '';
2076
                $event['course_name'] = isset($courseInfo['title']) ? $courseInfo['title'] : '';
2077
2078
                if (isset($row['to_group_id']) && !empty($row['to_group_id'])) {
2079
                    $event['borderColor'] = $event['backgroundColor'] = $this->event_group_color;
2080
                }
2081
2082
                if (!empty($color)) {
2083
                    $event['borderColor'] = $event['backgroundColor'] = $color;
2084
                }
2085
2086
                if (isset($row['color']) && !empty($row['color'])) {
2087
                    $event['borderColor'] = $event['backgroundColor'] = $row['color'];
2088
                }
2089
2090
                $event['editable'] = false;
2091
                if ($this->getIsAllowedToEdit() && $this->type == 'course') {
2092
                    $event['editable'] = true;
2093
                    if (!empty($sessionId)) {
2094
                        if ($coachCanEdit == false) {
2095
                            $event['editable'] = false;
2096
                        }
2097
                        if ($isAllowToEditByHrm) {
2098
                            $event['editable'] = true;
2099
                        }
2100
                    }
2101
                    // if user is author then he can edit the item
2102
                    if (api_get_user_id() == $row['insert_user_id']) {
2103
                        $event['editable'] = true;
2104
                    }
2105
                }
2106
2107
                if (!empty($row['start_date'])) {
2108
                    $event['start'] = $this->formatEventDate($row['start_date']);
2109
                    $event['start_date_localtime'] = api_get_local_time($row['start_date']);
2110
                }
2111
                if (!empty($row['end_date'])) {
2112
                    $event['end'] = $this->formatEventDate($row['end_date']);
2113
                    $event['end_date_localtime'] = api_get_local_time($row['end_date']);
2114
                }
2115
2116
                $event['sent_to'] = '';
2117
                $event['type'] = 'course';
2118
                if ($row['session_id'] != 0) {
2119
                    $event['type'] = 'session';
2120
                }
2121
2122
                // Event Sent to a group?
2123
                if (isset($row['to_group_id']) && !empty($row['to_group_id'])) {
2124
                    $sent_to = [];
2125
                    if (!empty($group_to_array)) {
2126
                        foreach ($group_to_array as $group_item) {
2127
                            $sent_to[] = $groupNameList[$group_item];
2128
                        }
2129
                    }
2130
                    $sent_to = implode('@@', $sent_to);
2131
                    $sent_to = str_replace(
2132
                        '@@',
2133
                        '</div><div class="label_tag notice">',
2134
                        $sent_to
2135
                    );
2136
                    $event['sent_to'] = '<div class="label_tag notice">'.$sent_to.'</div>';
2137
                    $event['type'] = 'group';
2138
                }
2139
2140
                // Event sent to a user?
2141
                if (isset($row['to_user_id'])) {
2142
                    $sent_to = [];
2143
                    if (!empty($user_to_array)) {
2144
                        foreach ($user_to_array as $item) {
2145
                            $user_info = api_get_user_info($item);
2146
                            // Add username as tooltip for $event['sent_to'] - ref #4226
2147
                            $username = api_htmlentities(
2148
                                sprintf(
2149
                                    get_lang('LoginX'),
2150
                                    $user_info['username']
2151
                                ),
2152
                                ENT_QUOTES
2153
                            );
2154
                            $sent_to[] = "<span title='".$username."'>".$user_info['complete_name']."</span>";
2155
                        }
2156
                    }
2157
                    $sent_to = implode('@@', $sent_to);
2158
                    $sent_to = str_replace(
2159
                        '@@',
2160
                        '</div><div class="label_tag notice">',
2161
                        $sent_to
2162
                    );
2163
                    $event['sent_to'] = '<div class="label_tag notice">'.$sent_to.'</div>';
2164
                }
2165
2166
                //Event sent to everyone!
2167
                if (empty($event['sent_to'])) {
2168
                    $event['sent_to'] = '<div class="label_tag notice">'.get_lang('Everyone').'</div>';
2169
                }
2170
2171
                $event['description'] = $row['content'];
2172
                $event['visibility'] = $row['visibility'];
2173
                $event['real_id'] = $row['id'];
2174
                $event['allDay'] = isset($row['all_day']) && $row['all_day'] == 1 ? $row['all_day'] : 0;
2175
                $event['parent_event_id'] = $row['parent_event_id'];
2176
                $event['has_children'] = $this->hasChildren($row['id'], $courseId) ? 1 : 0;
2177
                $event['comment'] = $row['comment'];
2178
                $this->events[] = $event;
2179
            }
2180
        }
2181
2182
        return $this->events;
2183
    }
2184
2185
    /**
2186
     * @param int $start tms
2187
     * @param int $end   tms
2188
     *
2189
     * @return array
2190
     */
2191
    public function getPlatformEvents($start, $end)
2192
    {
2193
        $start = isset($start) && !empty($start) ? api_get_utc_datetime(intval($start)) : null;
2194
        $end = isset($end) && !empty($end) ? api_get_utc_datetime(intval($end)) : null;
2195
        $dateCondition = '';
2196
2197
        if (!empty($start) && !empty($end)) {
2198
            $dateCondition .= "AND (
2199
                 start_date BETWEEN '".$start."' AND '".$end."' OR
2200
                 end_date BETWEEN '".$start."' AND '".$end."' OR
2201
                 (
2202
                     start_date IS NOT NULL AND end_date IS NOT NULL AND
2203
                     YEAR(start_date) = YEAR(end_date) AND
2204
                     MONTH('$start') BETWEEN MONTH(start_date) AND MONTH(end_date)
2205
                 )
2206
            )";
2207
        }
2208
2209
        $access_url_id = api_get_current_access_url_id();
2210
2211
        $sql = "SELECT *
2212
                FROM ".$this->tbl_global_agenda."
2213
                WHERE access_url_id = $access_url_id
2214
                $dateCondition";
2215
        $result = Database::query($sql);
2216
        $my_events = [];
2217
        if (Database::num_rows($result)) {
2218
            while ($row = Database::fetch_array($result, 'ASSOC')) {
2219
                $event = [];
2220
                $event['id'] = 'platform_'.$row['id'];
2221
                $event['title'] = $row['title'];
2222
                $event['className'] = 'platform';
2223
                $event['allDay'] = 'false';
2224
                $event['borderColor'] = $event['backgroundColor'] = $this->event_platform_color;
2225
                $event['editable'] = false;
2226
                $event['type'] = 'admin';
2227
2228
                if (api_is_platform_admin() && $this->type === 'admin') {
2229
                    $event['editable'] = true;
2230
                }
2231
2232
                if (!empty($row['start_date'])) {
2233
                    $event['start'] = $this->formatEventDate($row['start_date']);
2234
                    $event['start_date_localtime'] = api_get_local_time($row['start_date']);
2235
                }
2236
2237
                if (!empty($row['end_date'])) {
2238
                    $event['end'] = $this->formatEventDate($row['end_date']);
2239
                    $event['end_date_localtime'] = api_get_local_time($row['end_date']);
2240
                }
2241
                $event['allDay'] = isset($row['all_day']) && $row['all_day'] == 1 ? $row['all_day'] : 0;
2242
                $event['parent_event_id'] = 0;
2243
                $event['has_children'] = 0;
2244
                $event['description'] = $row['content'];
2245
2246
                $my_events[] = $event;
2247
                $this->events[] = $event;
2248
            }
2249
        }
2250
2251
        return $my_events;
2252
    }
2253
2254
    /**
2255
     * @param FormValidator $form
2256
     * @param array         $groupList
2257
     * @param array         $userList
2258
     * @param array         $sendTo               array('users' => [1, 2], 'groups' => [3, 4])
2259
     * @param array         $attributes
2260
     * @param bool          $addOnlyItemsInSendTo
2261
     * @param bool          $required
2262
     */
2263
    public function setSendToSelect(
2264
        $form,
2265
        $groupList = [],
2266
        $userList = [],
2267
        $sendTo = [],
2268
        $attributes = [],
2269
        $addOnlyItemsInSendTo = false,
2270
        $required = false
2271
    ) {
2272
        $params = [
2273
            'id' => 'users_to_send_id',
2274
            'data-placeholder' => get_lang('Select'),
2275
            'multiple' => 'multiple',
2276
            'class' => 'multiple-select',
2277
        ];
2278
2279
        if (!empty($attributes)) {
2280
            $params = array_merge($params, $attributes);
2281
            if (empty($params['multiple'])) {
2282
                unset($params['multiple']);
2283
            }
2284
        }
2285
2286
        $sendToGroups = isset($sendTo['groups']) ? $sendTo['groups'] : [];
2287
        $sendToUsers = isset($sendTo['users']) ? $sendTo['users'] : [];
2288
2289
        /** @var HTML_QuickForm_select $select */
2290
        $select = $form->addSelect(
2291
            'users_to_send',
2292
            get_lang('To'),
2293
            null,
2294
            $params
2295
        );
2296
2297
        if ($required) {
2298
            $form->setRequired($select);
2299
        }
2300
2301
        $selectedEveryoneOptions = [];
2302
        if (isset($sendTo['everyone']) && $sendTo['everyone']) {
2303
            $selectedEveryoneOptions = ['selected'];
2304
            $sendToUsers = [];
2305
        }
2306
2307
        $select->addOption(
2308
            get_lang('Everyone'),
2309
            'everyone',
2310
            $selectedEveryoneOptions
2311
        );
2312
2313
        $options = [];
2314
        if (is_array($groupList)) {
2315
            foreach ($groupList as $group) {
2316
                $count_users = isset($group['count_users']) ? $group['count_users'] : $group['userNb'];
2317
                $count_users = " &ndash; $count_users ".get_lang('Users');
2318
                $option = [
2319
                    'text' => $group['name'].$count_users,
2320
                    'value' => "GROUP:".$group['id'],
2321
                ];
2322
                $selected = in_array(
2323
                    $group['id'],
2324
                    $sendToGroups
2325
                ) ? true : false;
2326
                if ($selected) {
2327
                    $option['selected'] = 'selected';
2328
                }
2329
2330
                if ($addOnlyItemsInSendTo) {
2331
                    if ($selected) {
2332
                        $options[] = $option;
2333
                    }
2334
                } else {
2335
                    $options[] = $option;
2336
                }
2337
            }
2338
            $select->addOptGroup($options, get_lang('Groups'));
2339
        }
2340
2341
        // adding the individual users to the select form
2342
        if (is_array($userList)) {
2343
            $options = [];
2344
            foreach ($userList as $user) {
2345
                if ($user['status'] == ANONYMOUS) {
2346
                    continue;
2347
                }
2348
                $option = [
2349
                    'text' => api_get_person_name(
2350
                            $user['firstname'],
2351
                            $user['lastname']
2352
                        ).' ('.$user['username'].')',
2353
                    'value' => "USER:".$user['user_id'],
2354
                ];
2355
2356
                $selected = in_array(
2357
                    $user['user_id'],
2358
                    $sendToUsers
2359
                ) ? true : false;
2360
2361
                if ($selected) {
2362
                    $option['selected'] = 'selected';
2363
                }
2364
2365
                if ($addOnlyItemsInSendTo) {
2366
                    if ($selected) {
2367
                        $options[] = $option;
2368
                    }
2369
                } else {
2370
                    $options[] = $option;
2371
                }
2372
            }
2373
2374
            $select->addOptGroup($options, get_lang('Users'));
2375
        }
2376
    }
2377
2378
    /**
2379
     * Separates the users and groups array
2380
     * users have a value USER:XXX (with XXX the user id
2381
     * groups have a value GROUP:YYY (with YYY the group id)
2382
     * use the 'everyone' key.
2383
     *
2384
     * @author Julio Montoya based in separate_users_groups in agenda.inc.php
2385
     *
2386
     * @param array $to
2387
     *
2388
     * @return array
2389
     */
2390
    public function parseSendToArray($to)
2391
    {
2392
        $groupList = [];
2393
        $userList = [];
2394
        $sendTo = null;
2395
2396
        $sendTo['everyone'] = false;
2397
        if (is_array($to) && count($to) > 0) {
2398
            foreach ($to as $item) {
2399
                if ($item == 'everyone') {
2400
                    $sendTo['everyone'] = true;
2401
                } else {
2402
                    list($type, $id) = explode(':', $item);
2403
                    switch ($type) {
2404
                        case 'GROUP':
2405
                            $groupList[] = $id;
2406
                            break;
2407
                        case 'USER':
2408
                            $userList[] = $id;
2409
                            break;
2410
                    }
2411
                }
2412
            }
2413
            $sendTo['groups'] = $groupList;
2414
            $sendTo['users'] = $userList;
2415
        }
2416
2417
        return $sendTo;
2418
    }
2419
2420
    /**
2421
     * @param array $params
2422
     *
2423
     * @return FormValidator
2424
     */
2425
    public function getForm($params = [])
2426
    {
2427
        $action = isset($params['action']) ? Security::remove_XSS($params['action']) : null;
2428
        $id = isset($params['id']) ? (int) $params['id'] : 0;
2429
2430
        $url = api_get_self().'?action='.$action.'&id='.$id.'&type='.$this->type;
2431
        if ($this->type == 'course') {
2432
            $url = api_get_self().'?'.api_get_cidreq().'&action='.$action.'&id='.$id.'&type='.$this->type;
2433
        }
2434
2435
        $form = new FormValidator(
2436
            'add_event',
2437
            'post',
2438
            $url,
2439
            null,
2440
            ['enctype' => 'multipart/form-data']
2441
        );
2442
2443
        $idAttach = isset($params['id_attach']) ? (int) $params['id_attach'] : null;
2444
        $groupId = api_get_group_id();
2445
        $form_Title = get_lang('AddCalendarItem');
2446
        if (!empty($id)) {
2447
            $form_Title = get_lang('ModifyCalendarItem');
2448
        }
2449
2450
        $form->addHeader($form_Title);
2451
        $form->addElement('hidden', 'id', $id);
2452
        $form->addElement('hidden', 'action', $action);
2453
        $form->addElement('hidden', 'id_attach', $idAttach);
2454
2455
        $isSubEventEdition = false;
2456
        $isParentFromSerie = false;
2457
        $showAttachmentForm = true;
2458
2459
        if ($this->type == 'course') {
2460
            // Edition mode.
2461
            if (!empty($id)) {
2462
                $showAttachmentForm = false;
2463
                if (isset($params['parent_event_id']) && !empty($params['parent_event_id'])) {
2464
                    $isSubEventEdition = true;
2465
                }
2466
                if (!empty($params['repeat_info'])) {
2467
                    $isParentFromSerie = true;
2468
                }
2469
            }
2470
        }
2471
2472
        if ($isSubEventEdition) {
2473
            $form->addElement(
2474
                'label',
2475
                null,
2476
                Display::return_message(
2477
                    get_lang('EditingThisEventWillRemoveItFromTheSerie'),
2478
                    'warning'
2479
                )
2480
            );
2481
        }
2482
2483
        $form->addElement('text', 'title', get_lang('ItemTitle'));
2484
2485
        if (isset($groupId) && !empty($groupId)) {
2486
            $form->addElement(
2487
                'hidden',
2488
                'users_to_send[]',
2489
                "GROUP:$groupId"
2490
            );
2491
            $form->addElement('hidden', 'to', 'true');
2492
        } else {
2493
            $sendTo = isset($params['send_to']) ? $params['send_to'] : ['everyone' => true];
2494
            if ($this->type == 'course') {
2495
                $this->showToForm($form, $sendTo, [], false, true);
2496
            }
2497
        }
2498
2499
        $form->addDateRangePicker(
2500
            'date_range',
2501
            get_lang('DateRange'),
2502
            false,
2503
            ['id' => 'date_range']
2504
        );
2505
        $form->addElement('checkbox', 'all_day', null, get_lang('AllDay'));
2506
2507
        if ($this->type == 'course') {
2508
            $repeat = $form->addElement(
2509
                'checkbox',
2510
                'repeat',
2511
                null,
2512
                get_lang('RepeatEvent'),
2513
                ['onclick' => 'return plus_repeated_event();']
2514
            );
2515
            $form->addElement(
2516
                'html',
2517
                '<div id="options2" style="display:none">'
2518
            );
2519
            $form->addElement(
2520
                'select',
2521
                'repeat_type',
2522
                get_lang('RepeatType'),
2523
                self::getRepeatTypes()
2524
            );
2525
            $form->addElement(
2526
                'date_picker',
2527
                'repeat_end_day',
2528
                get_lang('RepeatEnd'),
2529
                ['id' => 'repeat_end_date_form']
2530
            );
2531
2532
            if ($isSubEventEdition || $isParentFromSerie) {
2533
                $repeatInfo = $params['repeat_info'];
2534
                if ($isSubEventEdition) {
2535
                    $parentEvent = $params['parent_info'];
2536
                    $repeatInfo = $parentEvent['repeat_info'];
2537
                }
2538
                $params['repeat'] = 1;
2539
                $params['repeat_type'] = $repeatInfo['cal_type'];
2540
                $params['repeat_end_day'] = substr(
2541
                    api_get_local_time($repeatInfo['cal_end']),
2542
                    0,
2543
                    10
2544
                );
2545
2546
                $form->freeze(['repeat_type', 'repeat_end_day']);
2547
                $repeat->_attributes['disabled'] = 'disabled';
2548
            }
2549
            $form->addElement('html', '</div>');
2550
        }
2551
2552
        if (!empty($id)) {
2553
            if (empty($params['end_date'])) {
2554
                $params['date_range'] = $params['end_date'];
2555
            }
2556
2557
            $params['date_range'] =
2558
                substr(api_get_local_time($params['start_date']), 0, 16).' / '.
2559
                substr(api_get_local_time($params['end_date']), 0, 16);
2560
        }
2561
2562
        $toolbar = 'Agenda';
2563
        if (!api_is_allowed_to_edit(null, true)) {
2564
            $toolbar = 'AgendaStudent';
2565
        }
2566
2567
        $form->addElement(
2568
            'html_editor',
2569
            'content',
2570
            get_lang('Description'),
2571
            null,
2572
            [
2573
                'ToolbarSet' => $toolbar,
2574
                'Width' => '100%',
2575
                'Height' => '200',
2576
            ]
2577
        );
2578
2579
        if ($this->type == 'course') {
2580
            $form->addElement('textarea', 'comment', get_lang('Comment'));
2581
            $form->addLabel(
2582
                get_lang('FilesAttachment'),
2583
                '<div id="filepaths" class="file-upload-event">
2584
2585
                        <div id="filepath_1">
2586
                            <input type="file" name="attach_1"/>
2587
2588
                            <label>'.get_lang('Description').'</label>
2589
                            <input class="form-control" type="text" name="legend[]" />
2590
                        </div>
2591
2592
                    </div>'
2593
            );
2594
2595
            $form->addLabel(
2596
                '',
2597
                '<span id="link-more-attach">
2598
                    <a href="javascript://" onclick="return add_image_form()">'.
2599
                get_lang('AddOneMoreFile').'</a>
2600
                 </span>&nbsp;('.sprintf(
2601
                    get_lang('MaximunFileSizeX'),
2602
                    format_file_size(
2603
                        api_get_setting('message_max_upload_filesize')
2604
                    )
2605
                ).')'
2606
            );
2607
2608
            if (isset($params['attachment']) && !empty($params['attachment'])) {
2609
                $attachmentList = $params['attachment'];
2610
                foreach ($attachmentList as $attachment) {
2611
                    $params['file_comment'] = $attachment['comment'];
2612
                    if (!empty($attachment['path'])) {
2613
                        $form->addElement(
2614
                            'checkbox',
2615
                            'delete_attachment['.$attachment['id'].']',
2616
                            null,
2617
                            get_lang(
2618
                                'DeleteAttachment'
2619
                            ).': '.$attachment['filename']
2620
                        );
2621
                    }
2622
                }
2623
            }
2624
2625
            $form->addElement(
2626
                'textarea',
2627
                'file_comment',
2628
                get_lang('FileComment')
2629
            );
2630
        }
2631
2632
        if (empty($id)) {
2633
            $form->addElement(
2634
                'checkbox',
2635
                'add_announcement',
2636
                null,
2637
                get_lang('AddAnnouncement').'&nbsp('.get_lang('SendMail').')'
2638
            );
2639
        }
2640
2641
        $agendaCollectiveInvitations = api_get_configuration_value('agenda_collective_invitations');
2642
2643
        if ($agendaCollectiveInvitations && 'personal' === $this->type) {
2644
            $em = Database::getManager();
2645
2646
            $invitees = [];
2647
            $isCollective = false;
2648
2649
            if ($id) {
2650
                $event = $em->find('ChamiloCoreBundle:PersonalAgenda', $id);
2651
                $eventInvitation = $event->getInvitation();
2652
2653
                if ($eventInvitation) {
2654
                    foreach ($eventInvitation->getInvitees() as $invitee) {
2655
                        $inviteeUser = $invitee->getUser();
2656
2657
                        $invitees[$inviteeUser->getId()] = $inviteeUser->getCompleteNameWithUsername();
2658
                    }
2659
                }
2660
2661
                $isCollective = $event->isCollective();
2662
            }
2663
2664
            $form->addSelectAjax(
2665
                'invitees',
2666
                get_lang('Invitees'),
2667
                $invitees,
2668
                [
2669
                    'multiple' => 'multiple',
2670
                    'url' => api_get_path(WEB_AJAX_PATH).'message.ajax.php?a=find_users',
2671
                ]
2672
            );
2673
            $form->addCheckBox('collective', '', get_lang('IsItEditableByTheInvitees'));
2674
2675
            $params['invitees'] = array_keys($invitees);
2676
            $params['collective'] = $isCollective;
2677
        }
2678
2679
        if ($id) {
2680
            $form->addButtonUpdate(get_lang('ModifyEvent'));
2681
        } else {
2682
            $form->addButtonSave(get_lang('AgendaAdd'));
2683
        }
2684
2685
        $form->setDefaults($params);
2686
        $form->addRule(
2687
            'date_range',
2688
            get_lang('ThisFieldIsRequired'),
2689
            'required'
2690
        );
2691
        $form->addRule('title', get_lang('ThisFieldIsRequired'), 'required');
2692
2693
        return $form;
2694
    }
2695
2696
    /**
2697
     * @param FormValidator $form
2698
     * @param array         $sendTo               array('everyone' => false, 'users' => [1, 2], 'groups' => [3, 4])
2699
     * @param array         $attributes
2700
     * @param bool          $addOnlyItemsInSendTo
2701
     * @param bool          $required
2702
     *
2703
     * @return bool
2704
     */
2705
    public function showToForm(
2706
        $form,
2707
        $sendTo = [],
2708
        $attributes = [],
2709
        $addOnlyItemsInSendTo = false,
2710
        $required = false
2711
    ) {
2712
        if ($this->type != 'course') {
2713
            return false;
2714
        }
2715
2716
        $order = 'lastname';
2717
        if (api_is_western_name_order()) {
2718
            $order = 'firstname';
2719
        }
2720
2721
        $userList = CourseManager::get_user_list_from_course_code(
2722
            api_get_course_id(),
2723
            $this->sessionId,
2724
            null,
2725
            $order
2726
        );
2727
2728
        $groupList = CourseManager::get_group_list_of_course(
2729
            api_get_course_id(),
2730
            $this->sessionId
2731
        );
2732
2733
        $this->setSendToSelect(
2734
            $form,
2735
            $groupList,
2736
            $userList,
2737
            $sendTo,
2738
            $attributes,
2739
            $addOnlyItemsInSendTo,
2740
            $required
2741
        );
2742
2743
        return true;
2744
    }
2745
2746
    /**
2747
     * @param int   $id
2748
     * @param int   $visibility 0= invisible, 1 visible
2749
     * @param array $courseInfo
2750
     * @param int   $userId
2751
     */
2752
    public static function changeVisibility(
2753
        $id,
2754
        $visibility,
2755
        $courseInfo,
2756
        $userId = null
2757
    ) {
2758
        $id = intval($id);
2759
        if (empty($userId)) {
2760
            $userId = api_get_user_id();
2761
        } else {
2762
            $userId = intval($userId);
2763
        }
2764
2765
        if ($visibility == 0) {
2766
            api_item_property_update(
2767
                $courseInfo,
2768
                TOOL_CALENDAR_EVENT,
2769
                $id,
2770
                'invisible',
2771
                $userId
2772
            );
2773
        } else {
2774
            api_item_property_update(
2775
                $courseInfo,
2776
                TOOL_CALENDAR_EVENT,
2777
                $id,
2778
                'visible',
2779
                $userId
2780
            );
2781
        }
2782
    }
2783
2784
    /**
2785
     * Get repeat types.
2786
     *
2787
     * @return array
2788
     */
2789
    public static function getRepeatTypes()
2790
    {
2791
        return [
2792
            'daily' => get_lang('RepeatDaily'),
2793
            'weekly' => get_lang('RepeatWeekly'),
2794
            'monthlyByDate' => get_lang('RepeatMonthlyByDate'),
2795
            //monthlyByDay"> get_lang('RepeatMonthlyByDay');
2796
            //monthlyByDayR' => get_lang('RepeatMonthlyByDayR'),
2797
            'yearly' => get_lang('RepeatYearly'),
2798
        ];
2799
    }
2800
2801
    /**
2802
     * Show a list with all the attachments according to the post's id.
2803
     *
2804
     * @param int   $eventId
2805
     * @param array $courseInfo
2806
     *
2807
     * @return array with the post info
2808
     */
2809
    public function getAttachmentList($eventId, $courseInfo)
2810
    {
2811
        $tableAttachment = Database::get_course_table(TABLE_AGENDA_ATTACHMENT);
2812
        $courseId = (int) $courseInfo['real_id'];
2813
        $eventId = (int) $eventId;
2814
2815
        $sql = "SELECT id, path, filename, comment
2816
                FROM $tableAttachment
2817
                WHERE
2818
                    c_id = $courseId AND
2819
                    agenda_id = $eventId";
2820
        $result = Database::query($sql);
2821
        $list = [];
2822
        if (Database::num_rows($result) != 0) {
2823
            $list = Database::store_result($result, 'ASSOC');
2824
        }
2825
2826
        return $list;
2827
    }
2828
2829
    /**
2830
     * Show a list with all the attachments according to the post's id.
2831
     *
2832
     * @param int   $attachmentId
2833
     * @param int   $eventId
2834
     * @param array $courseInfo
2835
     *
2836
     * @return array with the post info
2837
     */
2838
    public function getAttachment($attachmentId, $eventId, $courseInfo)
2839
    {
2840
        if (empty($courseInfo) || empty($attachmentId) || empty($eventId)) {
2841
            return [];
2842
        }
2843
2844
        $tableAttachment = Database::get_course_table(TABLE_AGENDA_ATTACHMENT);
2845
        $courseId = (int) $courseInfo['real_id'];
2846
        $eventId = (int) $eventId;
2847
        $attachmentId = (int) $attachmentId;
2848
2849
        $row = [];
2850
        $sql = "SELECT id, path, filename, comment
2851
                FROM $tableAttachment
2852
                WHERE
2853
                    c_id = $courseId AND
2854
                    agenda_id = $eventId AND
2855
                    id = $attachmentId
2856
                ";
2857
        $result = Database::query($sql);
2858
        if (Database::num_rows($result) != 0) {
2859
            $row = Database::fetch_array($result, 'ASSOC');
2860
        }
2861
2862
        return $row;
2863
    }
2864
2865
    /**
2866
     * Add an attachment file into agenda.
2867
     *
2868
     * @param int    $eventId
2869
     * @param array  $fileUserUpload ($_FILES['user_upload'])
2870
     * @param string $comment        about file
2871
     * @param array  $courseInfo
2872
     *
2873
     * @return string
2874
     */
2875
    public function addAttachment(
2876
        $eventId,
2877
        $fileUserUpload,
2878
        $comment,
2879
        $courseInfo
2880
    ) {
2881
        $agenda_table_attachment = Database::get_course_table(TABLE_AGENDA_ATTACHMENT);
2882
        $eventId = (int) $eventId;
2883
2884
        // Storing the attachments
2885
        $upload_ok = false;
2886
        if (!empty($fileUserUpload['name'])) {
2887
            $upload_ok = process_uploaded_file($fileUserUpload);
2888
        }
2889
2890
        if (!empty($upload_ok)) {
2891
            $courseDir = $courseInfo['directory'].'/upload/calendar';
2892
            $sys_course_path = api_get_path(SYS_COURSE_PATH);
2893
            $uploadDir = $sys_course_path.$courseDir;
2894
2895
            // Try to add an extension to the file if it hasn't one
2896
            $new_file_name = add_ext_on_mime(
2897
                stripslashes($fileUserUpload['name']),
2898
                $fileUserUpload['type']
2899
            );
2900
2901
            // user's file name
2902
            $file_name = $fileUserUpload['name'];
2903
2904
            if (!filter_extension($new_file_name)) {
2905
                return Display::return_message(
2906
                    get_lang('UplUnableToSaveFileFilteredExtension'),
2907
                    'error'
2908
                );
2909
            } else {
2910
                $new_file_name = uniqid('');
2911
                $new_path = $uploadDir.'/'.$new_file_name;
2912
                $result = @move_uploaded_file(
2913
                    $fileUserUpload['tmp_name'],
2914
                    $new_path
2915
                );
2916
                $courseId = api_get_course_int_id();
2917
                $size = intval($fileUserUpload['size']);
2918
                // Storing the attachments if any
2919
                if ($result) {
2920
                    $params = [
2921
                        'c_id' => $courseId,
2922
                        'filename' => $file_name,
2923
                        'comment' => $comment,
2924
                        'path' => $new_file_name,
2925
                        'agenda_id' => $eventId,
2926
                        'size' => $size,
2927
                    ];
2928
                    $id = Database::insert($agenda_table_attachment, $params);
2929
                    if ($id) {
2930
                        $sql = "UPDATE $agenda_table_attachment
2931
                                SET id = iid WHERE iid = $id";
2932
                        Database::query($sql);
2933
2934
                        api_item_property_update(
2935
                            $courseInfo,
2936
                            'calendar_event_attachment',
2937
                            $id,
2938
                            'AgendaAttachmentAdded',
2939
                            api_get_user_id()
2940
                        );
2941
                    }
2942
                }
2943
            }
2944
        }
2945
    }
2946
2947
    /**
2948
     * @param int    $attachmentId
2949
     * @param int    $eventId
2950
     * @param array  $fileUserUpload
2951
     * @param string $comment
2952
     * @param array  $courseInfo
2953
     */
2954
    public function updateAttachment(
2955
        $attachmentId,
2956
        $eventId,
2957
        $fileUserUpload,
2958
        $comment,
2959
        $courseInfo
2960
    ) {
2961
        $attachment = $this->getAttachment(
2962
            $attachmentId,
2963
            $eventId,
2964
            $courseInfo
2965
        );
2966
        if (!empty($attachment)) {
2967
            $this->deleteAttachmentFile($attachmentId, $courseInfo);
2968
        }
2969
        $this->addAttachment($eventId, $fileUserUpload, $comment, $courseInfo);
2970
    }
2971
2972
    /**
2973
     * This function delete a attachment file by id.
2974
     *
2975
     * @param int   $attachmentId
2976
     * @param array $courseInfo
2977
     *
2978
     * @return string
2979
     */
2980
    public function deleteAttachmentFile($attachmentId, $courseInfo)
2981
    {
2982
        $table = Database::get_course_table(TABLE_AGENDA_ATTACHMENT);
2983
        $attachmentId = (int) $attachmentId;
2984
        $courseId = $courseInfo['real_id'];
2985
2986
        if (empty($courseId) || empty($attachmentId)) {
2987
            return false;
2988
        }
2989
2990
        $sql = "DELETE FROM $table
2991
                WHERE c_id = $courseId AND id = ".$attachmentId;
2992
        $result = Database::query($sql);
2993
2994
        // update item_property
2995
        api_item_property_update(
2996
            $courseInfo,
2997
            'calendar_event_attachment',
2998
            $attachmentId,
2999
            'AgendaAttachmentDeleted',
3000
            api_get_user_id()
3001
        );
3002
3003
        if (!empty($result)) {
3004
            return Display::return_message(
3005
                get_lang("AttachmentFileDeleteSuccess"),
3006
                'confirmation'
3007
            );
3008
        }
3009
    }
3010
3011
    /**
3012
     * @param int $eventId
3013
     *
3014
     * @return array
3015
     */
3016
    public function getAllRepeatEvents($eventId)
3017
    {
3018
        $events = [];
3019
        $eventId = (int) $eventId;
3020
3021
        switch ($this->type) {
3022
            case 'personal':
3023
                break;
3024
            case 'course':
3025
                if (!empty($this->course['real_id'])) {
3026
                    $sql = "SELECT * FROM ".$this->tbl_course_agenda."
3027
                            WHERE
3028
                                c_id = ".$this->course['real_id']." AND
3029
                                parent_event_id = ".$eventId;
3030
                    $result = Database::query($sql);
3031
                    if (Database::num_rows($result)) {
3032
                        while ($row = Database::fetch_array($result, 'ASSOC')) {
3033
                            $events[] = $row;
3034
                        }
3035
                    }
3036
                }
3037
                break;
3038
        }
3039
3040
        return $events;
3041
    }
3042
3043
    /**
3044
     * @param int $eventId
3045
     * @param int $courseId
3046
     *
3047
     * @return bool
3048
     */
3049
    public function hasChildren($eventId, $courseId)
3050
    {
3051
        $eventId = (int) $eventId;
3052
        $courseId = (int) $courseId;
3053
3054
        $sql = "SELECT count(DISTINCT(id)) as count
3055
                FROM ".$this->tbl_course_agenda."
3056
                WHERE
3057
                    c_id = $courseId AND
3058
                    parent_event_id = $eventId";
3059
        $result = Database::query($sql);
3060
        if (Database::num_rows($result)) {
3061
            $row = Database::fetch_array($result, 'ASSOC');
3062
3063
            return $row['count'] > 0;
3064
        }
3065
3066
        return false;
3067
    }
3068
3069
    /**
3070
     * @param int    $filter
3071
     * @param string $view
3072
     *
3073
     * @return string
3074
     */
3075
    public function displayActions($view, $filter = 0)
3076
    {
3077
        $groupInfo = GroupManager::get_group_properties(api_get_group_id());
3078
        $groupIid = isset($groupInfo['iid']) ? $groupInfo['iid'] : 0;
3079
3080
        $codePath = api_get_path(WEB_CODE_PATH);
3081
3082
        $currentUserId = api_get_user_id();
3083
        $cidReq = api_get_cidreq();
3084
3085
        $actionsLeft = '';
3086
        $actionsLeft .= Display::url(
3087
            Display::return_icon('calendar.png', get_lang('Calendar'), [], ICON_SIZE_MEDIUM),
3088
            $codePath."calendar/agenda_js.php?type={$this->type}&$cidReq"
3089
        );
3090
        $actionsLeft .= Display::url(
3091
            Display::return_icon('week.png', get_lang('AgendaList'), [], ICON_SIZE_MEDIUM),
3092
            $codePath."calendar/agenda_list.php?type={$this->type}&$cidReq"
3093
        );
3094
3095
        $form = '';
3096
        if (api_is_allowed_to_edit(false, true) ||
3097
            ('personal' === $this->type && !api_is_anonymous() && 'true' === api_get_setting('allow_personal_agenda')) ||
3098
            (
3099
                '1' === api_get_course_setting('allow_user_edit_agenda') && !api_is_anonymous() &&
3100
                api_is_allowed_to_session_edit(false, true))
3101
            || (
3102
                GroupManager::user_has_access($currentUserId, $groupIid, GroupManager::GROUP_TOOL_CALENDAR)
3103
                && GroupManager::is_tutor_of_group($currentUserId, $groupInfo)
3104
            )
3105
        ) {
3106
            $actionsLeft .= Display::url(
3107
                Display::return_icon('new_event.png', get_lang('AgendaAdd'), [], ICON_SIZE_MEDIUM),
3108
                $codePath."calendar/agenda.php?action=add&type={$this->type}&$cidReq"
3109
            );
3110
3111
            $actionsLeft .= Display::url(
3112
                Display::return_icon('import_calendar.png', get_lang('ICalFileImport'), [], ICON_SIZE_MEDIUM),
3113
                $codePath."calendar/agenda.php?action=importical&type={$this->type}&$cidReq"
3114
            );
3115
3116
            if ($this->type === 'course') {
3117
                if (!isset($_GET['action'])) {
3118
                    $form = new FormValidator(
3119
                        'form-search',
3120
                        'post',
3121
                        '',
3122
                        '',
3123
                        [],
3124
                        FormValidator::LAYOUT_INLINE
3125
                    );
3126
                    $attributes = [
3127
                        'multiple' => false,
3128
                        'id' => 'select_form_id_search',
3129
                    ];
3130
                    $selectedValues = $this->parseAgendaFilter($filter);
3131
                    $this->showToForm($form, $selectedValues, $attributes);
3132
                    $form = $form->returnForm();
3133
                }
3134
            }
3135
        }
3136
3137
        if ($this->type === 'personal' && !api_is_anonymous()) {
3138
            $actionsLeft .= Display::url(
3139
                Display::return_icon('1day.png', get_lang('SessionsPlanCalendar'), [], ICON_SIZE_MEDIUM),
3140
                $codePath.'calendar/planification.php'
3141
            );
3142
3143
            if (api_is_student_boss() || api_is_platform_admin()) {
3144
                $actionsLeft .= Display::url(
3145
                    Display::return_icon('calendar-user.png', get_lang('MyStudentsSchedule'), [], ICON_SIZE_MEDIUM),
3146
                    $codePath.'mySpace/calendar_plan.php'
3147
                );
3148
            }
3149
        }
3150
3151
        if (api_is_platform_admin() ||
3152
            api_is_teacher() ||
3153
            api_is_student_boss() ||
3154
            api_is_drh() ||
3155
            api_is_session_admin() ||
3156
            api_is_coach()
3157
        ) {
3158
            if ($this->type == 'personal') {
3159
                $form = null;
3160
                if (!isset($_GET['action'])) {
3161
                    $form = new FormValidator(
3162
                        'form-search',
3163
                        'get',
3164
                        api_get_self().'?type=personal&',
3165
                        '',
3166
                        [],
3167
                        FormValidator::LAYOUT_INLINE
3168
                    );
3169
3170
                    $sessions = [];
3171
3172
                    if (api_is_drh()) {
3173
                        $sessionList = SessionManager::get_sessions_followed_by_drh($currentUserId);
3174
                        if (!empty($sessionList)) {
3175
                            foreach ($sessionList as $sessionItem) {
3176
                                $sessions[$sessionItem['id']] = strip_tags($sessionItem['name']);
3177
                            }
3178
                        }
3179
                    } else {
3180
                        $sessions = SessionManager::get_sessions_by_user($currentUserId);
3181
                        $sessions = array_column($sessions, 'session_name', 'session_id');
3182
                    }
3183
3184
                    $form->addHidden('type', 'personal');
3185
                    $sessions = ['0' => get_lang('SelectAnOption')] + $sessions;
3186
3187
                    $form->addSelect(
3188
                        'session_id',
3189
                        get_lang('Session'),
3190
                        $sessions,
3191
                        ['id' => 'session_id', 'onchange' => 'submit();']
3192
                    );
3193
3194
                    $form->addButtonReset(get_lang('Reset'));
3195
                    $form = $form->returnForm();
3196
                }
3197
            }
3198
        }
3199
3200
        $actionsRight = '';
3201
        if ($view == 'calendar') {
3202
            $actionsRight .= $form;
3203
        }
3204
3205
        $toolbar = Display::toolbarAction(
3206
            'toolbar-agenda',
3207
            [$actionsLeft, $actionsRight]
3208
        );
3209
3210
        return $toolbar;
3211
    }
3212
3213
    /**
3214
     * @return FormValidator
3215
     */
3216
    public function getImportCalendarForm()
3217
    {
3218
        $form = new FormValidator(
3219
            'frm_import_ical',
3220
            'post',
3221
            api_get_self().'?action=importical&type='.$this->type,
3222
            ['enctype' => 'multipart/form-data']
3223
        );
3224
        $form->addHeader(get_lang('ICalFileImport'));
3225
        $form->addElement('file', 'ical_import', get_lang('ICalFileImport'));
3226
        $form->addRule(
3227
            'ical_import',
3228
            get_lang('ThisFieldIsRequired'),
3229
            'required'
3230
        );
3231
        $form->addButtonImport(get_lang('Import'), 'ical_submit');
3232
3233
        return $form;
3234
    }
3235
3236
    /**
3237
     * @param array $courseInfo
3238
     * @param $file
3239
     *
3240
     * @return false|string
3241
     */
3242
    public function importEventFile($courseInfo, $file)
3243
    {
3244
        $charset = api_get_system_encoding();
3245
        $filepath = api_get_path(SYS_ARCHIVE_PATH).$file['name'];
3246
        $messages = [];
3247
3248
        if (!@move_uploaded_file($file['tmp_name'], $filepath)) {
3249
            error_log(
3250
                'Problem moving uploaded file: '.$file['error'].' in '.__FILE__.' line '.__LINE__
3251
            );
3252
3253
            return false;
3254
        }
3255
3256
        $data = file_get_contents($filepath);
3257
3258
        $trans = [
3259
            'DAILY' => 'daily',
3260
            'WEEKLY' => 'weekly',
3261
            'MONTHLY' => 'monthlyByDate',
3262
            'YEARLY' => 'yearly',
3263
        ];
3264
        $sentTo = ['everyone' => true];
3265
        $calendar = Sabre\VObject\Reader::read($data);
3266
        $currentTimeZone = api_get_timezone();
3267
        if (!empty($calendar->VEVENT)) {
3268
            foreach ($calendar->VEVENT as $event) {
3269
                $start = $event->DTSTART->getDateTime();
3270
                $end = $event->DTEND->getDateTime();
3271
                //Sabre\VObject\DateTimeParser::parseDateTime(string $dt, \Sabre\VObject\DateTimeZone $tz)
3272
3273
                $startDateTime = api_get_local_time(
3274
                    $start->format('Y-m-d H:i:s'),
3275
                    $currentTimeZone,
3276
                    $start->format('e')
3277
                );
3278
                $endDateTime = api_get_local_time(
3279
                    $end->format('Y-m-d H:i'),
3280
                    $currentTimeZone,
3281
                    $end->format('e')
3282
                );
3283
                $title = api_convert_encoding(
3284
                    (string) $event->summary,
3285
                    $charset,
3286
                    'UTF-8'
3287
                );
3288
                $description = api_convert_encoding(
3289
                    (string) $event->description,
3290
                    $charset,
3291
                    'UTF-8'
3292
                );
3293
3294
                $id = $this->addEvent(
3295
                    $startDateTime,
3296
                    $endDateTime,
3297
                    'false',
3298
                    $title,
3299
                    $description,
3300
                    $sentTo
3301
                );
3302
3303
                $messages[] = " $title - ".$startDateTime." - ".$endDateTime;
3304
3305
                //$attendee = (string)$event->attendee;
3306
                /** @var Sabre\VObject\Property\ICalendar\Recur $repeat */
3307
                $repeat = $event->RRULE;
3308
                if ($id && !empty($repeat)) {
3309
                    $repeat = $repeat->getParts();
3310
                    $freq = $trans[$repeat['FREQ']];
3311
3312
                    if (isset($repeat['UNTIL']) && !empty($repeat['UNTIL'])) {
3313
                        // Check if datetime or just date (strlen == 8)
3314
                        if (strlen($repeat['UNTIL']) == 8) {
3315
                            // Fix the datetime format to avoid exception in the next step
3316
                            $repeat['UNTIL'] .= 'T000000';
3317
                        }
3318
                        $until = Sabre\VObject\DateTimeParser::parseDateTime(
3319
                            $repeat['UNTIL'],
3320
                            new DateTimeZone($currentTimeZone)
3321
                        );
3322
                        $until = $until->format('Y-m-d H:i:s');
3323
                        $this->addRepeatedItem(
3324
                            $id,
3325
                            $freq,
3326
                            $until,
3327
                            $sentTo
3328
                        );
3329
                    }
3330
3331
                    if (!empty($repeat['COUNT'])) {
3332
                        /*$count = $repeat['COUNT'];
3333
                        $interval = $repeat['INTERVAL'];
3334
                        $endDate = null;
3335
                        switch($freq) {
3336
                            case 'daily':
3337
                                $start = api_strtotime($startDateTime);
3338
                                $date = new DateTime($startDateTime);
3339
                                $days = $count * $interval;
3340
                                var_dump($days);
3341
                                $date->add(new DateInterval("P".$days."D"));
3342
                                $endDate = $date->format('Y-m-d H:i');
3343
                                //$endDate = $count *
3344
                                for ($i = 0; $i < $count; $i++) {
3345
                                    $days = 86400 * 7
3346
                                }
3347
                            }
3348
                        }*/
3349
                        //$res = agenda_add_repeat_item($courseInfo, $id, $freq, $count, $attendee);
3350
                        /*$this->addRepeatedItem(
3351
                            $id,
3352
                            $freq,
3353
                            $endDate,
3354
                            $sentTo
3355
                        );*/
3356
                    }
3357
                }
3358
            }
3359
        }
3360
3361
        if (!empty($messages)) {
3362
            $messages = implode('<br /> ', $messages);
3363
        } else {
3364
            $messages = get_lang('NoAgendaItems');
3365
        }
3366
3367
        return $messages;
3368
    }
3369
3370
    /**
3371
     * Parse filter turns USER:12 to ['users' => [12])] or G:1 ['groups' => [1]].
3372
     *
3373
     * @param int $filter
3374
     *
3375
     * @return array
3376
     */
3377
    public function parseAgendaFilter($filter)
3378
    {
3379
        $everyone = false;
3380
        $groupId = null;
3381
        $userId = null;
3382
3383
        if ($filter == 'everyone') {
3384
            $everyone = true;
3385
        } else {
3386
            if (substr($filter, 0, 1) == 'G') {
3387
                $groupId = str_replace('GROUP:', '', $filter);
3388
            } else {
3389
                $userId = str_replace('USER:', '', $filter);
3390
            }
3391
        }
3392
        if (empty($userId) && empty($groupId)) {
3393
            $everyone = true;
3394
        }
3395
3396
        return [
3397
            'everyone' => $everyone,
3398
            'users' => [$userId],
3399
            'groups' => [$groupId],
3400
        ];
3401
    }
3402
3403
    /**
3404
     *    This function retrieves all the agenda items of all the courses the user is subscribed to.
3405
     */
3406
    public static function get_myagendaitems(
3407
        $user_id,
3408
        $courses_dbs,
3409
        $month,
3410
        $year
3411
    ) {
3412
        $user_id = intval($user_id);
3413
3414
        $items = [];
3415
        $my_list = [];
3416
3417
        // get agenda-items for every course
3418
        foreach ($courses_dbs as $key => $array_course_info) {
3419
            //databases of the courses
3420
            $TABLEAGENDA = Database::get_course_table(TABLE_AGENDA);
3421
            $TABLE_ITEMPROPERTY = Database::get_course_table(
3422
                TABLE_ITEM_PROPERTY
3423
            );
3424
3425
            $group_memberships = GroupManager::get_group_ids(
3426
                $array_course_info['real_id'],
3427
                $user_id
3428
            );
3429
            $course_user_status = CourseManager::getUserInCourseStatus(
3430
                $user_id,
3431
                $array_course_info['real_id']
3432
            );
3433
            // if the user is administrator of that course we show all the agenda items
3434
            if ($course_user_status == '1') {
3435
                //echo "course admin";
3436
                $sqlquery = "SELECT DISTINCT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref
3437
							FROM ".$TABLEAGENDA." agenda,
3438
								 ".$TABLE_ITEMPROPERTY." ip
3439
							WHERE agenda.id = ip.ref
3440
							AND MONTH(agenda.start_date)='".$month."'
3441
							AND YEAR(agenda.start_date)='".$year."'
3442
							AND ip.tool='".TOOL_CALENDAR_EVENT."'
3443
							AND ip.visibility='1'
3444
							GROUP BY agenda.id
3445
							ORDER BY start_date ";
3446
            } else {
3447
                // if the user is not an administrator of that course
3448
                if (is_array($group_memberships) && count(
3449
                        $group_memberships
3450
                    ) > 0
3451
                ) {
3452
                    $sqlquery = "SELECT	agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref
3453
								FROM ".$TABLEAGENDA." agenda,
3454
									".$TABLE_ITEMPROPERTY." ip
3455
								WHERE agenda.id = ip.ref
3456
								AND MONTH(agenda.start_date)='".$month."'
3457
								AND YEAR(agenda.start_date)='".$year."'
3458
								AND ip.tool='".TOOL_CALENDAR_EVENT."'
3459
								AND	( ip.to_user_id='".$user_id."' OR (ip.to_group_id IS NULL OR ip.to_group_id IN (0, ".implode(
3460
                            ", ",
3461
                            $group_memberships
3462
                        ).")) )
3463
								AND ip.visibility='1'
3464
								ORDER BY start_date ";
3465
                } else {
3466
                    $sqlquery = "SELECT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref
3467
								FROM ".$TABLEAGENDA." agenda,
3468
									".$TABLE_ITEMPROPERTY." ip
3469
								WHERE agenda.id = ip.ref
3470
								AND MONTH(agenda.start_date)='".$month."'
3471
								AND YEAR(agenda.start_date)='".$year."'
3472
								AND ip.tool='".TOOL_CALENDAR_EVENT."'
3473
								AND ( ip.to_user_id='".$user_id."' OR ip.to_group_id='0' OR ip.to_group_id IS NULL)
3474
								AND ip.visibility='1'
3475
								ORDER BY start_date ";
3476
                }
3477
            }
3478
            $result = Database::query($sqlquery);
3479
3480
            while ($item = Database::fetch_array($result, 'ASSOC')) {
3481
                $agendaday = -1;
3482
                if (!empty($item['start_date'])) {
3483
                    $item['start_date'] = api_get_local_time(
3484
                        $item['start_date']
3485
                    );
3486
                    $item['start_date_tms'] = api_strtotime(
3487
                        $item['start_date']
3488
                    );
3489
                    $agendaday = date("j", $item['start_date_tms']);
3490
                }
3491
                if (!empty($item['end_date'])) {
3492
                    $item['end_date'] = api_get_local_time($item['end_date']);
3493
                }
3494
3495
                $url = api_get_path(
3496
                        WEB_CODE_PATH
3497
                    )."calendar/agenda.php?cidReq=".urlencode(
3498
                        $array_course_info["code"]
3499
                    )."&day=$agendaday&month=$month&year=$year#$agendaday";
3500
3501
                $item['url'] = $url;
3502
                $item['course_name'] = $array_course_info['title'];
3503
                $item['calendar_type'] = 'course';
3504
                $item['course_id'] = $array_course_info['course_id'];
3505
3506
                $my_list[$agendaday][] = $item;
3507
            }
3508
        }
3509
3510
        // sorting by hour for every day
3511
        $agendaitems = [];
3512
        foreach ($items as $agendaday => $tmpitems) {
3513
            if (!isset($agendaitems[$agendaday])) {
3514
                $agendaitems[$agendaday] = '';
3515
            }
3516
            sort($tmpitems);
3517
            foreach ($tmpitems as $val) {
3518
                $agendaitems[$agendaday] .= $val;
3519
            }
3520
        }
3521
3522
        return $my_list;
3523
    }
3524
3525
    /**
3526
     * This function retrieves one personal agenda item returns it.
3527
     *
3528
     * @param    array    The array containing existing events. We add to this array.
3529
     * @param    int        Day
3530
     * @param    int        Month
3531
     * @param    int        Year (4 digits)
3532
     * @param    int        Week number
3533
     * @param    string    Type of view (month_view, week_view, day_view)
3534
     *
3535
     * @return array The results of the database query, or null if not found
3536
     */
3537
    public static function get_global_agenda_items(
3538
        $agendaitems,
3539
        $day,
3540
        $month,
3541
        $year,
3542
        $week,
3543
        $type
3544
    ) {
3545
        $tbl_global_agenda = Database::get_main_table(
3546
            TABLE_MAIN_SYSTEM_CALENDAR
3547
        );
3548
        $month = intval($month);
3549
        $year = intval($year);
3550
        $week = intval($week);
3551
        $day = intval($day);
3552
        // 1. creating the SQL statement for getting the personal agenda items in MONTH view
3553
3554
        $current_access_url_id = api_get_current_access_url_id();
3555
3556
        if ($type == "month_view" || $type == "") {
3557
            // We are in month view
3558
            $sql = "SELECT * FROM ".$tbl_global_agenda."
3559
                    WHERE
3560
                        MONTH(start_date) = ".$month." AND
3561
                        YEAR(start_date) = ".$year."  AND
3562
                        access_url_id = $current_access_url_id
3563
                    ORDER BY start_date ASC";
3564
        }
3565
        // 2. creating the SQL statement for getting the personal agenda items in WEEK view
3566
        if ($type == "week_view") { // we are in week view
3567
            $start_end_day_of_week = self::calculate_start_end_of_week(
3568
                $week,
3569
                $year
3570
            );
3571
            $start_day = $start_end_day_of_week['start']['day'];
3572
            $start_month = $start_end_day_of_week['start']['month'];
3573
            $start_year = $start_end_day_of_week['start']['year'];
3574
            $end_day = $start_end_day_of_week['end']['day'];
3575
            $end_month = $start_end_day_of_week['end']['month'];
3576
            $end_year = $start_end_day_of_week['end']['year'];
3577
            // in sql statements you have to use year-month-day for date calculations
3578
            $start_filter = $start_year."-".$start_month."-".$start_day." 00:00:00";
3579
            $start_filter = api_get_utc_datetime($start_filter);
3580
3581
            $end_filter = $end_year."-".$end_month."-".$end_day." 23:59:59";
3582
            $end_filter = api_get_utc_datetime($end_filter);
3583
            $sql = " SELECT * FROM ".$tbl_global_agenda." WHERE start_date>='".$start_filter."' AND start_date<='".$end_filter."' AND  access_url_id = $current_access_url_id ";
3584
        }
3585
        // 3. creating the SQL statement for getting the personal agenda items in DAY view
3586
        if ($type == "day_view") { // we are in day view
3587
            // we could use mysql date() function but this is only available from 4.1 and higher
3588
            $start_filter = $year."-".$month."-".$day." 00:00:00";
3589
            $start_filter = api_get_utc_datetime($start_filter);
3590
3591
            $end_filter = $year."-".$month."-".$day." 23:59:59";
3592
            $end_filter = api_get_utc_datetime($end_filter);
3593
            $sql = " SELECT * FROM ".$tbl_global_agenda." WHERE start_date>='".$start_filter."' AND start_date<='".$end_filter."'  AND  access_url_id = $current_access_url_id";
3594
        }
3595
3596
        $result = Database::query($sql);
3597
3598
        while ($item = Database::fetch_array($result)) {
3599
            if (!empty($item['start_date'])) {
3600
                $item['start_date'] = api_get_local_time($item['start_date']);
3601
                $item['start_date_tms'] = api_strtotime($item['start_date']);
3602
            }
3603
            if (!empty($item['end_date'])) {
3604
                $item['end_date'] = api_get_local_time($item['end_date']);
3605
            }
3606
3607
            // we break the date field in the database into a date and a time part
3608
            $agenda_db_date = explode(" ", $item['start_date']);
3609
            $date = $agenda_db_date[0];
3610
            $time = $agenda_db_date[1];
3611
            // we divide the date part into a day, a month and a year
3612
            $agendadate = explode("-", $date);
3613
            $year = intval($agendadate[0]);
3614
            $month = intval($agendadate[1]);
3615
            $day = intval($agendadate[2]);
3616
            // we divide the time part into hour, minutes, seconds
3617
            $agendatime = explode(":", $time);
3618
            $hour = $agendatime[0];
3619
            $minute = $agendatime[1];
3620
            $second = $agendatime[2];
3621
3622
            if ($type == 'month_view') {
3623
                $item['calendar_type'] = 'global';
3624
                $agendaitems[$day][] = $item;
3625
                continue;
3626
            }
3627
3628
            $start_time = api_format_date(
3629
                $item['start_date'],
3630
                TIME_NO_SEC_FORMAT
3631
            );
3632
            $end_time = '';
3633
            if (!empty($item['end_date'])) {
3634
                $end_time = ' - '.api_format_date(
3635
                        $item['end_date'],
3636
                        DATE_TIME_FORMAT_LONG
3637
                    );
3638
            }
3639
3640
            // if the student has specified a course we a add a link to that course
3641
            if ($item['course'] != "") {
3642
                $url = api_get_path(
3643
                        WEB_CODE_PATH
3644
                    )."admin/agenda.php?cidReq=".urlencode(
3645
                        $item['course']
3646
                    )."&day=$day&month=$month&year=$year#$day"; // RH  //Patrick Cool: to highlight the relevant agenda item
3647
                $course_link = "<a href=\"$url\" title=\"".$item['course']."\">".$item['course']."</a>";
3648
            } else {
3649
                $course_link = "";
3650
            }
3651
            // Creating the array that will be returned. If we have week or month view we have an array with the date as the key
3652
            // if we have a day_view we use a half hour as index => key 33 = 16h30
3653
            if ($type !== "day_view") {
3654
                // This is the array construction for the WEEK or MONTH view
3655
                //Display the Agenda global in the tab agenda (administrator)
3656
                $agendaitems[$day] .= "<i>$start_time $end_time</i>&nbsp;-&nbsp;";
3657
                $agendaitems[$day] .= "<b>".get_lang('GlobalEvent')."</b>";
3658
                $agendaitems[$day] .= "<div>".$item['title']."</div><br>";
3659
            } else {
3660
                // this is the array construction for the DAY view
3661
                $halfhour = 2 * $agendatime['0'];
3662
                if ($agendatime['1'] >= '30') {
3663
                    $halfhour = $halfhour + 1;
3664
                }
3665
                if (!is_array($agendaitems[$halfhour])) {
3666
                    $content = $agendaitems[$halfhour];
3667
                }
3668
                $agendaitems[$halfhour] = $content."<div><i>$hour:$minute</i> <b>".get_lang(
3669
                        'GlobalEvent'
3670
                    ).":  </b>".$item['title']."</div>";
3671
            }
3672
        }
3673
3674
        return $agendaitems;
3675
    }
3676
3677
    /**
3678
     * This function retrieves all the personal agenda items and add them to the agenda items found by the other
3679
     * functions.
3680
     */
3681
    public static function get_personal_agenda_items(
3682
        $user_id,
3683
        $agendaitems,
3684
        $day,
3685
        $month,
3686
        $year,
3687
        $week,
3688
        $type
3689
    ) {
3690
        $tbl_personal_agenda = Database::get_main_table(TABLE_PERSONAL_AGENDA);
3691
        $user_id = intval($user_id);
3692
3693
        // 1. creating the SQL statement for getting the personal agenda items in MONTH view
3694
        if ($type === "month_view" || $type === "") {
3695
            // we are in month view
3696
            $sql = "SELECT * FROM $tbl_personal_agenda
3697
                    WHERE
3698
                        user='".$user_id."' AND
3699
                        MONTH(date)='".$month."' AND
3700
                        YEAR(date) = '".$year."'
3701
                     ORDER BY date ASC";
3702
        }
3703
3704
        // 2. creating the SQL statement for getting the personal agenda items in WEEK view
3705
        // we are in week view
3706
        if ($type == "week_view") {
3707
            $start_end_day_of_week = self::calculate_start_end_of_week(
3708
                $week,
3709
                $year
3710
            );
3711
            $start_day = $start_end_day_of_week['start']['day'];
3712
            $start_month = $start_end_day_of_week['start']['month'];
3713
            $start_year = $start_end_day_of_week['start']['year'];
3714
            $end_day = $start_end_day_of_week['end']['day'];
3715
            $end_month = $start_end_day_of_week['end']['month'];
3716
            $end_year = $start_end_day_of_week['end']['year'];
3717
            // in sql statements you have to use year-month-day for date calculations
3718
            $start_filter = $start_year."-".$start_month."-".$start_day." 00:00:00";
3719
            $start_filter = api_get_utc_datetime($start_filter);
3720
            $end_filter = $end_year."-".$end_month."-".$end_day." 23:59:59";
3721
            $end_filter = api_get_utc_datetime($end_filter);
3722
            $sql = " SELECT * FROM ".$tbl_personal_agenda." WHERE user='".$user_id."' AND date>='".$start_filter."' AND date<='".$end_filter."'";
3723
        }
3724
        // 3. creating the SQL statement for getting the personal agenda items in DAY view
3725
        if ($type == "day_view") {
3726
            // we are in day view
3727
            // we could use mysql date() function but this is only available from 4.1 and higher
3728
            $start_filter = $year."-".$month."-".$day." 00:00:00";
3729
            $start_filter = api_get_utc_datetime($start_filter);
3730
            $end_filter = $year."-".$month."-".$day." 23:59:59";
3731
            $end_filter = api_get_utc_datetime($end_filter);
3732
            $sql = " SELECT * FROM ".$tbl_personal_agenda." WHERE user='".$user_id."' AND date>='".$start_filter."' AND date<='".$end_filter."'";
3733
        }
3734
3735
        $result = Database::query($sql);
3736
        while ($item = Database::fetch_array($result, 'ASSOC')) {
3737
            $time_minute = api_convert_and_format_date(
3738
                $item['date'],
3739
                TIME_NO_SEC_FORMAT
3740
            );
3741
            $item['date'] = api_get_local_time($item['date']);
3742
            $item['start_date_tms'] = api_strtotime($item['date']);
3743
            $item['content'] = $item['text'];
3744
3745
            // we break the date field in the database into a date and a time part
3746
            $agenda_db_date = explode(" ", $item['date']);
3747
            $date = $agenda_db_date[0];
3748
            $time = $agenda_db_date[1];
3749
            // we divide the date part into a day, a month and a year
3750
            $agendadate = explode("-", $item['date']);
3751
            $year = intval($agendadate[0]);
3752
            $month = intval($agendadate[1]);
3753
            $day = intval($agendadate[2]);
3754
            // we divide the time part into hour, minutes, seconds
3755
            $agendatime = explode(":", $time);
3756
3757
            $hour = $agendatime[0];
3758
            $minute = $agendatime[1];
3759
            $second = $agendatime[2];
3760
3761
            if ($type == 'month_view') {
3762
                $item['calendar_type'] = 'personal';
3763
                $item['start_date'] = $item['date'];
3764
                $agendaitems[$day][] = $item;
3765
                continue;
3766
            }
3767
3768
            // if the student has specified a course we a add a link to that course
3769
            if ($item['course'] != "") {
3770
                $url = api_get_path(
3771
                        WEB_CODE_PATH
3772
                    )."calendar/agenda.php?cidReq=".urlencode(
3773
                        $item['course']
3774
                    )."&day=$day&month=$month&year=$year#$day"; // RH  //Patrick Cool: to highlight the relevant agenda item
3775
                $course_link = "<a href=\"$url\" title=\"".$item['course']."\">".$item['course']."</a>";
3776
            } else {
3777
                $course_link = "";
3778
            }
3779
            // Creating the array that will be returned. If we have week or month view we have an array with the date as the key
3780
            // if we have a day_view we use a half hour as index => key 33 = 16h30
3781
            if ($type !== "day_view") {
3782
                // This is the array construction for the WEEK or MONTH view
3783
3784
                //Display events in agenda
3785
                $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 />";
3786
            } else {
3787
                // this is the array construction for the DAY view
3788
                $halfhour = 2 * $agendatime['0'];
3789
                if ($agendatime['1'] >= '30') {
3790
                    $halfhour = $halfhour + 1;
3791
                }
3792
3793
                //Display events by list
3794
                $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>";
3795
            }
3796
        }
3797
3798
        return $agendaitems;
3799
    }
3800
3801
    /**
3802
     * Show the monthcalender of the given month.
3803
     *
3804
     * @param    array    Agendaitems
3805
     * @param    int    Month number
3806
     * @param    int    Year number
3807
     * @param    array    Array of strings containing long week day names (deprecated, you can send an empty array
3808
     *                          instead)
3809
     * @param    string    The month name
3810
     */
3811
    public static function display_mymonthcalendar(
3812
        $user_id,
3813
        $agendaitems,
3814
        $month,
3815
        $year,
3816
        $weekdaynames,
3817
        $monthName,
3818
        $show_content = true
3819
    ) {
3820
        global $DaysShort, $course_path;
3821
        //Handle leap year
3822
        $numberofdays = [
3823
            0,
3824
            31,
3825
            28,
3826
            31,
3827
            30,
3828
            31,
3829
            30,
3830
            31,
3831
            31,
3832
            30,
3833
            31,
3834
            30,
3835
            31,
3836
        ];
3837
        if (($year % 400 == 0) or ($year % 4 == 0 and $year % 100 != 0)) {
3838
            $numberofdays[2] = 29;
3839
        }
3840
        //Get the first day of the month
3841
        $dayone = getdate(mktime(0, 0, 0, $month, 1, $year));
3842
        //Start the week on monday
3843
        $startdayofweek = $dayone['wday'] != 0 ? ($dayone['wday'] - 1) : 6;
3844
        $g_cc = (isset($_GET['courseCode']) ? $_GET['courseCode'] : '');
3845
3846
        $next_month = ($month == 1 ? 12 : $month - 1);
3847
        $prev_month = ($month == 12 ? 1 : $month + 1);
3848
3849
        $next_year = ($month == 1 ? $year - 1 : $year);
3850
        $prev_year = ($month == 12 ? $year + 1 : $year);
3851
3852
        if ($show_content) {
3853
            $back_url = Display::url(
3854
                get_lang('Previous'),
3855
                api_get_self()."?coursePath=".urlencode(
3856
                    $course_path
3857
                )."&courseCode=".Security::remove_XSS(
3858
                    $g_cc
3859
                )."&action=view&view=month&month=".$next_month."&year=".$next_year
3860
            );
3861
            $next_url = Display::url(
3862
                get_lang('Next'),
3863
                api_get_self()."?coursePath=".urlencode(
3864
                    $course_path
3865
                )."&courseCode=".Security::remove_XSS(
3866
                    $g_cc
3867
                )."&action=view&view=month&month=".$prev_month."&year=".$prev_year
3868
            );
3869
        } else {
3870
            $back_url = Display::url(
3871
                get_lang('Previous'),
3872
                '',
3873
                [
3874
                    'onclick' => "load_calendar('".$user_id."','".$next_month."', '".$next_year."'); ",
3875
                    'class' => 'btn ui-button ui-widget ui-state-default',
3876
                ]
3877
            );
3878
            $next_url = Display::url(
3879
                get_lang('Next'),
3880
                '',
3881
                [
3882
                    'onclick' => "load_calendar('".$user_id."','".$prev_month."', '".$prev_year."'); ",
3883
                    'class' => 'pull-right btn ui-button ui-widget ui-state-default',
3884
                ]
3885
            );
3886
        }
3887
        $html = '';
3888
        $html .= '<div class="actions">';
3889
        $html .= '<div class="row">';
3890
        $html .= '<div class="col-md-4">'.$back_url.'</div>';
3891
        $html .= '<div class="col-md-4"><p class="agenda-title text-center">'.$monthName." ".$year.'</p></div>';
3892
        $html .= '<div class="col-md-4">'.$next_url.'</div>';
3893
        $html .= '</div>';
3894
        $html .= '</div>';
3895
        $html .= '<table id="agenda_list2" class="table table-bordered">';
3896
        $html .= '<tr>';
3897
        for ($ii = 1; $ii < 8; $ii++) {
3898
            $html .= '<td class="weekdays">'.$DaysShort[$ii % 7].'</td>';
3899
        }
3900
        $html .= '</tr>';
3901
3902
        $curday = -1;
3903
        $today = getdate();
3904
        while ($curday <= $numberofdays[$month]) {
3905
            $html .= "<tr>";
3906
            for ($ii = 0; $ii < 7; $ii++) {
3907
                if (($curday == -1) && ($ii == $startdayofweek)) {
3908
                    $curday = 1;
3909
                }
3910
                if (($curday > 0) && ($curday <= $numberofdays[$month])) {
3911
                    $bgcolor = $class = 'class="days_week"';
3912
                    $dayheader = Display::div(
3913
                        $curday,
3914
                        ['class' => 'agenda_day']
3915
                    );
3916
                    if (($curday == $today['mday']) && ($year == $today['year']) && ($month == $today['mon'])) {
3917
                        $class = "class=\"days_today\" style=\"width:10%;\"";
3918
                    }
3919
3920
                    $html .= "<td ".$class.">".$dayheader;
3921
3922
                    if (!empty($agendaitems[$curday])) {
3923
                        $items = $agendaitems[$curday];
3924
                        $items = msort($items, 'start_date_tms');
3925
3926
                        foreach ($items as $value) {
3927
                            $value['title'] = Security::remove_XSS(
3928
                                $value['title']
3929
                            );
3930
                            $start_time = api_format_date(
3931
                                $value['start_date'],
3932
                                TIME_NO_SEC_FORMAT
3933
                            );
3934
                            $end_time = '';
3935
3936
                            if (!empty($value['end_date'])) {
3937
                                $end_time = '-&nbsp;<i>'.api_format_date(
3938
                                        $value['end_date'],
3939
                                        DATE_TIME_FORMAT_LONG
3940
                                    ).'</i>';
3941
                            }
3942
                            $complete_time = '<i>'.api_format_date(
3943
                                    $value['start_date'],
3944
                                    DATE_TIME_FORMAT_LONG
3945
                                ).'</i>&nbsp;'.$end_time;
3946
                            $time = '<i>'.$start_time.'</i>';
3947
3948
                            switch ($value['calendar_type']) {
3949
                                case 'personal':
3950
                                    $bg_color = '#D0E7F4';
3951
                                    $icon = Display::return_icon(
3952
                                        'user.png',
3953
                                        get_lang('MyAgenda'),
3954
                                        [],
3955
                                        ICON_SIZE_SMALL
3956
                                    );
3957
                                    break;
3958
                                case 'global':
3959
                                    $bg_color = '#FFBC89';
3960
                                    $icon = Display::return_icon(
3961
                                        'view_remove.png',
3962
                                        get_lang('GlobalEvent'),
3963
                                        [],
3964
                                        ICON_SIZE_SMALL
3965
                                    );
3966
                                    break;
3967
                                case 'course':
3968
                                    $bg_color = '#CAFFAA';
3969
                                    $icon_name = 'course.png';
3970
                                    if (!empty($value['session_id'])) {
3971
                                        $icon_name = 'session.png';
3972
                                    }
3973
                                    if ($show_content) {
3974
                                        $icon = Display::url(
3975
                                            Display::return_icon(
3976
                                                $icon_name,
3977
                                                $value['course_name'].' '.get_lang(
3978
                                                    'Course'
3979
                                                ),
3980
                                                [],
3981
                                                ICON_SIZE_SMALL
3982
                                            ),
3983
                                            $value['url']
3984
                                        );
3985
                                    } else {
3986
                                        $icon = Display::return_icon(
3987
                                            $icon_name,
3988
                                            $value['course_name'].' '.get_lang(
3989
                                                'Course'
3990
                                            ),
3991
                                            [],
3992
                                            ICON_SIZE_SMALL
3993
                                        );
3994
                                    }
3995
                                    break;
3996
                                default:
3997
                                    break;
3998
                            }
3999
4000
                            $result = '<div class="rounded_div_agenda" style="background-color:'.$bg_color.';">';
4001
4002
                            if ($show_content) {
4003
                                //Setting a personal event to green
4004
                                $icon = Display::div(
4005
                                    $icon,
4006
                                    ['style' => 'float:right']
4007
                                );
4008
4009
                                $link = $value['calendar_type'].'_'.$value['id'].'_'.$value['course_id'].'_'.$value['session_id'];
4010
4011
                                //Link to bubble
4012
                                $url = Display::url(
4013
                                    cut($value['title'], 40),
4014
                                    '#',
4015
                                    ['id' => $link, 'class' => 'opener']
4016
                                );
4017
                                $result .= $time.' '.$icon.' '.Display::div(
4018
                                        $url
4019
                                    );
4020
4021
                                //Hidden content
4022
                                $content = Display::div(
4023
                                    $icon.Display::tag(
4024
                                        'h2',
4025
                                        $value['course_name']
4026
                                    ).'<hr />'.Display::tag(
4027
                                        'h3',
4028
                                        $value['title']
4029
                                    ).$complete_time.'<hr />'.Security::remove_XSS(
4030
                                        $value['content']
4031
                                    )
4032
                                );
4033
4034
                                //Main div
4035
                                $result .= Display::div(
4036
                                    $content,
4037
                                    [
4038
                                        'id' => 'main_'.$link,
4039
                                        'class' => 'dialog',
4040
                                        'style' => 'display:none',
4041
                                    ]
4042
                                );
4043
                                $result .= '</div>';
4044
                                $html .= $result;
4045
                            } else {
4046
                                $html .= $result .= $icon.'</div>';
4047
                            }
4048
                        }
4049
                    }
4050
                    $html .= "</td>";
4051
                    $curday++;
4052
                } else {
4053
                    $html .= "<td></td>";
4054
                }
4055
            }
4056
            $html .= "</tr>";
4057
        }
4058
        $html .= "</table>";
4059
        echo $html;
4060
    }
4061
4062
    /**
4063
     * Get personal agenda items between two dates (=all events from all registered courses).
4064
     *
4065
     * @param int $user_id user ID of the user
4066
     * @param    string    Optional start date in datetime format (if no start date is given, uses today)
4067
     * @param    string    Optional end date in datetime format (if no date is given, uses one year from now)
4068
     *
4069
     * @return array array of events ordered by start date, in
4070
     *               [0]('datestart','dateend','title'),[1]('datestart','dateend','title','link','coursetitle') format,
4071
     *               where datestart and dateend are in yyyyMMddhhmmss format
4072
     *
4073
     * @deprecated use agenda events
4074
     */
4075
    public static function get_personal_agenda_items_between_dates(
4076
        $user_id,
4077
        $date_start = '',
4078
        $date_end = ''
4079
    ) {
4080
        $items = [];
4081
        if ($user_id != strval(intval($user_id))) {
4082
            return $items;
4083
        }
4084
        if (empty($date_start)) {
4085
            $date_start = date('Y-m-d H:i:s');
4086
        }
4087
        if (empty($date_end)) {
4088
            $date_end = date(
4089
                'Y-m-d H:i:s',
4090
                mktime(0, 0, 0, date("m"), date("d"), date("Y") + 1)
4091
            );
4092
        }
4093
        $expr = '/\d{4}-\d{2}-\d{2}\ \d{2}:\d{2}:\d{2}/';
4094
        if (!preg_match($expr, $date_start)) {
4095
            return $items;
4096
        }
4097
        if (!preg_match($expr, $date_end)) {
4098
            return $items;
4099
        }
4100
4101
        // get agenda-items for every course
4102
        $courses = api_get_user_courses($user_id, false);
4103
        foreach ($courses as $id => $course) {
4104
            $c = api_get_course_info_by_id($course['real_id']);
4105
            //databases of the courses
4106
            $t_a = Database::get_course_table(TABLE_AGENDA, $course['db']);
4107
            $t_ip = Database::get_course_table(
4108
                TABLE_ITEM_PROPERTY,
4109
                $course['db']
4110
            );
4111
            // get the groups to which the user belong
4112
            $group_memberships = GroupManager:: get_group_ids(
4113
                $course['db'],
4114
                $user_id
4115
            );
4116
            // if the user is administrator of that course we show all the agenda items
4117
            if ($course['status'] == '1') {
4118
                //echo "course admin";
4119
                $sqlquery = "SELECT ".
4120
                    " DISTINCT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref ".
4121
                    " FROM ".$t_a." agenda, ".
4122
                    $t_ip." ip ".
4123
                    " WHERE agenda.id = ip.ref ".
4124
                    " AND agenda.start_date>='$date_start' ".
4125
                    " AND agenda.end_date<='$date_end' ".
4126
                    " AND ip.tool='".TOOL_CALENDAR_EVENT."' ".
4127
                    " AND ip.visibility='1' ".
4128
                    " GROUP BY agenda.id ".
4129
                    " ORDER BY start_date ";
4130
            } else {
4131
                // if the user is not an administrator of that course, then...
4132
                if (is_array($group_memberships) && count(
4133
                        $group_memberships
4134
                    ) > 0
4135
                ) {
4136
                    $sqlquery = "SELECT ".
4137
                        "DISTINCT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref ".
4138
                        " FROM ".$t_a." agenda, ".
4139
                        $t_ip." ip ".
4140
                        " WHERE agenda.id = ip.ref ".
4141
                        " AND agenda.start_date>='$date_start' ".
4142
                        " AND agenda.end_date<='$date_end' ".
4143
                        " AND ip.tool='".TOOL_CALENDAR_EVENT."' ".
4144
                        " AND	( ip.to_user_id='".$user_id."' OR (ip.to_group_id IS NULL OR ip.to_group_id IN (0, ".implode(
4145
                            ", ",
4146
                            $group_memberships
4147
                        ).")) ) ".
4148
                        " AND ip.visibility='1' ".
4149
                        " ORDER BY start_date ";
4150
                } else {
4151
                    $sqlquery = "SELECT ".
4152
                        "DISTINCT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref ".
4153
                        " FROM ".$t_a." agenda, ".
4154
                        $t_ip." ip ".
4155
                        " WHERE agenda.id = ip.ref ".
4156
                        " AND agenda.start_date>='$date_start' ".
4157
                        " AND agenda.end_date<='$date_end' ".
4158
                        " AND ip.tool='".TOOL_CALENDAR_EVENT."' ".
4159
                        " AND ( ip.to_user_id='".$user_id."' OR ip.to_group_id='0' OR ip.to_group_id IS NULL) ".
4160
                        " AND ip.visibility='1' ".
4161
                        " ORDER BY start_date ";
4162
                }
4163
            }
4164
4165
            $result = Database::query($sqlquery);
4166
            while ($item = Database::fetch_array($result)) {
4167
                $agendaday = date("j", strtotime($item['start_date']));
4168
                $month = date("n", strtotime($item['start_date']));
4169
                $year = date("Y", strtotime($item['start_date']));
4170
                $URL = api_get_path(
4171
                        WEB_PATH
4172
                    )."main/calendar/agenda.php?cidReq=".urlencode(
4173
                        $course["code"]
4174
                    )."&day=$agendaday&month=$month&year=$year#$agendaday";
4175
                list($year, $month, $day, $hour, $min, $sec) = explode(
4176
                    '[-: ]',
4177
                    $item['start_date']
4178
                );
4179
                $start_date = $year.$month.$day.$hour.$min;
4180
                list($year, $month, $day, $hour, $min, $sec) = explode(
4181
                    '[-: ]',
4182
                    $item['end_date']
4183
                );
4184
                $end_date = $year.$month.$day.$hour.$min;
4185
4186
                $items[] = [
4187
                    'datestart' => $start_date,
4188
                    'dateend' => $end_date,
4189
                    'title' => $item['title'],
4190
                    'link' => $URL,
4191
                    'coursetitle' => $c['name'],
4192
                ];
4193
            }
4194
        }
4195
4196
        return $items;
4197
    }
4198
4199
    /**
4200
     * This function calculates the startdate of the week (monday)
4201
     * and the enddate of the week (sunday)
4202
     * and returns it as an array.
4203
     */
4204
    public static function calculate_start_end_of_week($week_number, $year)
4205
    {
4206
        // determine the start and end date
4207
        // step 1: we calculate a timestamp for a day in this week
4208
        $random_day_in_week = mktime(
4209
                0,
4210
                0,
4211
                0,
4212
                1,
4213
                1,
4214
                $year
4215
            ) + ($week_number) * (7 * 24 * 60 * 60); // we calculate a random day in this week
4216
        // step 2: we which day this is (0=sunday, 1=monday, ...)
4217
        $number_day_in_week = date('w', $random_day_in_week);
4218
        // step 3: we calculate the timestamp of the monday of the week we are in
4219
        $start_timestamp = $random_day_in_week - (($number_day_in_week - 1) * 24 * 60 * 60);
4220
        // step 4: we calculate the timestamp of the sunday of the week we are in
4221
        $end_timestamp = $random_day_in_week + ((7 - $number_day_in_week + 1) * 24 * 60 * 60) - 3600;
4222
        // step 5: calculating the start_day, end_day, start_month, end_month, start_year, end_year
4223
        $start_day = date('j', $start_timestamp);
4224
        $start_month = date('n', $start_timestamp);
4225
        $start_year = date('Y', $start_timestamp);
4226
        $end_day = date('j', $end_timestamp);
4227
        $end_month = date('n', $end_timestamp);
4228
        $end_year = date('Y', $end_timestamp);
4229
        $start_end_array['start']['day'] = $start_day;
4230
        $start_end_array['start']['month'] = $start_month;
4231
        $start_end_array['start']['year'] = $start_year;
4232
        $start_end_array['end']['day'] = $end_day;
4233
        $start_end_array['end']['month'] = $end_month;
4234
        $start_end_array['end']['year'] = $end_year;
4235
4236
        return $start_end_array;
4237
    }
4238
4239
    /**
4240
     * @return bool
4241
     */
4242
    public function getIsAllowedToEdit()
4243
    {
4244
        return $this->isAllowedToEdit;
4245
    }
4246
4247
    /**
4248
     * @param bool $isAllowedToEdit
4249
     */
4250
    public function setIsAllowedToEdit($isAllowedToEdit)
4251
    {
4252
        $this->isAllowedToEdit = $isAllowedToEdit;
4253
    }
4254
4255
    /**
4256
     * Format needed for the Fullcalendar js lib.
4257
     *
4258
     * @param string $utcTime
4259
     *
4260
     * @return bool|string
4261
     */
4262
    public function formatEventDate($utcTime)
4263
    {
4264
        $utcTimeZone = new DateTimeZone('UTC');
4265
        $platformTimeZone = new DateTimeZone(api_get_timezone());
4266
4267
        $eventDate = new DateTime($utcTime, $utcTimeZone);
4268
        $eventDate->setTimezone($platformTimeZone);
4269
4270
        return $eventDate->format(DateTime::ISO8601);
4271
    }
4272
4273
    /**
4274
     * @throws \Doctrine\ORM\OptimisticLockException
4275
     * @throws \Doctrine\ORM\ORMException
4276
     * @throws \Doctrine\ORM\TransactionRequiredException
4277
     */
4278
    public static function saveCollectiveProperties(array $inviteeUserList, bool $isCollective, int $eventId)
4279
    {
4280
        $em = Database::getManager();
4281
4282
        $event = $em->find('ChamiloCoreBundle:PersonalAgenda', $eventId);
4283
4284
        $invitation = new AgendaEventInvitation();
4285
        $invitation->setCreator(api_get_user_entity(api_get_user_id()));
4286
4287
        $event
4288
            ->setCollective($isCollective)
4289
            ->setInvitation($invitation)
4290
        ;
4291
4292
        $em->persist($event);
4293
4294
        foreach ($inviteeUserList as $inviteeId) {
4295
            $invitee = new AgendaEventInvitee();
4296
            $invitee
4297
                ->setUser(api_get_user_entity($inviteeId))
4298
                ->setInvitation($invitation)
4299
            ;
4300
4301
            $em->persist($invitee);
4302
        }
4303
4304
        $em->flush();
4305
    }
4306
4307
    private static function isUserInvitedInEvent(int $id, int $userId): bool
4308
    {
4309
        $user = api_get_user_entity($userId);
4310
4311
        $event = Database::getManager()
4312
            ->getRepository('ChamiloCoreBundle:PersonalAgenda')
4313
            ->findOneByIdAndInvitee($id, $user)
4314
        ;
4315
4316
        return null !== $event;
4317
    }
4318
4319
    private function loadEventsAsInvitee(User $user, ?DateTime $startDate, ?DateTime $endDate)
4320
    {
4321
        $em = Database::getManager();
4322
        $eventRepo = $em->getRepository('ChamiloCoreBundle:PersonalAgenda');
4323
        $events = $eventRepo->getEventsForInvitee($user, $startDate, $endDate);
4324
4325
        foreach ($events as $event) {
4326
            $eventInfo = [];
4327
            $eventInfo['id'] = 'personal_'.$event->getId();
4328
            $eventInfo['title'] = $event->getTitle();
4329
            $eventInfo['className'] = 'personal';
4330
            $eventInfo['borderColor'] = $eventInfo['backgroundColor'] = $this->event_personal_color;
4331
            $eventInfo['editable'] = $event->isCollective();
4332
            $eventInfo['sent_to'] = get_lang('Me');
4333
            $eventInfo['type'] = 'personal';
4334
4335
            if ($event->getDate()) {
4336
                $eventInfo['start'] = $this->formatEventDate($event->getDate()->format('Y-m-d H:i:s'));
4337
                $eventInfo['start_date_localtime'] = api_get_local_time($event->getDate());
4338
            }
4339
4340
            if ($event->getEnddate()) {
4341
                $eventInfo['end'] = $this->formatEventDate($event->getEnddate()->format('Y-m-d H:i:s'));
4342
                $eventInfo['end_date_localtime'] = api_get_local_time($event->getEnddate());
4343
            }
4344
4345
            $eventInfo['description'] = $event->getText();
4346
            $eventInfo['allDay'] = $event->getAllDay();
4347
            $eventInfo['parent_event_id'] = 0;
4348
            $eventInfo['has_children'] = 0;
4349
            $eventInfo['collective'] = $event->isCollective();
4350
            $eventInfo['invitees'] = [];
4351
4352
            $invitation = $event->getInvitation();
4353
4354
            if ($invitation) {
4355
                foreach ($invitation->getInvitees() as $invitee) {
4356
                    $inviteeUser = $invitee->getUser();
4357
4358
                    $eventInfo['invitees'][] = [
4359
                        'id' => $inviteeUser->getId(),
4360
                        'name' => $inviteeUser->getCompleteNameWithUsername(),
4361
                    ];
4362
                }
4363
            }
4364
4365
            $this->events[] = $eventInfo;
4366
        }
4367
    }
4368
4369
    private function loadSessionsAsEvents(int $start, int $end)
4370
    {
4371
        if (false === api_get_configuration_value('personal_calendar_show_sessions_occupation')) {
4372
            return;
4373
        }
4374
4375
        $start = api_get_utc_datetime($start, false, true);
4376
        $end = api_get_utc_datetime($end, false, true);
4377
        $userInfo = api_get_user_info();
4378
        $sessionList = SessionManager::getSessionsFollowedByUser($userInfo['id'], $userInfo['status']);
4379
4380
        foreach ($sessionList as $sessionInfo) {
4381
            if (!empty($sessionInfo['duration'])) {
4382
                $courseAccess = CourseManager::getFirstCourseAccessPerSessionAndUser(
4383
                    $sessionInfo['session_id'],
4384
                    $userInfo['id']
4385
                );
4386
4387
                if (empty($courseAccess)) {
4388
                    continue;
4389
                }
4390
4391
                $firstAccessDate = new DateTime($courseAccess['login_course_date'], new DateTimeZone('UTC'));
4392
                $lastAccessDate = clone $firstAccessDate;
4393
                $lastAccessDate->modify('+'.$sessionInfo['duration'].' days');
4394
4395
                if ($firstAccessDate->format('Y-m-d H:i:s') > $start
4396
                    && $lastAccessDate->format('Y-m-d H:i:s') < $end
4397
                ) {
4398
                    continue;
4399
                }
4400
4401
                $courseList = SessionManager::get_course_list_by_session_id($sessionInfo['id']);
4402
                $firstCourse = current($courseList);
4403
4404
                $this->events[] = [
4405
                    'id' => 'session_'.$sessionInfo['id'],
4406
                    'session_id' => $sessionInfo['id'],
4407
                    'title' => $sessionInfo['name'],
4408
                    'description' => $sessionInfo['show_description'] ? $sessionInfo['description'] : '',
4409
                    'className' => 'personal',
4410
                    'borderColor' => $this->event_personal_color,
4411
                    'backgroundColor' => $this->event_personal_color,
4412
                    'editable' => false,
4413
                    'sent_to' => get_lang('Me'),
4414
                    'type' => 'session',
4415
                    'start' => $firstAccessDate->format(DateTime::ISO8601),
4416
                    'start_date_localtime' => api_get_local_time($firstAccessDate),
4417
                    'end' => $lastAccessDate->format(DateTime::ISO8601),
4418
                    'end_date_localtime' => api_get_local_time($lastAccessDate),
4419
                    'allDay' => 0,
4420
                    'parent_event_id' => 0,
4421
                    'has_children' => 0,
4422
                    'course_url' => api_get_course_url($firstCourse['code'], $sessionInfo['id']),
4423
                ];
4424
4425
                continue;
4426
            }
4427
4428
            if ($sessionInfo['display_start_date'] < $start
4429
                && $sessionInfo['display_end_date'] > $end
4430
            ) {
4431
                continue;
4432
            }
4433
4434
            $courseList = SessionManager::get_course_list_by_session_id($sessionInfo['id']);
4435
            $firstCourse = current($courseList);
4436
4437
            $this->events[] = [
4438
                'id' => 'session_'.$sessionInfo['id'],
4439
                'session_id' => $sessionInfo['id'],
4440
                'title' => $sessionInfo['name'],
4441
                'description' => $sessionInfo['show_description'] ? $sessionInfo['description'] : '',
4442
                'className' => 'personal',
4443
                'borderColor' => $this->event_personal_color,
4444
                'backgroundColor' => $this->event_personal_color,
4445
                'editable' => false,
4446
                'sent_to' => get_lang('Me'),
4447
                'type' => 'session',
4448
                'start' => $sessionInfo['display_start_date'],
4449
                'start_date_localtime' => $sessionInfo['display_start_date']
4450
                    ? $this->formatEventDate($sessionInfo['display_start_date'])
4451
                    : '',
4452
                'end' => $sessionInfo['display_end_date'],
4453
                'end_date_localtime' => $sessionInfo['display_end_date']
4454
                    ? $this->formatEventDate($sessionInfo['display_end_date'])
4455
                    : '',
4456
                'allDay' => 0,
4457
                'parent_event_id' => 0,
4458
                'has_children' => 0,
4459
                'course_url' => api_get_course_url($firstCourse['code'], $sessionInfo['id']),
4460
            ];
4461
        }
4462
    }
4463
}
4464