Passed
Pull Request — 1.11.x (#4109)
by Angel Fernando Quiroz
09:46
created

Agenda::getSenderId()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

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