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

Agenda::editEvent()   F

Complexity

Conditions 49
Paths 8248

Size

Total Lines 337
Code Lines 206

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
eloc 206
c 2
b 0
f 1
dl 0
loc 337
rs 0
cc 49
nc 8248
nop 17

How to fix   Long Method    Complexity    Many Parameters   

Long Method

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

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

Commonly applied refactorings include:

Many Parameters

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

There are several approaches to avoid long parameter lists:

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