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

Agenda::addEvent()   F

Complexity

Conditions 22
Paths 612

Size

Total Lines 211
Code Lines 145

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 22
eloc 145
nc 612
nop 12
dl 0
loc 211
rs 0.4311
c 0
b 0
f 0

How to fix   Long Method    Complexity    Many Parameters   

Long Method

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

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

Commonly applied refactorings include:

Many Parameters

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

There are several approaches to avoid long parameter lists:

1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
use Chamilo\CoreBundle\Entity\AgendaEventInvitation;
6
use Chamilo\CoreBundle\Entity\AgendaEventInvitee;
7
use Chamilo\UserBundle\Entity\User;
8
9
/**
10
 * Class Agenda.
11
 *
12
 * @author: Julio Montoya <[email protected]>
13
 */
14
class Agenda
15
{
16
    public $events = [];
17
    /** @var string Current type */
18
    public $type = 'personal';
19
    public $types = ['personal', 'admin', 'course'];
20
    public $sessionId = 0;
21
    public $senderId;
22
    /** @var array */
23
    public $course;
24
    /** @var string */
25
    public $comment;
26
    public $eventStudentPublicationColor;
27
    /** @var array */
28
    private $sessionInfo;
29
    /** @var bool */
30
    private $isAllowedToEdit;
31
32
    /**
33
     * Constructor.
34
     *
35
     * @param string $type
36
     * @param int    $senderId  Optional The user sender ID
37
     * @param int    $courseId  Optional. The course ID
38
     * @param int    $sessionId Optional The session ID
39
     */
40
    public function __construct(
41
        $type,
42
        $senderId = 0,
43
        $courseId = 0,
44
        $sessionId = 0
45
    ) {
46
        // Table definitions
47
        $this->tbl_global_agenda = Database::get_main_table(TABLE_MAIN_SYSTEM_CALENDAR);
48
        $this->tbl_personal_agenda = Database::get_main_table(TABLE_PERSONAL_AGENDA);
49
        $this->tbl_course_agenda = Database::get_course_table(TABLE_AGENDA);
50
        $this->table_repeat = Database::get_course_table(TABLE_AGENDA_REPEAT);
51
52
        $this->setType($type);
53
        $this->setSenderId($senderId ?: api_get_user_id());
54
        $isAllowToEdit = false;
55
56
        switch ($type) {
57
            case 'course':
58
                $sessionId = $sessionId ?: api_get_session_id();
59
                $sessionInfo = api_get_session_info($sessionId);
60
                $this->setSessionId($sessionId);
61
                $this->setSessionInfo($sessionInfo);
62
63
                // Setting the course object if we are in a course
64
                $courseInfo = api_get_course_info_by_id($courseId);
65
                if (!empty($courseInfo)) {
66
                    $this->set_course($courseInfo);
67
                }
68
69
                // Check if teacher/admin rights.
70
                $isAllowToEdit = api_is_allowed_to_edit(false, true);
71
                // Check course setting.
72
                if (api_get_course_setting('allow_user_edit_agenda') == '1'
73
                    && api_is_allowed_in_course()
74
                ) {
75
                    $isAllowToEdit = true;
76
                }
77
78
                $groupId = api_get_group_id();
79
                if (!empty($groupId)) {
80
                    $groupInfo = GroupManager::get_group_properties($groupId);
81
                    $userHasAccess = GroupManager::user_has_access(
82
                        api_get_user_id(),
83
                        $groupInfo['iid'],
84
                        GroupManager::GROUP_TOOL_CALENDAR
85
                    );
86
                    $isTutor = GroupManager::is_tutor_of_group(
87
                        api_get_user_id(),
88
                        $groupInfo
89
                    );
90
91
                    $isGroupAccess = $userHasAccess || $isTutor;
92
                    $isAllowToEdit = false;
93
                    if ($isGroupAccess) {
94
                        $isAllowToEdit = true;
95
                    }
96
                }
97
98
                if (false === $isAllowToEdit && !empty($sessionId)) {
99
                    $allowDhrToEdit = api_get_configuration_value('allow_agenda_edit_for_hrm');
100
                    if ($allowDhrToEdit) {
101
                        $isHrm = SessionManager::isUserSubscribedAsHRM($sessionId, api_get_user_id());
102
                        if ($isHrm) {
103
                            $isAllowToEdit = true;
104
                        }
105
                    }
106
                }
107
                break;
108
            case 'admin':
109
                $isAllowToEdit = api_is_platform_admin();
110
                break;
111
            case 'personal':
112
                $isAllowToEdit = !api_is_anonymous();
113
                break;
114
        }
115
116
        $this->setIsAllowedToEdit($isAllowToEdit);
117
        $this->events = [];
118
        $agendaColors = array_merge(
119
            [
120
                'platform' => 'red', //red
121
                'course' => '#458B00', //green
122
                'group' => '#A0522D', //siena
123
                'session' => '#00496D', // kind of green
124
                'other_session' => '#999', // kind of green
125
                'personal' => 'steel blue', //steel blue
126
                'student_publication' => '#FF8C00', //DarkOrange
127
            ],
128
            api_get_configuration_value('agenda_colors') ?: []
129
        );
130
131
        // Event colors
132
        $this->event_platform_color = $agendaColors['platform'];
133
        $this->event_course_color = $agendaColors['course'];
134
        $this->event_group_color = $agendaColors['group'];
135
        $this->event_session_color = $agendaColors['session'];
136
        $this->eventOtherSessionColor = $agendaColors['other_session'];
137
        $this->event_personal_color = $agendaColors['personal'];
138
        $this->eventStudentPublicationColor = $agendaColors['student_publication'];
139
    }
140
141
    /**
142
     * @param int $senderId
143
     */
144
    public function setSenderId($senderId)
145
    {
146
        $this->senderId = (int) $senderId;
147
    }
148
149
    /**
150
     * @return int
151
     */
152
    public function getSenderId()
153
    {
154
        return $this->senderId;
155
    }
156
157
    /**
158
     * @param string $type can be 'personal', 'admin'  or  'course'
159
     */
160
    public function setType($type)
161
    {
162
        $type = (string) trim($type);
163
        $typeList = $this->getTypes();
164
        if (in_array($type, $typeList, true)) {
165
            $this->type = $type;
166
        }
167
    }
168
169
    /**
170
     * Returns the type previously set (and filtered) through setType
171
     * If setType() was not called, then type defaults to "personal" as
172
     * set in the class definition.
173
     */
174
    public function getType()
175
    {
176
        if (isset($this->type)) {
177
            return $this->type;
178
        }
179
    }
180
181
    /**
182
     * @param int $id
183
     */
184
    public function setSessionId($id)
185
    {
186
        $this->sessionId = (int) $id;
187
    }
188
189
    /**
190
     * @param array $sessionInfo
191
     */
192
    public function setSessionInfo($sessionInfo)
193
    {
194
        $this->sessionInfo = $sessionInfo;
195
    }
196
197
    /**
198
     * @return int $id
199
     */
200
    public function getSessionId()
201
    {
202
        return $this->sessionId;
203
    }
204
205
    /**
206
     * @param array $courseInfo
207
     */
208
    public function set_course($courseInfo)
209
    {
210
        $this->course = $courseInfo;
211
    }
212
213
    /**
214
     * @return array
215
     */
216
    public function getTypes()
217
    {
218
        return $this->types;
219
    }
220
221
    /**
222
     * Adds an event to the calendar.
223
     *
224
     * @param string $start                 datetime format: 2012-06-14 09:00:00 in local time
225
     * @param string $end                   datetime format: 2012-06-14 09:00:00 in local time
226
     * @param string $allDay                (true, false)
227
     * @param string $title
228
     * @param string $content
229
     * @param array  $usersToSend           array('everyone') or a list of user/group ids
230
     * @param bool   $addAsAnnouncement     event as a *course* announcement
231
     * @param int    $parentEventId
232
     * @param array  $attachmentArray       array of $_FILES['']
233
     * @param array  $attachmentCommentList
234
     * @param string $eventComment
235
     * @param string $color
236
     *
237
     * @return int
238
     */
239
    public function addEvent(
240
        $start,
241
        $end,
242
        $allDay,
243
        $title,
244
        $content,
245
        $usersToSend = [],
246
        $addAsAnnouncement = false,
247
        $parentEventId = null,
248
        $attachmentArray = [],
249
        $attachmentCommentList = [],
250
        $eventComment = null,
251
        $color = ''
252
    ) {
253
        $start = api_get_utc_datetime($start);
254
        $end = api_get_utc_datetime($end);
255
        $allDay = isset($allDay) && ($allDay === 'true' || $allDay == 1) ? 1 : 0;
256
        $id = null;
257
258
        switch ($this->type) {
259
            case 'personal':
260
                $attributes = [
261
                    'user' => api_get_user_id(),
262
                    'title' => $title,
263
                    'text' => $content,
264
                    'date' => $start,
265
                    'enddate' => $end,
266
                    'all_day' => $allDay,
267
                    'color' => $color,
268
                ];
269
270
                $id = Database::insert(
271
                    $this->tbl_personal_agenda,
272
                    $attributes
273
                );
274
                break;
275
            case 'course':
276
                $attributes = [
277
                    'title' => $title,
278
                    'content' => $content,
279
                    'start_date' => $start,
280
                    'end_date' => $end,
281
                    'all_day' => $allDay,
282
                    'session_id' => $this->getSessionId(),
283
                    'c_id' => $this->course['real_id'],
284
                    'comment' => $eventComment,
285
                    'color' => $color,
286
                ];
287
288
                if (!empty($parentEventId)) {
289
                    $attributes['parent_event_id'] = $parentEventId;
290
                }
291
292
                $senderId = $this->getSenderId();
293
                $sessionId = $this->getSessionId();
294
295
                // Simple course event.
296
                $id = Database::insert($this->tbl_course_agenda, $attributes);
297
298
                if ($id) {
299
                    $sql = "UPDATE ".$this->tbl_course_agenda." SET id = iid WHERE iid = $id";
300
                    Database::query($sql);
301
302
                    $groupId = api_get_group_id();
303
                    $groupInfo = [];
304
                    if ($groupId) {
305
                        $groupInfo = GroupManager::get_group_properties(
306
                            $groupId
307
                        );
308
                    }
309
310
                    if (!empty($usersToSend)) {
311
                        $sendTo = $this->parseSendToArray($usersToSend);
312
                        if ($sendTo['everyone']) {
313
                            api_item_property_update(
314
                                $this->course,
315
                                TOOL_CALENDAR_EVENT,
316
                                $id,
317
                                'AgendaAdded',
318
                                $senderId,
319
                                $groupInfo,
320
                                '',
321
                                $start,
322
                                $end,
323
                                $sessionId
324
                            );
325
                            api_item_property_update(
326
                                $this->course,
327
                                TOOL_CALENDAR_EVENT,
328
                                $id,
329
                                'visible',
330
                                $senderId,
331
                                $groupInfo,
332
                                '',
333
                                $start,
334
                                $end,
335
                                $sessionId
336
                            );
337
                        } else {
338
                            // Storing the selected groups
339
                            if (!empty($sendTo['groups'])) {
340
                                foreach ($sendTo['groups'] as $group) {
341
                                    $groupInfoItem = [];
342
                                    if ($group) {
343
                                        $groupInfoItem = GroupManager::get_group_properties($group);
344
                                    }
345
346
                                    api_item_property_update(
347
                                        $this->course,
348
                                        TOOL_CALENDAR_EVENT,
349
                                        $id,
350
                                        'AgendaAdded',
351
                                        $senderId,
352
                                        $groupInfoItem,
353
                                        0,
354
                                        $start,
355
                                        $end,
356
                                        $sessionId
357
                                    );
358
359
                                    api_item_property_update(
360
                                        $this->course,
361
                                        TOOL_CALENDAR_EVENT,
362
                                        $id,
363
                                        'visible',
364
                                        $senderId,
365
                                        $groupInfoItem,
366
                                        0,
367
                                        $start,
368
                                        $end,
369
                                        $sessionId
370
                                    );
371
                                }
372
                            }
373
374
                            // storing the selected users
375
                            if (!empty($sendTo['users'])) {
376
                                foreach ($sendTo['users'] as $userId) {
377
                                    api_item_property_update(
378
                                        $this->course,
379
                                        TOOL_CALENDAR_EVENT,
380
                                        $id,
381
                                        'AgendaAdded',
382
                                        $senderId,
383
                                        $groupInfo,
384
                                        $userId,
385
                                        $start,
386
                                        $end,
387
                                        $sessionId
388
                                    );
389
390
                                    api_item_property_update(
391
                                        $this->course,
392
                                        TOOL_CALENDAR_EVENT,
393
                                        $id,
394
                                        'visible',
395
                                        $senderId,
396
                                        $groupInfo,
397
                                        $userId,
398
                                        $start,
399
                                        $end,
400
                                        $sessionId
401
                                    );
402
                                }
403
                            }
404
                        }
405
                    }
406
407
                    // Add announcement.
408
                    if ($addAsAnnouncement) {
409
                        $this->storeAgendaEventAsAnnouncement(
410
                            $id,
411
                            $usersToSend
412
                        );
413
                    }
414
415
                    // Add attachment.
416
                    if (isset($attachmentArray) && !empty($attachmentArray)) {
417
                        $counter = 0;
418
                        foreach ($attachmentArray as $attachmentItem) {
419
                            $this->addAttachment(
420
                                $id,
421
                                $attachmentItem,
422
                                $attachmentCommentList[$counter],
423
                                $this->course
424
                            );
425
                            $counter++;
426
                        }
427
                    }
428
                }
429
                break;
430
            case 'admin':
431
                if (api_is_platform_admin()) {
432
                    $attributes = [
433
                        'title' => $title,
434
                        'content' => $content,
435
                        'start_date' => $start,
436
                        'end_date' => $end,
437
                        'all_day' => $allDay,
438
                        'access_url_id' => api_get_current_access_url_id(),
439
                    ];
440
441
                    $id = Database::insert(
442
                        $this->tbl_global_agenda,
443
                        $attributes
444
                    );
445
                }
446
                break;
447
        }
448
449
        return $id;
450
    }
451
452
    /**
453
     * @param int $eventId
454
     * @param int $courseId
455
     *
456
     * @return array
457
     */
458
    public function getRepeatedInfoByEvent($eventId, $courseId)
459
    {
460
        $repeatTable = Database::get_course_table(TABLE_AGENDA_REPEAT);
461
        $eventId = (int) $eventId;
462
        $courseId = (int) $courseId;
463
        $sql = "SELECT * FROM $repeatTable
464
                WHERE c_id = $courseId AND cal_id = $eventId";
465
        $res = Database::query($sql);
466
        $repeatInfo = [];
467
        if (Database::num_rows($res) > 0) {
468
            $repeatInfo = Database::fetch_array($res, 'ASSOC');
469
        }
470
471
        return $repeatInfo;
472
    }
473
474
    /**
475
     * @param string $type
476
     * @param string $startEvent      in UTC
477
     * @param string $endEvent        in UTC
478
     * @param string $repeatUntilDate in UTC
479
     *
480
     * @throws Exception
481
     *
482
     * @return array with local times
483
     */
484
    public function generateDatesByType($type, $startEvent, $endEvent, $repeatUntilDate)
485
    {
486
        $continue = true;
487
        $repeatUntilDate = new DateTime($repeatUntilDate, new DateTimeZone('UTC'));
488
        $loopMax = 365;
489
        $counter = 0;
490
        $list = [];
491
492
        switch ($type) {
493
            case 'daily':
494
                $interval = 'P1D';
495
                break;
496
            case 'weekly':
497
                $interval = 'P1W';
498
                break;
499
            case 'monthlyByDate':
500
                $interval = 'P1M';
501
                break;
502
            case 'monthlyByDay':
503
                // not yet implemented
504
                break;
505
            case 'monthlyByDayR':
506
                // not yet implemented
507
                break;
508
            case 'yearly':
509
                $interval = 'P1Y';
510
                break;
511
        }
512
513
        if (empty($interval)) {
514
            return [];
515
        }
516
        $timeZone = api_get_timezone();
517
518
        while ($continue) {
519
            $startDate = new DateTime($startEvent, new DateTimeZone('UTC'));
520
            $endDate = new DateTime($endEvent, new DateTimeZone('UTC'));
521
522
            $startDate->add(new DateInterval($interval));
523
            $endDate->add(new DateInterval($interval));
524
525
            $newStartDate = $startDate->format('Y-m-d H:i:s');
526
            $newEndDate = $endDate->format('Y-m-d H:i:s');
527
528
            $startEvent = $newStartDate;
529
            $endEvent = $newEndDate;
530
531
            if ($endDate > $repeatUntilDate) {
532
                break;
533
            }
534
535
            // @todo remove comment code
536
            // The code below was not adpating to saving light time but was doubling the difference with UTC time.
537
            // Might be necessary to adapt to update saving light time difference.
538
            /*            $startDateInLocal = new DateTime($newStartDate, new DateTimeZone($timeZone));
539
                        if ($startDateInLocal->format('I') == 0) {
540
                            // Is saving time? Then fix UTC time to add time
541
                            $seconds = $startDateInLocal->getOffset();
542
                            $startDate->add(new DateInterval("PT".$seconds."S"));
543
                            //$startDateFixed = $startDate->format('Y-m-d H:i:s');
544
                            //$startDateInLocalFixed = new DateTime($startDateFixed, new DateTimeZone($timeZone));
545
                            //$newStartDate = $startDateInLocalFixed->format('Y-m-d H:i:s');
546
                            //$newStartDate = $startDate->setTimezone(new DateTimeZone($timeZone))->format('Y-m-d H:i:s');
547
                        }
548
549
                        $endDateInLocal = new DateTime($newEndDate, new DateTimeZone($timeZone));
550
                        if ($endDateInLocal->format('I') == 0) {
551
                            // Is saving time? Then fix UTC time to add time
552
                            $seconds = $endDateInLocal->getOffset();
553
                            $endDate->add(new DateInterval("PT".$seconds."S"));
554
                            //$endDateFixed = $endDate->format('Y-m-d H:i:s');
555
                            //$endDateInLocalFixed = new DateTime($endDateFixed, new DateTimeZone($timeZone));
556
                            //$newEndDate = $endDateInLocalFixed->format('Y-m-d H:i:s');
557
                    }
558
            */
559
            $newStartDate = $startDate->setTimezone(new DateTimeZone($timeZone))->format('Y-m-d H:i:s');
560
            $newEndDate = $endDate->setTimezone(new DateTimeZone($timeZone))->format('Y-m-d H:i:s');
561
            $list[] = ['start' => $newStartDate, 'end' => $newEndDate];
562
            $counter++;
563
564
            // just in case stop if more than $loopMax
565
            if ($counter > $loopMax) {
566
                break;
567
            }
568
        }
569
570
        return $list;
571
    }
572
573
    /**
574
     * @param int    $eventId
575
     * @param string $type
576
     * @param string $end     in UTC
577
     * @param array  $sentTo
578
     *
579
     * @return bool
580
     */
581
    public function addRepeatedItem($eventId, $type, $end, $sentTo = [])
582
    {
583
        $t_agenda = Database::get_course_table(TABLE_AGENDA);
584
        $t_agenda_r = Database::get_course_table(TABLE_AGENDA_REPEAT);
585
586
        if (empty($this->course)) {
587
            return false;
588
        }
589
590
        $courseId = $this->course['real_id'];
591
        $eventId = (int) $eventId;
592
593
        $sql = "SELECT title, content, start_date, end_date, all_day
594
                FROM $t_agenda
595
                WHERE c_id = $courseId AND id = $eventId";
596
        $res = Database::query($sql);
597
598
        if (Database::num_rows($res) !== 1) {
599
            return false;
600
        }
601
602
        $typeList = [
603
            'daily',
604
            'weekly',
605
            'monthlyByDate',
606
            'monthlyByDay',
607
            'monthlyByDayR',
608
            'yearly',
609
        ];
610
611
        if (!in_array($type, $typeList)) {
612
            return false;
613
        }
614
615
        $now = time();
616
617
        // The event has to repeat *in the future*. We don't allow repeated
618
        // events in the past.
619
        $endTimeStamp = api_strtotime($end, 'UTC');
620
621
        if ($endTimeStamp < $now) {
622
            return false;
623
        }
624
625
        $row = Database::fetch_array($res);
626
627
        $title = $row['title'];
628
        $content = $row['content'];
629
        $allDay = $row['all_day'];
630
631
        $type = Database::escape_string($type);
632
        $end = Database::escape_string($end);
633
634
        $sql = "INSERT INTO $t_agenda_r (c_id, cal_id, cal_type, cal_end)
635
                VALUES ($courseId, '$eventId', '$type', '$endTimeStamp')";
636
        Database::query($sql);
637
638
        $generatedDates = $this->generateDatesByType($type, $row['start_date'], $row['end_date'], $end);
639
640
        if (empty($generatedDates)) {
641
            return false;
642
        }
643
644
        foreach ($generatedDates as $dateInfo) {
645
//            $start = api_get_local_time($dateInfo['start']);
646
//            $end = api_get_local_time($dateInfo['end']);
647
            // On line 529 in function generateDatesByType there is a @todo remove comment code
648
            // just before the part updating the date in local time so keep both synchronised
649
            $start = $dateInfo['start'];
650
            $end = $dateInfo['end'];
651
652
            $this->addEvent(
653
                $start,
654
                $end,
655
                $allDay,
656
                $title,
657
                $content,
658
                $sentTo,
659
                false,
660
                $eventId
661
            );
662
        }
663
664
        return true;
665
    }
666
667
    /**
668
     * @param int   $item_id
669
     * @param array $sentTo
670
     *
671
     * @return int
672
     */
673
    public function storeAgendaEventAsAnnouncement($item_id, $sentTo = [])
674
    {
675
        $table_agenda = Database::get_course_table(TABLE_AGENDA);
676
        $courseId = api_get_course_int_id();
677
678
        // Check params
679
        if (empty($item_id) || $item_id != strval(intval($item_id))) {
680
            return -1;
681
        }
682
683
        // Get the agenda item.
684
        $item_id = intval($item_id);
685
        $sql = "SELECT * FROM $table_agenda
686
                WHERE c_id = $courseId AND id = ".$item_id;
687
        $res = Database::query($sql);
688
689
        if (Database::num_rows($res) > 0) {
690
            $row = Database::fetch_array($res, 'ASSOC');
691
692
            // Sending announcement
693
            if (!empty($sentTo)) {
694
                $id = AnnouncementManager::add_announcement(
695
                    api_get_course_info(),
696
                    api_get_session_id(),
697
                    $row['title'],
698
                    $row['content'],
699
                    $sentTo,
700
                    null,
701
                    null,
702
                    $row['end_date']
703
                );
704
705
                AnnouncementManager::sendEmail(
706
                    api_get_course_info(),
707
                    api_get_session_id(),
708
                    $id
709
                );
710
711
                return $id;
712
            }
713
        }
714
715
        return -1;
716
    }
717
718
    /**
719
     * Edits an event.
720
     *
721
     * @param int    $id
722
     * @param string $start                 datetime format: 2012-06-14 09:00:00
723
     * @param string $end                   datetime format: 2012-06-14 09:00:00
724
     * @param int    $allDay                is all day 'true' or 'false'
725
     * @param string $title
726
     * @param string $content
727
     * @param array  $usersToSend
728
     * @param array  $attachmentArray
729
     * @param array  $attachmentCommentList
730
     * @param string $comment
731
     * @param string $color
732
     * @param bool   $addAnnouncement
733
     * @param bool   $updateContent
734
     * @param int    $authorId
735
     *
736
     * @return bool
737
     */
738
    public function editEvent(
739
        $id,
740
        $start,
741
        $end,
742
        $allDay,
743
        $title,
744
        $content,
745
        $usersToSend = [],
746
        $attachmentArray = [],
747
        $attachmentCommentList = [],
748
        $comment = null,
749
        $color = '',
750
        $addAnnouncement = false,
751
        $updateContent = true,
752
        $authorId = 0
753
    ) {
754
        $id = (int) $id;
755
        $start = api_get_utc_datetime($start);
756
        $end = api_get_utc_datetime($end);
757
        $allDay = isset($allDay) && $allDay == 'true' ? 1 : 0;
758
        $currentUserId = api_get_user_id();
759
        $authorId = empty($authorId) ? $currentUserId : (int) $authorId;
760
761
        switch ($this->type) {
762
            case 'personal':
763
                $eventInfo = $this->get_event($id);
764
                if ($eventInfo['user'] != $currentUserId
765
                    && (
766
                        api_get_configuration_value('agenda_collective_invitations')
767
                            && !self::isUserInvitedInEvent($id, $currentUserId)
768
                    )
769
                ) {
770
                    break;
771
                }
772
                $attributes = [
773
                    'title' => $title,
774
                    'date' => $start,
775
                    'enddate' => $end,
776
                    'all_day' => $allDay,
777
                ];
778
779
                if ($updateContent) {
780
                    $attributes['text'] = $content;
781
                }
782
783
                if (!empty($color)) {
784
                    $attributes['color'] = $color;
785
                }
786
787
                Database::update(
788
                    $this->tbl_personal_agenda,
789
                    $attributes,
790
                    ['id = ?' => $id]
791
                );
792
                break;
793
            case 'course':
794
                $eventInfo = $this->get_event($id);
795
796
                if (empty($eventInfo)) {
797
                    return false;
798
                }
799
800
                $groupId = api_get_group_id();
801
                $groupIid = 0;
802
                $groupInfo = [];
803
                if ($groupId) {
804
                    $groupInfo = GroupManager::get_group_properties($groupId);
805
                    if ($groupInfo) {
806
                        $groupIid = $groupInfo['iid'];
807
                    }
808
                }
809
810
                $courseId = $this->course['real_id'];
811
812
                if (empty($courseId)) {
813
                    return false;
814
                }
815
816
                if ($this->getIsAllowedToEdit()) {
817
                    $attributes = [
818
                        'title' => $title,
819
                        'start_date' => $start,
820
                        'end_date' => $end,
821
                        'all_day' => $allDay,
822
                        'comment' => $comment,
823
                    ];
824
825
                    if ($updateContent) {
826
                        $attributes['content'] = $content;
827
                    }
828
829
                    if (!empty($color)) {
830
                        $attributes['color'] = $color;
831
                    }
832
833
                    Database::update(
834
                        $this->tbl_course_agenda,
835
                        $attributes,
836
                        [
837
                            'id = ? AND c_id = ? AND session_id = ? ' => [
838
                                $id,
839
                                $courseId,
840
                                $this->sessionId,
841
                            ],
842
                        ]
843
                    );
844
845
                    if (!empty($usersToSend)) {
846
                        $sendTo = $this->parseSendToArray($usersToSend);
847
848
                        $usersToDelete = array_diff(
849
                            $eventInfo['send_to']['users'],
850
                            $sendTo['users']
851
                        );
852
                        $usersToAdd = array_diff(
853
                            $sendTo['users'],
854
                            $eventInfo['send_to']['users']
855
                        );
856
857
                        $groupsToDelete = array_diff(
858
                            $eventInfo['send_to']['groups'],
859
                            $sendTo['groups']
860
                        );
861
                        $groupToAdd = array_diff(
862
                            $sendTo['groups'],
863
                            $eventInfo['send_to']['groups']
864
                        );
865
866
                        if ($sendTo['everyone']) {
867
                            // Delete all from group
868
                            if (isset($eventInfo['send_to']['groups']) &&
869
                                !empty($eventInfo['send_to']['groups'])
870
                            ) {
871
                                foreach ($eventInfo['send_to']['groups'] as $group) {
872
                                    $groupIidItem = 0;
873
                                    if ($group) {
874
                                        $groupInfoItem = GroupManager::get_group_properties(
875
                                            $group
876
                                        );
877
                                        if ($groupInfoItem) {
878
                                            $groupIidItem = $groupInfoItem['iid'];
879
                                        }
880
                                    }
881
882
                                    api_item_property_delete(
883
                                        $this->course,
884
                                        TOOL_CALENDAR_EVENT,
885
                                        $id,
886
                                        0,
887
                                        $groupIidItem,
888
                                        $this->sessionId
889
                                    );
890
                                }
891
                            }
892
893
                            // Storing the selected users.
894
                            if (isset($eventInfo['send_to']['users']) &&
895
                                !empty($eventInfo['send_to']['users'])
896
                            ) {
897
                                foreach ($eventInfo['send_to']['users'] as $userId) {
898
                                    api_item_property_delete(
899
                                        $this->course,
900
                                        TOOL_CALENDAR_EVENT,
901
                                        $id,
902
                                        $userId,
903
                                        $groupIid,
904
                                        $this->sessionId
905
                                    );
906
                                }
907
                            }
908
909
                            // Add to everyone only.
910
                            api_item_property_update(
911
                                $this->course,
912
                                TOOL_CALENDAR_EVENT,
913
                                $id,
914
                                'visible',
915
                                $authorId,
916
                                $groupInfo,
917
                                null,
918
                                $start,
919
                                $end,
920
                                $this->sessionId
921
                            );
922
                        } else {
923
                            // Delete "everyone".
924
                            api_item_property_delete(
925
                                $this->course,
926
                                TOOL_CALENDAR_EVENT,
927
                                $id,
928
                                0,
929
                                0,
930
                                $this->sessionId
931
                            );
932
933
                            // Add groups
934
                            if (!empty($groupToAdd)) {
935
                                foreach ($groupToAdd as $group) {
936
                                    $groupInfoItem = [];
937
                                    if ($group) {
938
                                        $groupInfoItem = GroupManager::get_group_properties(
939
                                            $group
940
                                        );
941
                                    }
942
943
                                    api_item_property_update(
944
                                        $this->course,
945
                                        TOOL_CALENDAR_EVENT,
946
                                        $id,
947
                                        'visible',
948
                                        $authorId,
949
                                        $groupInfoItem,
950
                                        0,
951
                                        $start,
952
                                        $end,
953
                                        $this->sessionId
954
                                    );
955
                                }
956
                            }
957
958
                            // Delete groups.
959
                            if (!empty($groupsToDelete)) {
960
                                foreach ($groupsToDelete as $group) {
961
                                    $groupIidItem = 0;
962
                                    $groupInfoItem = [];
963
                                    if ($group) {
964
                                        $groupInfoItem = GroupManager::get_group_properties(
965
                                            $group
966
                                        );
967
                                        if ($groupInfoItem) {
968
                                            $groupIidItem = $groupInfoItem['iid'];
969
                                        }
970
                                    }
971
972
                                    api_item_property_delete(
973
                                        $this->course,
974
                                        TOOL_CALENDAR_EVENT,
975
                                        $id,
976
                                        0,
977
                                        $groupIidItem,
978
                                        $this->sessionId
979
                                    );
980
                                }
981
                            }
982
983
                            // Add users.
984
                            if (!empty($usersToAdd)) {
985
                                foreach ($usersToAdd as $userId) {
986
                                    api_item_property_update(
987
                                        $this->course,
988
                                        TOOL_CALENDAR_EVENT,
989
                                        $id,
990
                                        'visible',
991
                                        $authorId,
992
                                        $groupInfo,
993
                                        $userId,
994
                                        $start,
995
                                        $end,
996
                                        $this->sessionId
997
                                    );
998
                                }
999
                            }
1000
1001
                            // Delete users.
1002
                            if (!empty($usersToDelete)) {
1003
                                foreach ($usersToDelete as $userId) {
1004
                                    api_item_property_delete(
1005
                                        $this->course,
1006
                                        TOOL_CALENDAR_EVENT,
1007
                                        $id,
1008
                                        $userId,
1009
                                        $groupInfo,
1010
                                        $this->sessionId
1011
                                    );
1012
                                }
1013
                            }
1014
                        }
1015
                    }
1016
1017
                    // Add announcement.
1018
                    if (isset($addAnnouncement) && !empty($addAnnouncement)) {
1019
                        $this->storeAgendaEventAsAnnouncement(
1020
                            $id,
1021
                            $usersToSend
1022
                        );
1023
                    }
1024
1025
                    // Add attachment.
1026
                    if (isset($attachmentArray) && !empty($attachmentArray)) {
1027
                        $counter = 0;
1028
                        foreach ($attachmentArray as $attachmentItem) {
1029
                            $this->updateAttachment(
1030
                                $attachmentItem['id'],
1031
                                $id,
1032
                                $attachmentItem,
1033
                                $attachmentCommentList[$counter],
1034
                                $this->course
1035
                            );
1036
                            $counter++;
1037
                        }
1038
                    }
1039
1040
                    return true;
1041
                } else {
1042
                    return false;
1043
                }
1044
                break;
1045
            case 'admin':
1046
            case 'platform':
1047
                if (api_is_platform_admin()) {
1048
                    $attributes = [
1049
                        'title' => $title,
1050
                        'start_date' => $start,
1051
                        'end_date' => $end,
1052
                        'all_day' => $allDay,
1053
                    ];
1054
1055
                    if ($updateContent) {
1056
                        $attributes['content'] = $content;
1057
                    }
1058
                    Database::update(
1059
                        $this->tbl_global_agenda,
1060
                        $attributes,
1061
                        ['id = ?' => $id]
1062
                    );
1063
                }
1064
                break;
1065
        }
1066
    }
1067
1068
    /**
1069
     * @param int  $id
1070
     * @param bool $deleteAllItemsFromSerie
1071
     *
1072
     * @throws \Doctrine\ORM\ORMException
1073
     * @throws \Doctrine\ORM\OptimisticLockException
1074
     */
1075
    public function deleteEvent($id, $deleteAllItemsFromSerie = false)
1076
    {
1077
        $em = Database::getManager();
1078
1079
        switch ($this->type) {
1080
            case 'personal':
1081
                $eventInfo = $this->get_event($id);
1082
                if ($eventInfo['user'] == api_get_user_id()) {
1083
                    Database::delete(
1084
                        $this->tbl_personal_agenda,
1085
                        ['id = ?' => $id]
1086
                    );
1087
                } elseif (api_get_configuration_value('agenda_collective_invitations')) {
1088
                    $currentUser = api_get_user_entity(api_get_user_id());
1089
1090
                    $eventRepo = $em->getRepository('ChamiloCoreBundle:PersonalAgenda');
1091
                    $event = $eventRepo->findOneByIdAndInvitee($id, $currentUser);
1092
                    $invitation = $event ? $event->getInvitation() : null;
1093
1094
                    if ($invitation) {
1095
                        $invitation->removeInviteeUser($currentUser);
1096
1097
                        $em->persist($invitation);
1098
                        $em->flush();
1099
                    }
1100
                }
1101
                break;
1102
            case 'course':
1103
                $courseId = api_get_course_int_id();
1104
                $isAllowToEdit = $this->getIsAllowedToEdit();
1105
1106
                if (!empty($courseId) && $isAllowToEdit) {
1107
                    $eventInfo = $this->get_event($id);
1108
                    if ($deleteAllItemsFromSerie) {
1109
                        /* This is one of the children.
1110
                           Getting siblings and delete 'Em all + the father! */
1111
                        if (isset($eventInfo['parent_event_id']) && !empty($eventInfo['parent_event_id'])) {
1112
                            // Removing items.
1113
                            $events = $this->getAllRepeatEvents($eventInfo['parent_event_id']);
1114
                            if (!empty($events)) {
1115
                                foreach ($events as $event) {
1116
                                    $this->deleteEvent($event['id']);
1117
                                }
1118
                            }
1119
                            // Removing parent.
1120
                            $this->deleteEvent($eventInfo['parent_event_id']);
1121
                        } else {
1122
                            // This is the father looking for the children.
1123
                            $events = $this->getAllRepeatEvents($id);
1124
                            if (!empty($events)) {
1125
                                foreach ($events as $event) {
1126
                                    $this->deleteEvent($event['id']);
1127
                                }
1128
                            }
1129
                        }
1130
                    }
1131
1132
                    // Removing from events.
1133
                    Database::delete(
1134
                        $this->tbl_course_agenda,
1135
                        ['id = ? AND c_id = ?' => [$id, $courseId]]
1136
                    );
1137
1138
                    api_item_property_update(
1139
                        $this->course,
1140
                        TOOL_CALENDAR_EVENT,
1141
                        $id,
1142
                        'delete',
1143
                        api_get_user_id()
1144
                    );
1145
1146
                    // Removing from series.
1147
                    Database::delete(
1148
                        $this->table_repeat,
1149
                        [
1150
                            'cal_id = ? AND c_id = ?' => [
1151
                                $id,
1152
                                $courseId,
1153
                            ],
1154
                        ]
1155
                    );
1156
1157
                    if (isset($eventInfo['attachment']) && !empty($eventInfo['attachment'])) {
1158
                        foreach ($eventInfo['attachment'] as $attachment) {
1159
                            self::deleteAttachmentFile(
1160
                                $attachment['id'],
1161
                                $this->course
1162
                            );
1163
                        }
1164
                    }
1165
                }
1166
                break;
1167
            case 'admin':
1168
                if (api_is_platform_admin()) {
1169
                    Database::delete(
1170
                        $this->tbl_global_agenda,
1171
                        ['id = ?' => $id]
1172
                    );
1173
                }
1174
                break;
1175
        }
1176
    }
1177
1178
    /**
1179
     * Get agenda events.
1180
     *
1181
     * @param int    $start
1182
     * @param int    $end
1183
     * @param int    $courseId
1184
     * @param int    $groupId
1185
     * @param int    $user_id
1186
     * @param string $format
1187
     *
1188
     * @return array|string
1189
     */
1190
    public function getEvents(
1191
        $start,
1192
        $end,
1193
        $courseId = null,
1194
        $groupId = null,
1195
        $user_id = 0,
1196
        $format = 'json'
1197
    ) {
1198
        switch ($this->type) {
1199
            case 'admin':
1200
                $this->getPlatformEvents($start, $end);
1201
                break;
1202
            case 'course':
1203
                $courseInfo = api_get_course_info_by_id($courseId);
1204
1205
                // Session coach can see all events inside a session.
1206
                if (api_is_coach()) {
1207
                    // Own course
1208
                    $this->getCourseEvents(
1209
                        $start,
1210
                        $end,
1211
                        $courseInfo,
1212
                        $groupId,
1213
                        $this->sessionId,
1214
                        $user_id
1215
                    );
1216
1217
                    // Others
1218
                    $this->getSessionEvents(
1219
                        $start,
1220
                        $end,
1221
                        $this->sessionId,
1222
                        $user_id,
1223
                        $this->eventOtherSessionColor
1224
                    );
1225
                } else {
1226
                    $this->getCourseEvents(
1227
                        $start,
1228
                        $end,
1229
                        $courseInfo,
1230
                        $groupId,
1231
                        $this->sessionId,
1232
                        $user_id
1233
                    );
1234
                }
1235
                break;
1236
            case 'personal':
1237
            default:
1238
                $sessionFilterActive = false;
1239
                if (!empty($this->sessionId)) {
1240
                    $sessionFilterActive = true;
1241
                }
1242
1243
                if ($sessionFilterActive == false) {
1244
                    // Getting personal events
1245
                    $this->getPersonalEvents($start, $end);
1246
1247
                    // Getting platform/admin events
1248
                    $this->getPlatformEvents($start, $end);
1249
                }
1250
1251
                $ignoreVisibility = api_get_configuration_value('personal_agenda_show_all_session_events');
1252
1253
                // Getting course events
1254
                $my_course_list = [];
1255
                if (!api_is_anonymous()) {
1256
                    $session_list = SessionManager::get_sessions_by_user(
1257
                        api_get_user_id(),
1258
                        $ignoreVisibility
1259
                    );
1260
                    $my_course_list = CourseManager::get_courses_list_by_user_id(
1261
                        api_get_user_id(),
1262
                        false
1263
                    );
1264
                }
1265
1266
                if (api_is_drh()) {
1267
                    if (api_drh_can_access_all_session_content()) {
1268
                        $session_list = [];
1269
                        $sessionList = SessionManager::get_sessions_followed_by_drh(
1270
                            api_get_user_id(),
1271
                            null,
1272
                            null,
1273
                            null,
1274
                            true,
1275
                            false
1276
                        );
1277
1278
                        if (!empty($sessionList)) {
1279
                            foreach ($sessionList as $sessionItem) {
1280
                                $sessionId = $sessionItem['id'];
1281
                                $courses = SessionManager::get_course_list_by_session_id($sessionId);
1282
                                $sessionInfo = [
1283
                                    'session_id' => $sessionId,
1284
                                    'courses' => $courses,
1285
                                ];
1286
                                $session_list[] = $sessionInfo;
1287
                            }
1288
                        }
1289
                    }
1290
                }
1291
1292
                if (!empty($session_list)) {
1293
                    foreach ($session_list as $session_item) {
1294
                        if ($sessionFilterActive) {
1295
                            if ($this->sessionId != $session_item['session_id']) {
1296
                                continue;
1297
                            }
1298
                        }
1299
1300
                        $my_courses = $session_item['courses'];
1301
                        $my_session_id = $session_item['session_id'];
1302
1303
                        if (!empty($my_courses)) {
1304
                            foreach ($my_courses as $course_item) {
1305
                                $courseInfo = api_get_course_info_by_id(
1306
                                    $course_item['real_id']
1307
                                );
1308
                                $this->getCourseEvents(
1309
                                    $start,
1310
                                    $end,
1311
                                    $courseInfo,
1312
                                    0,
1313
                                    $my_session_id
1314
                                );
1315
                            }
1316
                        }
1317
                    }
1318
                }
1319
1320
                if (!empty($my_course_list) && $sessionFilterActive == false) {
1321
                    foreach ($my_course_list as $courseInfoItem) {
1322
                        $courseInfo = api_get_course_info_by_id(
1323
                            $courseInfoItem['real_id']
1324
                        );
1325
                        if (isset($courseId) && !empty($courseId)) {
1326
                            if ($courseInfo['real_id'] == $courseId) {
1327
                                $this->getCourseEvents(
1328
                                    $start,
1329
                                    $end,
1330
                                    $courseInfo,
1331
                                    0,
1332
                                    0,
1333
                                    $user_id
1334
                                );
1335
                            }
1336
                        } else {
1337
                            $this->getCourseEvents(
1338
                                $start,
1339
                                $end,
1340
                                $courseInfo,
1341
                                0,
1342
                                0,
1343
                                $user_id
1344
                            );
1345
                        }
1346
                    }
1347
                }
1348
                break;
1349
        }
1350
1351
        $this->cleanEvents();
1352
1353
        switch ($format) {
1354
            case 'json':
1355
                if (empty($this->events)) {
1356
                    return '[]';
1357
                }
1358
1359
                return json_encode($this->events);
1360
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

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