Completed
Push — master ( 27e209...a08afa )
by Julito
186:04 queued 150:53
created

Agenda::setSendToSelect()   F

Complexity

Conditions 22

Size

Total Lines 112
Code Lines 69

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 22
eloc 69
nop 7
dl 0
loc 112
rs 2
c 0
b 0
f 0

How to fix   Long Method    Complexity   

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:

1
<?php
2
/* For licensing terms, see /license.txt */
3
4
/**
5
 * Class Agenda
6
 *
7
 * @author: Julio Montoya <[email protected]>
8
 */
9
class Agenda
10
{
11
    public $events = [];
12
    /** @var string Current type */
13
    public $type = 'personal';
14
    public $types = ['personal', 'admin', 'course'];
15
    public $sessionId = 0;
16
    public $senderId;
17
    /** @var array */
18
    public $course;
19
    /** @var array */
20
    private $sessionInfo;
21
    /** @var string */
22
    public $comment;
23
    /** @var bool */
24
    private $isAllowedToEdit;
25
    public $eventStudentPublicationColor;
26
27
    /**
28
     * Constructor
29
     * @param string $type
30
     * @param int $senderId Optional The user sender ID
31
     * @param int $courseId Opitonal. The course ID
32
     * @param int $sessionId Optional The session ID
33
     */
34
    public function __construct(
35
        $type,
36
        $senderId = 0,
37
        $courseId = 0,
38
        $sessionId = 0
39
    ) {
40
        // Table definitions
41
        $this->tbl_global_agenda = Database::get_main_table(TABLE_MAIN_SYSTEM_CALENDAR);
0 ignored issues
show
Bug Best Practice introduced by
The property tbl_global_agenda does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
42
        $this->tbl_personal_agenda = Database::get_main_table(TABLE_PERSONAL_AGENDA);
0 ignored issues
show
Bug Best Practice introduced by
The property tbl_personal_agenda does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
43
        $this->tbl_course_agenda = Database::get_course_table(TABLE_AGENDA);
0 ignored issues
show
Bug Best Practice introduced by
The property tbl_course_agenda does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
44
        $this->table_repeat = Database::get_course_table(TABLE_AGENDA_REPEAT);
0 ignored issues
show
Bug Best Practice introduced by
The property table_repeat does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
45
46
        $this->setType($type);
47
        $this->setSenderId($senderId ?: api_get_user_id());
48
        $isAllowToEdit = false;
49
50
        switch ($type) {
51
            case 'course':
52
                $sessionId = $sessionId ?: api_get_session_id();
53
                $sessionInfo = api_get_session_info($sessionId);
54
                $this->setSessionId($sessionId);
55
                $this->setSessionInfo($sessionInfo);
56
57
                // Setting the course object if we are in a course
58
                $courseInfo = api_get_course_info_by_id($courseId);
59
                if (!empty($courseInfo)) {
60
                    $this->set_course($courseInfo);
61
                }
62
63
                // Check if teacher/admin rights.
64
                $isAllowToEdit = api_is_allowed_to_edit(false, true);
65
                // Check course setting.
66
                if (api_get_course_setting('allow_user_edit_agenda') == '1'
67
                    && api_is_allowed_in_course()
68
                ) {
69
                    $isAllowToEdit = true;
70
                }
71
72
                $groupId = api_get_group_id();
73
                if (!empty($groupId)) {
74
                    $groupInfo = GroupManager::get_group_properties($groupId);
75
                    $userHasAccess = GroupManager::user_has_access(
76
                        api_get_user_id(),
77
                        $groupInfo['iid'],
78
                        GroupManager::GROUP_TOOL_CALENDAR
79
                    );
80
                    $isTutor = GroupManager::is_tutor_of_group(
81
                        api_get_user_id(),
82
                        $groupInfo
83
                    );
84
85
                    $isGroupAccess = $userHasAccess || $isTutor;
86
                    if ($isGroupAccess) {
87
                        $isAllowToEdit = true;
88
                    } else {
89
                        $isAllowToEdit = false;
90
                    }
91
                }
92
93
                if (!empty($sessionId)) {
94
                    $allowDhrToEdit = api_get_configuration_value('allow_agenda_edit_for_hrm');
95
                    if ($allowDhrToEdit) {
96
                        $isHrm = SessionManager::isUserSubscribedAsHRM($sessionId, api_get_user_id());
97
                        if ($isHrm) {
98
                            $isAllowToEdit = true;
99
                        }
100
                    }
101
                }
102
                break;
103
            case 'admin':
104
                $isAllowToEdit = api_is_platform_admin();
105
                break;
106
            case 'personal':
107
                $isAllowToEdit = !api_is_anonymous();
108
                break;
109
        }
110
111
        $this->setIsAllowedToEdit($isAllowToEdit);
112
        $this->events = [];
113
114
        $agendaColors = array_merge(
115
            [
116
                'platform' => 'red', //red
117
                'course' => '#458B00', //green
118
                'group' => '#A0522D', //siena
119
                'session' => '#00496D', // kind of green
120
                'other_session' => '#999', // kind of green
121
                'personal' => 'steel blue', //steel blue
122
                'student_publication' => '#FF8C00' //DarkOrange
123
            ],
124
            api_get_configuration_value('agenda_colors') ?: []
125
        );
126
127
        // Event colors
128
        $this->event_platform_color = $agendaColors['platform'];
0 ignored issues
show
Bug Best Practice introduced by
The property event_platform_color does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
129
        $this->event_course_color = $agendaColors['course'];
0 ignored issues
show
Bug Best Practice introduced by
The property event_course_color does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
130
        $this->event_group_color = $agendaColors['group'];
0 ignored issues
show
Bug Best Practice introduced by
The property event_group_color does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
131
        $this->event_session_color = $agendaColors['session'];
0 ignored issues
show
Bug Best Practice introduced by
The property event_session_color does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
132
        $this->eventOtherSessionColor = $agendaColors['other_session'];
0 ignored issues
show
Bug Best Practice introduced by
The property eventOtherSessionColor does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
133
        $this->event_personal_color = $agendaColors['personal'];
0 ignored issues
show
Bug Best Practice introduced by
The property event_personal_color does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
134
        $this->eventStudentPublicationColor = $agendaColors['student_publication'];
135
    }
136
137
    /**
138
     * @param int $senderId
139
     */
140
    public function setSenderId($senderId)
141
    {
142
        $this->senderId = intval($senderId);
143
    }
144
145
    /**
146
     * @return int
147
     */
148
    public function getSenderId()
149
    {
150
        return $this->senderId;
151
    }
152
153
    /**
154
     * @param string $type can be 'personal', 'admin'  or  'course'
155
     */
156
    public function setType($type)
157
    {
158
        $typeList = $this->getTypes();
159
        if (in_array($type, $typeList)) {
160
            $this->type = $type;
161
        }
162
    }
163
164
    /**
165
     * @param int $id
166
     */
167
    public function setSessionId($id)
168
    {
169
        $this->sessionId = intval($id);
170
    }
171
172
    /**
173
     * @param array $sessionInfo
174
     */
175
    public function setSessionInfo($sessionInfo)
176
    {
177
        $this->sessionInfo = $sessionInfo;
178
    }
179
180
    /**
181
     * @return int $id
182
     */
183
    public function getSessionId()
184
    {
185
        return $this->sessionId;
186
    }
187
188
    /**
189
     * @param array $courseInfo
190
     */
191
    public function set_course($courseInfo)
192
    {
193
        $this->course = $courseInfo;
194
    }
195
196
    /**
197
     * @return array
198
     */
199
    public function getTypes()
200
    {
201
        return $this->types;
202
    }
203
204
    /**
205
     * Adds an event to the calendar
206
     * @param string $start datetime format: 2012-06-14 09:00:00
207
     * @param string $end datetime format: 2012-06-14 09:00:00
208
     * @param string $allDay (true, false)
209
     * @param string $title
210
     * @param string $content
211
     * @param array $usersToSend array('everyone') or a list of user/group ids
212
     * @param bool $addAsAnnouncement event as a *course* announcement
213
     * @param int $parentEventId
214
     * @param array $attachmentArray array of $_FILES['']
215
     * @param array $attachmentCommentList
216
     * @param string $eventComment
217
     * @param string $color
218
     *
219
     * @return int
220
     */
221
    public function addEvent(
222
        $start,
223
        $end,
224
        $allDay,
225
        $title,
226
        $content,
227
        $usersToSend = [],
228
        $addAsAnnouncement = false,
229
        $parentEventId = null,
230
        $attachmentArray = [],
231
        $attachmentCommentList = [],
232
        $eventComment = null,
233
        $color = ''
234
    ) {
235
        $start = api_get_utc_datetime($start);
236
        $end = api_get_utc_datetime($end);
237
        $allDay = isset($allDay) && $allDay === 'true' ? 1 : 0;
238
        $id = null;
239
240
        switch ($this->type) {
241
            case 'personal':
242
                $attributes = [
243
                    'user' => api_get_user_id(),
244
                    'title' => $title,
245
                    'text' => $content,
246
                    'date' => $start,
247
                    'enddate' => $end,
248
                    'all_day' => $allDay,
249
                    'color' => $color
250
                ];
251
252
                $id = Database::insert(
253
                    $this->tbl_personal_agenda,
254
                    $attributes
255
                );
256
                break;
257
            case 'course':
258
                $attributes = [
259
                    'title' => $title,
260
                    'content' => $content,
261
                    'start_date' => $start,
262
                    'end_date' => $end,
263
                    'all_day' => $allDay,
264
                    'session_id' => $this->getSessionId(),
265
                    'c_id' => $this->course['real_id'],
266
                    'comment' => $eventComment,
267
                    'color' => $color
268
                ];
269
270
                if (!empty($parentEventId)) {
271
                    $attributes['parent_event_id'] = $parentEventId;
272
                }
273
274
                $senderId = $this->getSenderId();
275
                $sessionId = $this->getSessionId();
276
277
                // Simple course event.
278
                $id = Database::insert($this->tbl_course_agenda, $attributes);
279
280
                if ($id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $id of type integer|false is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
281
                    $sql = "UPDATE ".$this->tbl_course_agenda." SET id = iid WHERE iid = $id";
282
                    Database::query($sql);
283
284
                    $groupId = api_get_group_id();
285
                    $groupInfo = [];
286
                    if ($groupId) {
287
                        $groupInfo = GroupManager::get_group_properties(
288
                            $groupId
289
                        );
290
                    }
291
292
                    if (!empty($usersToSend)) {
293
                        $sendTo = $this->parseSendToArray($usersToSend);
294
                        if ($sendTo['everyone']) {
295
                            api_item_property_update(
296
                                $this->course,
297
                                TOOL_CALENDAR_EVENT,
298
                                $id,
299
                                'AgendaAdded',
300
                                $senderId,
301
                                $groupInfo,
302
                                '',
303
                                $start,
304
                                $end,
305
                                $sessionId
306
                            );
307
                            api_item_property_update(
308
                                $this->course,
309
                                TOOL_CALENDAR_EVENT,
310
                                $id,
311
                                'visible',
312
                                $senderId,
313
                                $groupInfo,
314
                                '',
315
                                $start,
316
                                $end,
317
                                $sessionId
318
                            );
319
                        } else {
320
                            // Storing the selected groups
321
                            if (!empty($sendTo['groups'])) {
322
                                foreach ($sendTo['groups'] as $group) {
323
                                    $groupInfoItem = [];
324
                                    if ($group) {
325
                                        $groupInfoItem = GroupManager::get_group_properties(
326
                                            $group
327
                                        );
328
                                        if ($groupInfoItem) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $groupInfoItem of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
329
                                            $groupIidItem = $groupInfoItem['iid'];
330
                                        }
331
                                    }
332
333
                                    api_item_property_update(
334
                                        $this->course,
335
                                        TOOL_CALENDAR_EVENT,
336
                                        $id,
337
                                        'AgendaAdded',
338
                                        $senderId,
339
                                        $groupInfoItem,
340
                                        0,
341
                                        $start,
342
                                        $end,
343
                                        $sessionId
344
                                    );
345
346
                                    api_item_property_update(
347
                                        $this->course,
348
                                        TOOL_CALENDAR_EVENT,
349
                                        $id,
350
                                        'visible',
351
                                        $senderId,
352
                                        $groupInfoItem,
353
                                        0,
354
                                        $start,
355
                                        $end,
356
                                        $sessionId
357
                                    );
358
                                }
359
                            }
360
361
                            // storing the selected users
362
                            if (!empty($sendTo['users'])) {
363
                                foreach ($sendTo['users'] as $userId) {
364
                                    api_item_property_update(
365
                                        $this->course,
366
                                        TOOL_CALENDAR_EVENT,
367
                                        $id,
368
                                        'AgendaAdded',
369
                                        $senderId,
370
                                        $groupInfo,
371
                                        $userId,
372
                                        $start,
373
                                        $end,
374
                                        $sessionId
375
                                    );
376
377
                                    api_item_property_update(
378
                                        $this->course,
379
                                        TOOL_CALENDAR_EVENT,
380
                                        $id,
381
                                        'visible',
382
                                        $senderId,
383
                                        $groupInfo,
384
                                        $userId,
385
                                        $start,
386
                                        $end,
387
                                        $sessionId
388
                                    );
389
                                }
390
                            }
391
                        }
392
                    }
393
394
                    // Add announcement.
395
                    if ($addAsAnnouncement) {
396
                        $this->storeAgendaEventAsAnnouncement(
397
                            $id,
398
                            $usersToSend
399
                        );
400
                    }
401
402
                    // Add attachment.
403
                    if (isset($attachmentArray) && !empty($attachmentArray)) {
404
                        $counter = 0;
405
                        foreach ($attachmentArray as $attachmentItem) {
406
                            $this->addAttachment(
407
                                $id,
408
                                $attachmentItem,
409
                                $attachmentCommentList[$counter],
410
                                $this->course
411
                            );
412
                            $counter++;
413
                        }
414
                    }
415
                }
416
                break;
417
            case 'admin':
418
                if (api_is_platform_admin()) {
419
                    $attributes = [
420
                        'title' => $title,
421
                        'content' => $content,
422
                        'start_date' => $start,
423
                        'end_date' => $end,
424
                        'all_day' => $allDay,
425
                        'access_url_id' => api_get_current_access_url_id()
426
                    ];
427
428
                    $id = Database::insert(
429
                        $this->tbl_global_agenda,
430
                        $attributes
431
                    );
432
                }
433
                break;
434
        }
435
436
        return $id;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $id could also return false which is incompatible with the documented return type integer. Did you maybe forget to handle an error condition?

If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled.

Loading history...
437
    }
438
439
    /**
440
     * @param int $eventId
441
     * @param int $courseId
442
     *
443
     * @return array
444
     */
445
    public function getRepeatedInfoByEvent($eventId, $courseId)
446
    {
447
        $repeatTable = Database::get_course_table(TABLE_AGENDA_REPEAT);
448
        $eventId = intval($eventId);
449
        $courseId = intval($courseId);
450
        $sql = "SELECT * FROM $repeatTable
451
                WHERE c_id = $courseId AND cal_id = $eventId";
452
        $res = Database::query($sql);
453
        $repeatInfo = [];
454
        if (Database::num_rows($res) > 0) {
455
            $repeatInfo = Database::fetch_array($res, 'ASSOC');
456
        }
457
458
        return $repeatInfo;
459
    }
460
461
    /**
462
     * @param int $eventId
463
     * @param string $type
464
     * @param string $end in local time
465
     * @param array $sentTo
466
     *
467
     * @return bool
468
     */
469
    public function addRepeatedItem($eventId, $type, $end, $sentTo = [])
470
    {
471
        $t_agenda = Database::get_course_table(TABLE_AGENDA);
472
        $t_agenda_r = Database::get_course_table(TABLE_AGENDA_REPEAT);
473
474
        if (empty($this->course)) {
475
            return false;
476
        }
477
478
        $course_id = $this->course['real_id'];
479
        $eventId = intval($eventId);
480
481
        $sql = "SELECT title, content, start_date, end_date, all_day
482
                FROM $t_agenda
483
                WHERE c_id = $course_id AND id = $eventId";
484
        $res = Database::query($sql);
485
486
        if (Database::num_rows($res) !== 1) {
487
            return false;
488
        }
489
490
        $row = Database::fetch_array($res);
491
        $origStartDate = api_strtotime($row['start_date'], 'UTC');
492
        $origEndDate = api_strtotime($row['end_date'], 'UTC');
493
        $diff = $origEndDate - $origStartDate;
494
495
        $title = $row['title'];
496
        $content = $row['content'];
497
        $allDay = $row['all_day'];
498
499
        $now = time();
500
        $type = Database::escape_string($type);
501
        $end = api_strtotime($end);
502
503
        if (1 <= $end && $end <= 500) {
504
            // We assume that, with this type of value, the user actually gives a count of repetitions
505
            //and that he wants us to calculate the end date with that (particularly in case of imports from ical)
506
            switch ($type) {
507
                case 'daily':
508
                    $end = $origStartDate + (86400 * $end);
509
                    break;
510
                case 'weekly':
511
                    $end = $this->addWeek($origStartDate, $end);
512
                    break;
513
                case 'monthlyByDate':
514
                    $end = $this->addMonth($origStartDate, $end);
515
                    break;
516
                case 'monthlyByDay':
517
                    //TODO
518
                    break;
519
                case 'monthlyByDayR':
520
                    //TODO
521
                    break;
522
                case 'yearly':
523
                    $end = $this->addYear($origStartDate, $end);
524
                    break;
525
            }
526
        }
527
528
        $typeList = [
529
            'daily',
530
            'weekly',
531
            'monthlyByDate',
532
            'monthlyByDay',
533
            'monthlyByDayR',
534
            'yearly'
535
        ];
536
537
        // The event has to repeat *in the future*. We don't allow repeated
538
        // events in the past
539
        if ($end > $now && in_array($type, $typeList)) {
540
            $sql = "INSERT INTO $t_agenda_r (c_id, cal_id, cal_type, cal_end)
541
                    VALUES ($course_id, '$eventId', '$type', '$end')";
542
            Database::query($sql);
543
544
            switch ($type) {
545
                // @todo improve loop.
546
                case 'daily':
547
                    for ($i = $origStartDate + 86400; $i <= $end; $i += 86400) {
548
                        $start = date('Y-m-d H:i:s', $i);
549
                        $repeatEnd = date('Y-m-d H:i:s', $i + $diff);
550
                        $this->addEvent(
551
                            $start,
552
                            $repeatEnd,
553
                            $allDay,
554
                            $title,
555
                            $content,
556
                            $sentTo,
557
                            false,
558
                            $eventId
559
                        );
560
                    }
561
                    break;
562
                case 'weekly':
563
                    for ($i = $origStartDate + 604800; $i <= $end; $i += 604800) {
564
                        $start = date('Y-m-d H:i:s', $i);
565
                        $repeatEnd = date('Y-m-d H:i:s', $i + $diff);
566
                        $this->addEvent(
567
                            $start,
568
                            $repeatEnd,
569
                            $allDay,
570
                            $title,
571
                            $content,
572
                            $sentTo,
573
                            false,
574
                            $eventId
575
                        );
576
                    }
577
                    break;
578
                case 'monthlyByDate':
579
                    $next_start = $this->addMonth($origStartDate);
580
                    while ($next_start <= $end) {
581
                        $start = date('Y-m-d H:i:s', $next_start);
582
                        $repeatEnd = date('Y-m-d H:i:s', $next_start + $diff);
583
                        $this->addEvent(
584
                            $start,
585
                            $repeatEnd,
586
                            $allDay,
587
                            $title,
588
                            $content,
589
                            $sentTo,
590
                            false,
591
                            $eventId
592
                        );
593
                        $next_start = $this->addMonth($next_start);
594
                    }
595
                    break;
596
                case 'monthlyByDay':
597
                    //not yet implemented
598
                    break;
599
                case 'monthlyByDayR':
600
                    //not yet implemented
601
                    break;
602
                case 'yearly':
603
                    $next_start = $this->addYear($origStartDate);
604
                    while ($next_start <= $end) {
605
                        $start = date('Y-m-d H:i:s', $next_start);
606
                        $repeatEnd = date('Y-m-d H:i:s', $next_start + $diff);
607
                        $this->addEvent(
608
                            $start,
609
                            $repeatEnd,
610
                            $allDay,
611
                            $title,
612
                            $content,
613
                            $sentTo,
614
                            false,
615
                            $eventId
616
                        );
617
                        $next_start = $this->addYear($next_start);
618
                    }
619
                    break;
620
            }
621
        }
622
623
        return true;
624
    }
625
626
    /**
627
     * @param int $item_id
628
     * @param array $sentTo
629
     * @return int
630
     */
631
    public function storeAgendaEventAsAnnouncement($item_id, $sentTo = [])
632
    {
633
        $table_agenda = Database::get_course_table(TABLE_AGENDA);
634
        $course_id = api_get_course_int_id();
635
636
        // Check params
637
        if (empty($item_id) || $item_id != strval(intval($item_id))) {
638
            return -1;
639
        }
640
641
        // Get the agenda item.
642
        $item_id = intval($item_id);
643
        $sql = "SELECT * FROM $table_agenda
644
                WHERE c_id = $course_id AND id = ".$item_id;
645
        $res = Database::query($sql);
646
647
        if (Database::num_rows($res) > 0) {
648
            $row = Database::fetch_array($res, 'ASSOC');
649
650
            // Sending announcement
651
            if (!empty($sentTo)) {
652
                $id = AnnouncementManager::add_announcement(
653
                    api_get_course_info(),
654
                    api_get_session_id(),
655
                    $row['title'],
656
                    $row['content'],
657
                    $sentTo,
658
                    null,
659
                    null,
660
                    $row['end_date']
661
                );
662
663
                AnnouncementManager::sendEmail(
664
                    api_get_course_info(),
665
                    api_get_session_id(),
666
                    $id
667
                );
668
669
                return $id;
670
            }
671
        }
672
673
        return -1;
674
    }
675
676
    /**
677
     * Edits an event
678
     *
679
     * @param int $id
680
     * @param string $start datetime format: 2012-06-14 09:00:00
681
     * @param string $end datetime format: 2012-06-14 09:00:00
682
     * @param int $allDay is all day 'true' or 'false'
683
     * @param string $title
684
     * @param string $content
685
     * @param array $usersToSend
686
     * @param array $attachmentArray
687
     * @param array $attachmentCommentList
688
     * @param string $comment
689
     * @param string $color
690
     * @param bool $addAnnouncement
691
     * @param bool $updateContent
692
     * @param int $authorId
693
     *
694
     * @return bool
695
     */
696
    public function editEvent(
697
        $id,
698
        $start,
699
        $end,
700
        $allDay,
701
        $title,
702
        $content,
703
        $usersToSend = [],
704
        $attachmentArray = [],
705
        $attachmentCommentList = [],
706
        $comment = null,
707
        $color = '',
708
        $addAnnouncement = false,
709
        $updateContent = true,
710
        $authorId = 0
711
    ) {
712
        $start = api_get_utc_datetime($start);
713
        $end = api_get_utc_datetime($end);
714
        $allDay = isset($allDay) && $allDay == 'true' ? 1 : 0;
715
        $authorId = empty($authorId) ? api_get_user_id() : (int) $authorId;
716
717
        switch ($this->type) {
718
            case 'personal':
719
                $eventInfo = $this->get_event($id);
720
                if ($eventInfo['user'] != api_get_user_id()) {
721
                    break;
722
                }
723
                $attributes = [
724
                    'title' => $title,
725
                    'date' => $start,
726
                    'enddate' => $end,
727
                    'all_day' => $allDay,
728
729
                ];
730
731
                if ($updateContent) {
732
                    $attributes['text'] = $content;
733
                }
734
735
                if (!empty($color)) {
736
                    $attributes['color'] = $color;
737
                }
738
739
                Database::update(
740
                    $this->tbl_personal_agenda,
741
                    $attributes,
742
                    ['id = ?' => $id]
743
                );
744
                break;
745
            case 'course':
746
                $eventInfo = $this->get_event($id);
747
748
                if (empty($eventInfo)) {
749
                    return false;
750
                }
751
752
                $groupId = api_get_group_id();
753
                $groupIid = 0;
754
                $groupInfo = [];
755
                if ($groupId) {
756
                    $groupInfo = GroupManager::get_group_properties($groupId);
757
                    if ($groupInfo) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $groupInfo of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
758
                        $groupIid = $groupInfo['iid'];
759
                    }
760
                }
761
762
                $course_id = $this->course['real_id'];
763
764
                if (empty($course_id)) {
765
                    return false;
766
                }
767
768
                if ($this->getIsAllowedToEdit()) {
769
                    $attributes = [
770
                        'title' => $title,
771
                        'start_date' => $start,
772
                        'end_date' => $end,
773
                        'all_day' => $allDay,
774
                        'comment' => $comment
775
                    ];
776
777
                    if ($updateContent) {
778
                        $attributes['content'] = $content;
779
                    }
780
781
                    if (!empty($color)) {
782
                        $attributes['color'] = $color;
783
                    }
784
785
                    Database::update(
786
                        $this->tbl_course_agenda,
787
                        $attributes,
788
                        [
789
                            'id = ? AND c_id = ? AND session_id = ? ' => [
790
                                $id,
791
                                $course_id,
792
                                $this->sessionId
793
                            ]
794
                        ]
795
                    );
796
797
                    if (!empty($usersToSend)) {
798
                        $sendTo = $this->parseSendToArray($usersToSend);
799
800
                        $usersToDelete = array_diff(
801
                            $eventInfo['send_to']['users'],
802
                            $sendTo['users']
803
                        );
804
                        $usersToAdd = array_diff(
805
                            $sendTo['users'],
806
                            $eventInfo['send_to']['users']
807
                        );
808
809
                        $groupsToDelete = array_diff(
810
                            $eventInfo['send_to']['groups'],
811
                            $sendTo['groups']
812
                        );
813
                        $groupToAdd = array_diff(
814
                            $sendTo['groups'],
815
                            $eventInfo['send_to']['groups']
816
                        );
817
818
                        if ($sendTo['everyone']) {
819
                            // Delete all from group
820
                            if (isset($eventInfo['send_to']['groups']) &&
821
                                !empty($eventInfo['send_to']['groups'])
822
                            ) {
823
                                foreach ($eventInfo['send_to']['groups'] as $group) {
824
                                    $groupIidItem = 0;
825
                                    if ($group) {
826
                                        $groupInfoItem = GroupManager::get_group_properties(
827
                                            $group
828
                                        );
829
                                        if ($groupInfoItem) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $groupInfoItem of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
830
                                            $groupIidItem = $groupInfoItem['iid'];
831
                                        }
832
                                    }
833
834
                                    api_item_property_delete(
835
                                        $this->course,
836
                                        TOOL_CALENDAR_EVENT,
837
                                        $id,
838
                                        0,
839
                                        $groupIidItem,
840
                                        $this->sessionId
841
                                    );
842
                                }
843
                            }
844
845
                            // Storing the selected users.
846
                            if (isset($eventInfo['send_to']['users']) &&
847
                                !empty($eventInfo['send_to']['users'])
848
                            ) {
849
                                foreach ($eventInfo['send_to']['users'] as $userId) {
850
                                    api_item_property_delete(
851
                                        $this->course,
852
                                        TOOL_CALENDAR_EVENT,
853
                                        $id,
854
                                        $userId,
855
                                        $groupIid,
856
                                        $this->sessionId
857
                                    );
858
                                }
859
                            }
860
861
                            // Add to everyone only.
862
                            api_item_property_update(
863
                                $this->course,
864
                                TOOL_CALENDAR_EVENT,
865
                                $id,
866
                                'visible',
867
                                $authorId,
868
                                $groupInfo,
869
                                null,
870
                                $start,
871
                                $end,
872
                                $this->sessionId
873
                            );
874
                        } else {
875
                            // Delete "everyone".
876
                            api_item_property_delete(
877
                                $this->course,
878
                                TOOL_CALENDAR_EVENT,
879
                                $id,
880
                                0,
881
                                0,
882
                                $this->sessionId
883
                            );
884
885
                            // Add groups
886
                            if (!empty($groupToAdd)) {
887
                                foreach ($groupToAdd as $group) {
888
                                    $groupInfoItem = [];
889
                                    if ($group) {
890
                                        $groupInfoItem = GroupManager::get_group_properties(
891
                                            $group
892
                                        );
893
                                    }
894
895
                                    api_item_property_update(
896
                                        $this->course,
897
                                        TOOL_CALENDAR_EVENT,
898
                                        $id,
899
                                        'visible',
900
                                        $authorId,
901
                                        $groupInfoItem,
902
                                        0,
903
                                        $start,
904
                                        $end,
905
                                        $this->sessionId
906
                                    );
907
                                }
908
                            }
909
910
                            // Delete groups.
911
                            if (!empty($groupsToDelete)) {
912
                                foreach ($groupsToDelete as $group) {
913
                                    $groupIidItem = 0;
914
                                    $groupInfoItem = [];
915
                                    if ($group) {
916
                                        $groupInfoItem = GroupManager::get_group_properties(
917
                                            $group
918
                                        );
919
                                        if ($groupInfoItem) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $groupInfoItem of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
920
                                            $groupIidItem = $groupInfoItem['iid'];
921
                                        }
922
                                    }
923
924
                                    api_item_property_delete(
925
                                        $this->course,
926
                                        TOOL_CALENDAR_EVENT,
927
                                        $id,
928
                                        0,
929
                                        $groupIidItem,
930
                                        $this->sessionId
931
                                    );
932
                                }
933
                            }
934
935
                            // Add users.
936
                            if (!empty($usersToAdd)) {
937
                                foreach ($usersToAdd as $userId) {
938
                                    api_item_property_update(
939
                                        $this->course,
940
                                        TOOL_CALENDAR_EVENT,
941
                                        $id,
942
                                        'visible',
943
                                        $authorId,
944
                                        $groupInfo,
945
                                        $userId,
946
                                        $start,
947
                                        $end,
948
                                        $this->sessionId
949
                                    );
950
                                }
951
                            }
952
953
                            // Delete users.
954
                            if (!empty($usersToDelete)) {
955
                                foreach ($usersToDelete as $userId) {
956
                                    api_item_property_delete(
957
                                        $this->course,
958
                                        TOOL_CALENDAR_EVENT,
959
                                        $id,
960
                                        $userId,
961
                                        $groupInfo,
962
                                        $this->sessionId
963
                                    );
964
                                }
965
                            }
966
                        }
967
                    }
968
969
                    // Add announcement.
970
                    if (isset($addAnnouncement) && !empty($addAnnouncement)) {
971
                        $this->storeAgendaEventAsAnnouncement(
972
                            $id,
973
                            $usersToSend
974
                        );
975
                    }
976
977
                    // Add attachment.
978
                    if (isset($attachmentArray) && !empty($attachmentArray)) {
979
                        $counter = 0;
980
                        foreach ($attachmentArray as $attachmentItem) {
981
                            $this->updateAttachment(
982
                                $attachmentItem['id'],
983
                                $id,
984
                                $attachmentItem,
985
                                $attachmentCommentList[$counter],
986
                                $this->course
987
                            );
988
                            $counter++;
989
                        }
990
                    }
991
992
                    return true;
993
                } else {
994
                    return false;
995
                }
996
                break;
997
            case 'admin':
998
            case 'platform':
999
                if (api_is_platform_admin()) {
1000
                    $attributes = [
1001
                        'title' => $title,
1002
                        'start_date' => $start,
1003
                        'end_date' => $end,
1004
                        'all_day' => $allDay
1005
                    ];
1006
1007
                    if ($updateContent) {
1008
                        $attributes['content'] = $content;
1009
                    }
1010
                    Database::update(
1011
                        $this->tbl_global_agenda,
1012
                        $attributes,
1013
                        ['id = ?' => $id]
1014
                    );
1015
                }
1016
                break;
1017
        }
1018
    }
1019
1020
    /**
1021
     * @param int $id
1022
     * @param bool $deleteAllItemsFromSerie
1023
     */
1024
    public function deleteEvent($id, $deleteAllItemsFromSerie = false)
1025
    {
1026
        switch ($this->type) {
1027
            case 'personal':
1028
                $eventInfo = $this->get_event($id);
1029
                if ($eventInfo['user'] == api_get_user_id()) {
1030
                    Database::delete(
1031
                        $this->tbl_personal_agenda,
1032
                        ['id = ?' => $id]
1033
                    );
1034
                }
1035
                break;
1036
            case 'course':
1037
                $course_id = api_get_course_int_id();
1038
                $sessionId = api_get_session_id();
1039
                $isAllowToEdit = api_is_allowed_to_edit(null, true);
1040
1041
                if ($isAllowToEdit == false && !empty($sessionId)) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
1042
                    $allowDhrToEdit = api_get_configuration_value('allow_agenda_edit_for_hrm');
1043
                    if ($allowDhrToEdit) {
1044
                        $isHrm = SessionManager::isUserSubscribedAsHRM(
1045
                            $sessionId,
1046
                            api_get_user_id()
1047
                        );
1048
                        if ($isHrm) {
1049
                            $isAllowToEdit = true;
1050
                        }
1051
                    }
1052
                }
1053
1054
                if (!empty($course_id) && $isAllowToEdit) {
1055
                    // Delete
1056
                    $eventInfo = $this->get_event($id);
1057
                    if ($deleteAllItemsFromSerie) {
1058
                        /* This is one of the children.
1059
                           Getting siblings and delete 'Em all + the father! */
1060
                        if (isset($eventInfo['parent_event_id']) && !empty($eventInfo['parent_event_id'])) {
1061
                            // Removing items.
1062
                            $events = $this->getAllRepeatEvents(
1063
                                $eventInfo['parent_event_id']
1064
                            );
1065
                            if (!empty($events)) {
1066
                                foreach ($events as $event) {
1067
                                    $this->deleteEvent($event['id']);
1068
                                }
1069
                            }
1070
                            // Removing parent.
1071
                            $this->deleteEvent($eventInfo['parent_event_id']);
1072
                        } else {
1073
                            // This is the father looking for the children.
1074
                            $events = $this->getAllRepeatEvents($id);
1075
                            if (!empty($events)) {
1076
                                foreach ($events as $event) {
1077
                                    $this->deleteEvent($event['id']);
1078
                                }
1079
                            }
1080
                        }
1081
                    }
1082
1083
                    // Removing from events.
1084
                    Database::delete(
1085
                        $this->tbl_course_agenda,
1086
                        ['id = ? AND c_id = ?' => [$id, $course_id]]
1087
                    );
1088
1089
                    api_item_property_update(
1090
                        $this->course,
1091
                        TOOL_CALENDAR_EVENT,
1092
                        $id,
1093
                        'delete',
1094
                        api_get_user_id()
1095
                    );
1096
1097
                    // Removing from series.
1098
                    Database::delete(
1099
                        $this->table_repeat,
1100
                        [
1101
                            'cal_id = ? AND c_id = ?' => [
1102
                                $id,
1103
                                $course_id
1104
                            ]
1105
                        ]
1106
                    );
1107
1108
                    if (isset($eventInfo['attachment']) && !empty($eventInfo['attachment'])) {
1109
                        foreach ($eventInfo['attachment'] as $attachment) {
1110
                            self::deleteAttachmentFile(
0 ignored issues
show
Bug Best Practice introduced by
The method Agenda::deleteAttachmentFile() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1110
                            self::/** @scrutinizer ignore-call */ 
1111
                                  deleteAttachmentFile(
Loading history...
1111
                                $attachment['id'],
1112
                                $this->course
1113
                            );
1114
                        }
1115
                    }
1116
                }
1117
                break;
1118
            case 'admin':
1119
                if (api_is_platform_admin()) {
1120
                    Database::delete(
1121
                        $this->tbl_global_agenda,
1122
                        ['id = ?' => $id]
1123
                    );
1124
                }
1125
                break;
1126
        }
1127
    }
1128
1129
    /**
1130
     * Get agenda events
1131
     * @param int $start
1132
     * @param int $end
1133
     * @param int $course_id
1134
     * @param int $groupId
1135
     * @param int $user_id
1136
     * @param string $format
1137
     *
1138
     * @return array|string
1139
     */
1140
    public function getEvents(
1141
        $start,
1142
        $end,
1143
        $course_id = null,
1144
        $groupId = null,
1145
        $user_id = 0,
1146
        $format = 'json'
1147
    ) {
1148
        switch ($this->type) {
1149
            case 'admin':
1150
                $this->getPlatformEvents($start, $end);
1151
                break;
1152
            case 'course':
1153
                $courseInfo = api_get_course_info_by_id($course_id);
1154
1155
                // Session coach can see all events inside a session.
1156
                if (api_is_coach()) {
1157
                    // Own course
1158
                    $this->getCourseEvents(
1159
                        $start,
1160
                        $end,
1161
                        $courseInfo,
1162
                        $groupId,
1163
                        $this->sessionId,
1164
                        $user_id
1165
                    );
1166
1167
                    // Others
1168
                    $this->getSessionEvents(
1169
                        $start,
1170
                        $end,
1171
                        $this->sessionId,
1172
                        $user_id,
1173
                        $this->eventOtherSessionColor
1174
                    );
1175
                } else {
1176
                    $this->getCourseEvents(
1177
                        $start,
1178
                        $end,
1179
                        $courseInfo,
1180
                        $groupId,
1181
                        $this->sessionId,
1182
                        $user_id
1183
                    );
1184
                }
1185
                break;
1186
            case 'personal':
1187
            default:
1188
                $sessionFilterActive = false;
1189
                if (!empty($this->sessionId)) {
1190
                    $sessionFilterActive = true;
1191
                }
1192
1193
                if ($sessionFilterActive == false) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
1194
                    // Getting personal events
1195
                    $this->getPersonalEvents($start, $end);
1196
1197
                    // Getting platform/admin events
1198
                    $this->getPlatformEvents($start, $end);
1199
                }
1200
1201
                $ignoreVisibility = api_get_configuration_value('personal_agenda_show_all_session_events');
1202
1203
                // Getting course events
1204
                $my_course_list = [];
1205
                if (!api_is_anonymous()) {
1206
                    $session_list = SessionManager::get_sessions_by_user(
1207
                        api_get_user_id(),
1208
                        $ignoreVisibility
1209
1210
                    );
1211
                    $my_course_list = CourseManager::get_courses_list_by_user_id(
1212
                        api_get_user_id(),
1213
                        false
1214
                    );
1215
                }
1216
1217
                if (api_is_drh()) {
1218
                    if (api_drh_can_access_all_session_content()) {
1219
                        $session_list = [];
1220
                        $sessionList = SessionManager::get_sessions_followed_by_drh(
1221
                            api_get_user_id(),
1222
                            null,
1223
                            null,
1224
                            null,
1225
                            true,
1226
                            false
1227
                        );
1228
1229
                        if (!empty($sessionList)) {
1230
                            foreach ($sessionList as $sessionItem) {
1231
                                $sessionId = $sessionItem['id'];
1232
                                $courses = SessionManager::get_course_list_by_session_id(
1233
                                    $sessionId
1234
                                );
1235
                                $sessionInfo = [
1236
                                    'session_id' => $sessionId,
1237
                                    'courses' => $courses
1238
                                ];
1239
                                $session_list[] = $sessionInfo;
1240
                            }
1241
                        }
1242
                    }
1243
                }
1244
1245
                if (!empty($session_list)) {
1246
                    foreach ($session_list as $session_item) {
1247
                        if ($sessionFilterActive) {
1248
                            if ($this->sessionId != $session_item['session_id']) {
1249
                                continue;
1250
                            }
1251
                        }
1252
1253
                        $my_courses = $session_item['courses'];
1254
                        $my_session_id = $session_item['session_id'];
1255
1256
                        if (!empty($my_courses)) {
1257
                            foreach ($my_courses as $course_item) {
1258
                                $courseInfo = api_get_course_info_by_id(
1259
                                    $course_item['real_id']
1260
                                );
1261
                                $this->getCourseEvents(
1262
                                    $start,
1263
                                    $end,
1264
                                    $courseInfo,
1265
                                    0,
1266
                                    $my_session_id
1267
                                );
1268
                            }
1269
                        }
1270
                    }
1271
                }
1272
1273
                if (!empty($my_course_list) && $sessionFilterActive == false) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
1274
                    foreach ($my_course_list as $courseInfoItem) {
1275
                        $courseInfo = api_get_course_info_by_id(
1276
                            $courseInfoItem['real_id']
1277
                        );
1278
                        if (isset($course_id) && !empty($course_id)) {
1279
                            if ($courseInfo['real_id'] == $course_id) {
1280
                                $this->getCourseEvents(
1281
                                    $start,
1282
                                    $end,
1283
                                    $courseInfo,
1284
                                    0,
1285
                                    0,
1286
                                    $user_id
1287
                                );
1288
                            }
1289
                        } else {
1290
                            $this->getCourseEvents(
1291
                                $start,
1292
                                $end,
1293
                                $courseInfo,
1294
                                0,
1295
                                0,
1296
                                $user_id
1297
                            );
1298
                        }
1299
                    }
1300
                }
1301
1302
                break;
1303
        }
1304
1305
        switch ($format) {
1306
            case 'json':
1307
                if (empty($this->events)) {
1308
                    return '[]';
1309
                }
1310
1311
                return json_encode($this->events);
1312
                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...
1313
            case 'array':
1314
                if (empty($this->events)) {
1315
                    return [];
1316
                }
1317
1318
                return $this->events;
1319
                break;
1320
        }
1321
    }
1322
1323
    /**
1324
     * @param int $id
1325
     * @param int $minute_delta
1326
     * @return int
1327
     */
1328
    public function resizeEvent($id, $minute_delta)
1329
    {
1330
        $id = (int) $id;
1331
        $delta = intval($minute_delta);
1332
        $event = $this->get_event($id);
1333
        if (!empty($event)) {
1334
            switch ($this->type) {
1335
                case 'personal':
1336
                    $sql = "UPDATE $this->tbl_personal_agenda SET
1337
                            enddate = DATE_ADD(enddate, INTERVAL $delta MINUTE)
1338
							WHERE id = ".$id;
1339
                    Database::query($sql);
1340
                    break;
1341
                case 'course':
1342
                    $sql = "UPDATE $this->tbl_course_agenda SET
1343
                            end_date = DATE_ADD(end_date, INTERVAL $delta MINUTE)
1344
							WHERE 
1345
							    c_id = ".$this->course['real_id']." AND 
1346
							    id = ".$id;
1347
                    Database::query($sql);
1348
                    break;
1349
                case 'admin':
1350
                    $sql = "UPDATE $this->tbl_global_agenda SET
1351
                            end_date = DATE_ADD(end_date, INTERVAL $delta MINUTE)
1352
							WHERE id = ".$id;
1353
                    Database::query($sql);
1354
                    break;
1355
            }
1356
        }
1357
1358
        return 1;
1359
    }
1360
1361
    /**
1362
     * @param int $id
1363
     * @param int $minute_delta minutes
1364
     * @param int $allDay
1365
     * @return int
1366
     */
1367
    public function move_event($id, $minute_delta, $allDay)
1368
    {
1369
        $id = (int) $id;
1370
        $event = $this->get_event($id);
1371
1372
        if (empty($event)) {
1373
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type integer.
Loading history...
1374
        }
1375
1376
        // we convert the hour delta into minutes and add the minute delta
1377
        $delta = intval($minute_delta);
1378
        $allDay = intval($allDay);
1379
1380
        if (!empty($event)) {
1381
            switch ($this->type) {
1382
                case 'personal':
1383
                    $sql = "UPDATE $this->tbl_personal_agenda SET
1384
                            all_day = $allDay, date = DATE_ADD(date, INTERVAL $delta MINUTE),
1385
                            enddate = DATE_ADD(enddate, INTERVAL $delta MINUTE)
1386
							WHERE id=".$id;
1387
                    Database::query($sql);
1388
                    break;
1389
                case 'course':
1390
                    $sql = "UPDATE $this->tbl_course_agenda SET
1391
                            all_day = $allDay, 
1392
                            start_date = DATE_ADD(start_date, INTERVAL $delta MINUTE),
1393
                            end_date = DATE_ADD(end_date, INTERVAL $delta MINUTE)
1394
							WHERE 
1395
							    c_id = ".$this->course['real_id']." AND 
1396
							    id=".$id;
1397
                    Database::query($sql);
1398
                    break;
1399
                case 'admin':
1400
                    $sql = "UPDATE $this->tbl_global_agenda SET
1401
                            all_day = $allDay,
1402
                            start_date = DATE_ADD(start_date,INTERVAL $delta MINUTE),
1403
                            end_date = DATE_ADD(end_date, INTERVAL $delta MINUTE)
1404
							WHERE id=".$id;
1405
                    Database::query($sql);
1406
                    break;
1407
            }
1408
        }
1409
1410
        return 1;
1411
    }
1412
1413
    /**
1414
     * Gets a single event
1415
     *
1416
     * @param int $id event id
1417
     * @return array
1418
     */
1419
    public function get_event($id)
1420
    {
1421
        // make sure events of the personal agenda can only be seen by the user himself
1422
        $id = intval($id);
1423
        $event = null;
1424
        switch ($this->type) {
1425
            case 'personal':
1426
                $sql = "SELECT * FROM ".$this->tbl_personal_agenda."
1427
                        WHERE id = $id AND user = ".api_get_user_id();
1428
                $result = Database::query($sql);
1429
                if (Database::num_rows($result)) {
1430
                    $event = Database::fetch_array($result, 'ASSOC');
1431
                    $event['description'] = $event['text'];
1432
                    $event['content'] = $event['text'];
1433
                    $event['start_date'] = $event['date'];
1434
                    $event['end_date'] = $event['enddate'];
1435
                }
1436
                break;
1437
            case 'course':
1438
                if (!empty($this->course['real_id'])) {
1439
                    $sql = "SELECT * FROM ".$this->tbl_course_agenda."
1440
                            WHERE c_id = ".$this->course['real_id']." AND id = ".$id;
1441
                    $result = Database::query($sql);
1442
                    if (Database::num_rows($result)) {
1443
                        $event = Database::fetch_array($result, 'ASSOC');
1444
                        $event['description'] = $event['content'];
1445
1446
                        // Getting send to array
1447
                        $event['send_to'] = $this->getUsersAndGroupSubscribedToEvent(
1448
                            $id,
1449
                            $this->course['real_id'],
1450
                            $this->sessionId
1451
                        );
1452
1453
                        // Getting repeat info
1454
                        $event['repeat_info'] = $this->getRepeatedInfoByEvent(
1455
                            $id,
1456
                            $this->course['real_id']
1457
                        );
1458
1459
                        if (!empty($event['parent_event_id'])) {
1460
                            $event['parent_info'] = $this->get_event(
1461
                                $event['parent_event_id']
1462
                            );
1463
                        }
1464
1465
                        $event['attachment'] = $this->getAttachmentList(
1466
                            $id,
1467
                            $this->course
1468
                        );
1469
                    }
1470
                }
1471
                break;
1472
            case 'admin':
1473
            case 'platform':
1474
                $sql = "SELECT * FROM ".$this->tbl_global_agenda."
1475
                        WHERE id = $id";
1476
                $result = Database::query($sql);
1477
                if (Database::num_rows($result)) {
1478
                    $event = Database::fetch_array($result, 'ASSOC');
1479
                    $event['description'] = $event['content'];
1480
                }
1481
                break;
1482
        }
1483
1484
        return $event;
1485
    }
1486
1487
    /**
1488
     * Gets personal events
1489
     * @param int $start
1490
     * @param int $end
1491
     * @return array
1492
     */
1493
    public function getPersonalEvents($start, $end)
1494
    {
1495
        $start = intval($start);
1496
        $end = intval($end);
1497
        $startCondition = '';
1498
        $endCondition = '';
1499
1500
        if ($start !== 0) {
1501
            $start = api_get_utc_datetime($start);
1502
            $startCondition = "AND date >= '".$start."'";
1503
        }
1504
        if ($start !== 0) {
1505
            $end = api_get_utc_datetime($end);
1506
            $endCondition = "AND (enddate <= '".$end."' OR enddate IS NULL)";
1507
        }
1508
        $user_id = api_get_user_id();
1509
1510
        $sql = "SELECT * FROM ".$this->tbl_personal_agenda."
1511
                WHERE user = $user_id $startCondition $endCondition";
1512
1513
        $result = Database::query($sql);
1514
        $my_events = [];
1515
        if (Database::num_rows($result)) {
1516
            while ($row = Database::fetch_array($result, 'ASSOC')) {
1517
                $event = [];
1518
                $event['id'] = 'personal_'.$row['id'];
1519
                $event['title'] = $row['title'];
1520
                $event['className'] = 'personal';
1521
                $event['borderColor'] = $event['backgroundColor'] = $this->event_personal_color;
1522
                $event['editable'] = true;
1523
                $event['sent_to'] = get_lang('Me');
1524
                $event['type'] = 'personal';
1525
1526
                if (!empty($row['date'])) {
1527
                    $event['start'] = $this->formatEventDate($row['date']);
1528
                    $event['start_date_localtime'] = api_get_local_time(
1529
                        $row['date']
1530
                    );
1531
                }
1532
1533
                if (!empty($row['enddate'])) {
1534
                    $event['end'] = $this->formatEventDate($row['enddate']);
1535
                    $event['end_date_localtime'] = api_get_local_time(
1536
                        $row['enddate']
1537
                    );
1538
                }
1539
1540
                $event['description'] = $row['text'];
1541
                $event['allDay'] = isset($row['all_day']) && $row['all_day'] == 1 ? $row['all_day'] : 0;
1542
                $event['parent_event_id'] = 0;
1543
                $event['has_children'] = 0;
1544
1545
                $my_events[] = $event;
1546
                $this->events[] = $event;
1547
            }
1548
        }
1549
1550
        return $my_events;
1551
    }
1552
1553
    /**
1554
     * Get user/group list per event.
1555
     *
1556
     * @param int $eventId
1557
     * @param int $courseId
1558
     * @param integer $sessionId
1559
     * @paraù int $sessionId
1560
     *
1561
     * @return array
1562
     */
1563
    public function getUsersAndGroupSubscribedToEvent(
1564
        $eventId,
1565
        $courseId,
1566
        $sessionId
1567
    ) {
1568
        $eventId = intval($eventId);
1569
        $courseId = intval($courseId);
1570
        $sessionId = intval($sessionId);
1571
1572
        $sessionCondition = "ip.session_id = $sessionId";
1573
        if (empty($sessionId)) {
1574
            $sessionCondition = " (ip.session_id = 0 OR ip.session_id IS NULL) ";
1575
        }
1576
1577
        $tlb_course_agenda = Database::get_course_table(TABLE_AGENDA);
1578
        $tbl_property = Database::get_course_table(TABLE_ITEM_PROPERTY);
1579
1580
        // Get sent_tos
1581
        $sql = "SELECT DISTINCT to_user_id, to_group_id
1582
                FROM $tbl_property ip
1583
                INNER JOIN $tlb_course_agenda agenda
1584
                ON (
1585
                  ip.ref = agenda.id AND
1586
                  ip.c_id = agenda.c_id AND
1587
                  ip.tool = '".TOOL_CALENDAR_EVENT."'
1588
                )
1589
                WHERE
1590
                    ref = $eventId AND
1591
                    ip.visibility = '1' AND
1592
                    ip.c_id = $courseId AND
1593
                    $sessionCondition
1594
                ";
1595
1596
        $result = Database::query($sql);
1597
        $users = [];
1598
        $groups = [];
1599
        $everyone = false;
1600
1601
        while ($row = Database::fetch_array($result, 'ASSOC')) {
1602
            if (!empty($row['to_group_id'])) {
1603
                $groups[] = $row['to_group_id'];
1604
            }
1605
            if (!empty($row['to_user_id'])) {
1606
                $users[] = $row['to_user_id'];
1607
            }
1608
1609
            if (empty($groups) && empty($users)) {
1610
                if ($row['to_group_id'] == 0) {
1611
                    $everyone = true;
1612
                }
1613
            }
1614
        }
1615
1616
        return [
1617
            'everyone' => $everyone,
1618
            'users' => $users,
1619
            'groups' => $groups
1620
        ];
1621
    }
1622
1623
    /**
1624
     * @param int $start
1625
     * @param int $end
1626
     * @param int $sessionId
1627
     * @param int $userId
1628
     * @param string $color
1629
     *
1630
     * @return array
1631
     */
1632
    public function getSessionEvents(
1633
        $start,
1634
        $end,
1635
        $sessionId = 0,
1636
        $userId = 0,
0 ignored issues
show
Unused Code introduced by
The parameter $userId is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1636
        /** @scrutinizer ignore-unused */ $userId = 0,

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1637
        $color = ''
1638
    ) {
1639
        $courses = SessionManager::get_course_list_by_session_id($sessionId);
1640
1641
        if (!empty($courses)) {
1642
            foreach ($courses as $course) {
1643
                $this->getCourseEvents(
1644
                    $start,
1645
                    $end,
1646
                    $course,
1647
                    0,
1648
                    $sessionId,
1649
                    0,
1650
                    $color
1651
                );
1652
            }
1653
        }
1654
    }
1655
1656
    /**
1657
     * @param int $start
1658
     * @param int $end
1659
     * @param array $courseInfo
1660
     * @param int $groupId
1661
     * @param int $session_id
1662
     * @param int $user_id
1663
     * @param string $color
1664
     *
1665
     * @return array
1666
     */
1667
    public function getCourseEvents(
1668
        $start,
1669
        $end,
1670
        $courseInfo,
1671
        $groupId = 0,
1672
        $sessionId = 0,
1673
        $user_id = 0,
1674
        $color = ''
1675
    ) {
1676
        $start = isset($start) && !empty($start) ? api_get_utc_datetime(intval($start)) : null;
1677
        $end = isset($end) && !empty($end) ? api_get_utc_datetime(intval($end)) : null;
1678
1679
        if (empty($courseInfo)) {
1680
            return [];
1681
        }
1682
        $courseId = $courseInfo['real_id'];
1683
1684
        if (empty($courseId)) {
1685
            return [];
1686
        }
1687
1688
        $sessionId = intval($sessionId);
1689
        $user_id = intval($user_id);
1690
1691
        $groupList = GroupManager::get_group_list(
1692
            null,
1693
            $courseInfo,
1694
            null,
1695
            $sessionId
1696
        );
1697
1698
        $groupNameList = [];
1699
        if (!empty($groupList)) {
1700
            foreach ($groupList as $group) {
1701
                $groupNameList[$group['iid']] = $group['name'];
1702
            }
1703
        }
1704
1705
        if (api_is_platform_admin() || api_is_allowed_to_edit()) {
1706
            $isAllowToEdit = true;
1707
        } else {
1708
            $isAllowToEdit = CourseManager::is_course_teacher(
1709
                api_get_user_id(),
1710
                $courseInfo['code']
1711
            );
1712
        }
1713
1714
        $isAllowToEditByHrm = false;
1715
        if (!empty($sessionId)) {
1716
            $allowDhrToEdit = api_get_configuration_value('allow_agenda_edit_for_hrm');
1717
            if ($allowDhrToEdit) {
1718
                $isHrm = SessionManager::isUserSubscribedAsHRM($sessionId, api_get_user_id());
1719
                if ($isHrm) {
1720
                    $isAllowToEdit = $isAllowToEditByHrm = true;
1721
                }
1722
            }
1723
        }
1724
1725
        $groupMemberships = [];
1726
        if (!empty($groupId)) {
1727
            $groupMemberships = [$groupId];
1728
        } else {
1729
            if ($isAllowToEdit) {
1730
                if (!empty($groupList)) {
1731
                    // c_item_property.to_group_id field was migrated to use
1732
                    // c_group_info.iid
1733
                    $groupMemberships = array_column($groupList, 'iid');
1734
                }
1735
            } else {
1736
                // get only related groups from user
1737
                $groupMemberships = GroupManager::get_group_ids(
1738
                    $courseId,
1739
                    api_get_user_id()
1740
                );
1741
            }
1742
        }
1743
1744
        $tlb_course_agenda = Database::get_course_table(TABLE_AGENDA);
1745
        $tbl_property = Database::get_course_table(TABLE_ITEM_PROPERTY);
1746
1747
        if (empty($sessionId)) {
1748
            $sessionCondition = "
1749
            (
1750
                agenda.session_id = 0 AND (ip.session_id IS NULL OR ip.session_id = 0)
1751
            ) ";
1752
        } else {
1753
            $sessionCondition = "
1754
            (
1755
                agenda.session_id = $sessionId AND
1756
                ip.session_id = $sessionId
1757
            ) ";
1758
        }
1759
1760
        if ($isAllowToEdit) {
1761
            // No group filter was asked
1762
            if (empty($groupId)) {
1763
                if (empty($user_id)) {
1764
                    // Show all events not added in group
1765
                    $userCondition = ' (ip.to_group_id IS NULL OR ip.to_group_id = 0) ';
1766
                    // admin see only his stuff
1767
                    if ($this->type === 'personal') {
1768
                        $userCondition = " (ip.to_user_id = ".api_get_user_id()." AND (ip.to_group_id IS NULL OR ip.to_group_id = 0) ) ";
1769
                        $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) ) ";
1770
                    }
1771
1772
                    if (!empty($groupMemberships)) {
1773
                        // Show events sent to selected groups
1774
                        $userCondition .= " OR (ip.to_user_id = 0 OR ip.to_user_id is NULL) AND (ip.to_group_id IN (".implode(", ", $groupMemberships).")) ";
1775
                    }
1776
                } else {
1777
                    // Show events of requested user in no group
1778
                    $userCondition = " (ip.to_user_id = $user_id AND (ip.to_group_id IS NULL OR ip.to_group_id = 0)) ";
1779
                    // Show events sent to selected groups
1780
                    if (!empty($groupMemberships)) {
1781
                        $userCondition .= " OR (ip.to_user_id = $user_id) AND (ip.to_group_id IN (".implode(", ", $groupMemberships).")) ";
1782
                    }
1783
                }
1784
            } else {
1785
                // Show only selected groups (depending of user status)
1786
                $userCondition = " (ip.to_user_id = 0 OR ip.to_user_id is NULL) AND (ip.to_group_id IN (".implode(", ", $groupMemberships).")) ";
1787
1788
                if (!empty($groupMemberships)) {
1789
                    // Show send to $user_id in selected groups
1790
                    $userCondition .= " OR (ip.to_user_id = $user_id) AND (ip.to_group_id IN (".implode(", ", $groupMemberships).")) ";
1791
                }
1792
            }
1793
        } else {
1794
            // No group filter was asked
1795
            if (empty($groupId)) {
1796
                // Show events sent to everyone and no group
1797
                $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) ';
1798
1799
                // Show events sent to selected groups
1800
                if (!empty($groupMemberships)) {
1801
                    $userCondition .= " OR (ip.to_user_id = 0 OR ip.to_user_id is NULL) AND (ip.to_group_id IN (".implode(", ", $groupMemberships)."))) ";
1802
                } else {
1803
                    $userCondition .= " ) ";
1804
                }
1805
                $userCondition .= " OR (ip.to_user_id = ".api_get_user_id()." AND (ip.to_group_id IS NULL OR ip.to_group_id = 0)) ";
1806
            } else {
1807
                if (!empty($groupMemberships)) {
1808
                    // Show send to everyone - and only selected groups
1809
                    $userCondition = " (ip.to_user_id = 0 OR ip.to_user_id is NULL) AND (ip.to_group_id IN (".implode(", ", $groupMemberships).")) ";
1810
                }
1811
            }
1812
1813
            // Show sent to only me and no group
1814
            if (!empty($groupMemberships)) {
1815
                $userCondition .= " OR (ip.to_user_id = ".api_get_user_id().") AND (ip.to_group_id IN (".implode(", ", $groupMemberships).")) ";
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $userCondition does not seem to be defined for all execution paths leading up to this point.
Loading history...
1816
            } else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
1817
                // Show sent to only me and selected groups
1818
            }
1819
        }
1820
1821
        if (api_is_allowed_to_edit()) {
1822
            $visibilityCondition = " (ip.visibility IN ('1', '0'))  ";
1823
        } else {
1824
            $visibilityCondition = " (ip.visibility = '1') ";
1825
        }
1826
1827
        $sql = "SELECT DISTINCT
1828
                    agenda.*,
1829
                    ip.visibility,
1830
                    ip.to_group_id,
1831
                    ip.insert_user_id,
1832
                    ip.ref,
1833
                    to_user_id
1834
                FROM $tlb_course_agenda agenda
1835
                INNER JOIN $tbl_property ip
1836
                ON (
1837
                    agenda.id = ip.ref AND 
1838
                    agenda.c_id = ip.c_id AND 
1839
                    ip.tool = '".TOOL_CALENDAR_EVENT."'
1840
                )
1841
                WHERE
1842
                    $sessionCondition AND
1843
                    ($userCondition) AND
1844
                    $visibilityCondition AND
1845
                    agenda.c_id = $courseId
1846
        ";
1847
        $dateCondition = '';
1848
        if (!empty($start) && !empty($end)) {
1849
            $dateCondition .= "AND (
1850
                 agenda.start_date BETWEEN '".$start."' AND '".$end."' OR
1851
                 agenda.end_date BETWEEN '".$start."' AND '".$end."' OR
1852
                 (
1853
                     agenda.start_date IS NOT NULL AND agenda.end_date IS NOT NULL AND
1854
                     YEAR(agenda.start_date) = YEAR(agenda.end_date) AND
1855
                     MONTH('$start') BETWEEN MONTH(agenda.start_date) AND MONTH(agenda.end_date)
1856
                 )
1857
            )";
1858
        }
1859
1860
        $sql .= $dateCondition;
1861
        $result = Database::query($sql);
1862
1863
        $coachCanEdit = false;
1864
        if (!empty($sessionId)) {
1865
            $coachCanEdit = api_is_coach($sessionId, $courseId) || api_is_platform_admin();
1866
        }
1867
1868
        if (Database::num_rows($result)) {
1869
            $eventsAdded = array_column($this->events, 'unique_id');
1870
            while ($row = Database::fetch_array($result, 'ASSOC')) {
1871
                $event = [];
1872
                $event['id'] = 'course_'.$row['id'];
1873
                $event['unique_id'] = $row['iid'];
1874
                // To avoid doubles
1875
                if (in_array($event['unique_id'], $eventsAdded)) {
1876
                    continue;
1877
                }
1878
1879
                $eventsAdded[] = $event['unique_id'];
1880
                $eventId = $row['ref'];
1881
                $items = $this->getUsersAndGroupSubscribedToEvent(
1882
                    $eventId,
1883
                    $courseId,
1884
                    $this->sessionId
1885
                );
1886
                $group_to_array = $items['groups'];
1887
                $user_to_array = $items['users'];
1888
                $attachmentList = $this->getAttachmentList(
1889
                    $row['id'],
1890
                    $courseInfo
1891
                );
1892
                $event['attachment'] = '';
1893
                if (!empty($attachmentList)) {
1894
                    foreach ($attachmentList as $attachment) {
1895
                        $has_attachment = Display::return_icon(
1896
                            'attachment.gif',
1897
                            get_lang('Attachment')
1898
                        );
1899
                        $user_filename = $attachment['filename'];
1900
                        $url = api_get_path(WEB_CODE_PATH).'calendar/download.php?file='.$attachment['path'].'&course_id='.$courseId.'&'.api_get_cidreq();
1901
                        $event['attachment'] .= $has_attachment.
1902
                            Display::url(
1903
                                $user_filename,
1904
                                $url
1905
                            ).'<br />';
1906
                    }
1907
                }
1908
1909
                $event['title'] = $row['title'];
1910
                $event['className'] = 'course';
1911
                $event['allDay'] = 'false';
1912
                $event['course_id'] = $courseId;
1913
                $event['borderColor'] = $event['backgroundColor'] = $this->event_course_color;
1914
1915
                $sessionInfo = [];
1916
                if (isset($row['session_id']) && !empty($row['session_id'])) {
1917
                    $sessionInfo = api_get_session_info($sessionId);
1918
                    $event['borderColor'] = $event['backgroundColor'] = $this->event_session_color;
1919
                }
1920
1921
                $event['session_name'] = isset($sessionInfo['name']) ? $sessionInfo['name'] : '';
1922
                $event['course_name'] = isset($courseInfo['title']) ? $courseInfo['title'] : '';
1923
1924
                if (isset($row['to_group_id']) && !empty($row['to_group_id'])) {
1925
                    $event['borderColor'] = $event['backgroundColor'] = $this->event_group_color;
1926
                }
1927
1928
                if (!empty($color)) {
1929
                    $event['borderColor'] = $event['backgroundColor'] = $color;
1930
                }
1931
1932
                if (isset($row['color']) && !empty($row['color'])) {
1933
                    $event['borderColor'] = $event['backgroundColor'] = $row['color'];
1934
                }
1935
1936
                $event['editable'] = false;
1937
                if ($this->getIsAllowedToEdit() && $this->type == 'course') {
1938
                    $event['editable'] = true;
1939
                    if (!empty($sessionId)) {
1940
                        if ($coachCanEdit == false) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
1941
                            $event['editable'] = false;
1942
                        }
1943
                        if ($isAllowToEditByHrm) {
1944
                            $event['editable'] = true;
1945
                        }
1946
                    }
1947
                    // if user is author then he can edit the item
1948
                    if (api_get_user_id() == $row['insert_user_id']) {
1949
                        $event['editable'] = true;
1950
                    }
1951
                }
1952
1953
                if (!empty($row['start_date'])) {
1954
                    $event['start'] = $this->formatEventDate(
1955
                        $row['start_date']
1956
                    );
1957
                    $event['start_date_localtime'] = api_get_local_time(
1958
                        $row['start_date']
1959
                    );
1960
                }
1961
                if (!empty($row['end_date'])) {
1962
                    $event['end'] = $this->formatEventDate($row['end_date']);
1963
                    $event['end_date_localtime'] = api_get_local_time(
1964
                        $row['end_date']
1965
                    );
1966
                }
1967
1968
                $event['sent_to'] = '';
1969
                $event['type'] = 'course';
1970
                if ($row['session_id'] != 0) {
1971
                    $event['type'] = 'session';
1972
                }
1973
1974
                // Event Sent to a group?
1975
                if (isset($row['to_group_id']) && !empty($row['to_group_id'])) {
1976
                    $sent_to = [];
1977
                    if (!empty($group_to_array)) {
1978
                        foreach ($group_to_array as $group_item) {
1979
                            $sent_to[] = $groupNameList[$group_item];
1980
                        }
1981
                    }
1982
                    $sent_to = implode('@@', $sent_to);
1983
                    $sent_to = str_replace(
1984
                        '@@',
1985
                        '</div><div class="label_tag notice">',
1986
                        $sent_to
1987
                    );
1988
                    $event['sent_to'] = '<div class="label_tag notice">'.$sent_to.'</div>';
1989
                    $event['type'] = 'group';
1990
                }
1991
1992
                // Event sent to a user?
1993
                if (isset($row['to_user_id'])) {
1994
                    $sent_to = [];
1995
                    if (!empty($user_to_array)) {
1996
                        foreach ($user_to_array as $item) {
1997
                            $user_info = api_get_user_info($item);
1998
                            // Add username as tooltip for $event['sent_to'] - ref #4226
1999
                            $username = api_htmlentities(
2000
                                sprintf(
2001
                                    get_lang('LoginX'),
2002
                                    $user_info['username']
2003
                                ),
2004
                                ENT_QUOTES
2005
                            );
2006
                            $sent_to[] = "<span title='".$username."'>".$user_info['complete_name']."</span>";
2007
                        }
2008
                    }
2009
                    $sent_to = implode('@@', $sent_to);
2010
                    $sent_to = str_replace(
2011
                        '@@',
2012
                        '</div><div class="label_tag notice">',
2013
                        $sent_to
2014
                    );
2015
                    $event['sent_to'] = '<div class="label_tag notice">'.$sent_to.'</div>';
2016
                }
2017
2018
                //Event sent to everyone!
2019
                if (empty($event['sent_to'])) {
2020
                    $event['sent_to'] = '<div class="label_tag notice">'.get_lang('Everyone').'</div>';
2021
                }
2022
2023
                $event['description'] = $row['content'];
2024
                $event['visibility'] = $row['visibility'];
2025
                $event['real_id'] = $row['id'];
2026
                $event['allDay'] = isset($row['all_day']) && $row['all_day'] == 1 ? $row['all_day'] : 0;
2027
                $event['parent_event_id'] = $row['parent_event_id'];
2028
                $event['has_children'] = $this->hasChildren($row['id'], $courseId) ? 1 : 0;
2029
                $event['comment'] = $row['comment'];
2030
                $this->events[] = $event;
2031
            }
2032
        }
2033
2034
        return $this->events;
2035
    }
2036
2037
    /**
2038
     * @param int $start tms
2039
     * @param int $end tms
2040
     * @return array
2041
     */
2042
    public function getPlatformEvents($start, $end)
2043
    {
2044
        $start = isset($start) && !empty($start) ? api_get_utc_datetime(intval($start)) : null;
2045
        $end = isset($end) && !empty($end) ? api_get_utc_datetime(intval($end)) : null;
2046
        $dateCondition = '';
2047
2048
        if (!empty($start) && !empty($end)) {
2049
            $dateCondition .= "AND (
2050
                 start_date BETWEEN '".$start."' AND '".$end."' OR
2051
                 end_date BETWEEN '".$start."' AND '".$end."' OR
2052
                 (
2053
                     start_date IS NOT NULL AND end_date IS NOT NULL AND
2054
                     YEAR(start_date) = YEAR(end_date) AND
2055
                     MONTH('$start') BETWEEN MONTH(start_date) AND MONTH(end_date)
2056
                 )
2057
            )";
2058
        }
2059
2060
        $access_url_id = api_get_current_access_url_id();
2061
2062
        $sql = "SELECT *
2063
                FROM ".$this->tbl_global_agenda."
2064
                WHERE access_url_id = $access_url_id
2065
                $dateCondition";
2066
        $result = Database::query($sql);
2067
        $my_events = [];
2068
        if (Database::num_rows($result)) {
2069
            while ($row = Database::fetch_array($result, 'ASSOC')) {
2070
                $event = [];
2071
                $event['id'] = 'platform_'.$row['id'];
2072
                $event['title'] = $row['title'];
2073
                $event['className'] = 'platform';
2074
                $event['allDay'] = 'false';
2075
                $event['borderColor'] = $event['backgroundColor'] = $this->event_platform_color;
2076
                $event['editable'] = false;
2077
                $event['type'] = 'admin';
2078
2079
                if (api_is_platform_admin() && $this->type == 'admin') {
2080
                    $event['editable'] = true;
2081
                }
2082
2083
                if (!empty($row['start_date'])) {
2084
                    $event['start'] = $this->formatEventDate($row['start_date']);
2085
                    $event['start_date_localtime'] = api_get_local_time($row['start_date']);
2086
                }
2087
2088
                if (!empty($row['end_date'])) {
2089
                    $event['end'] = $this->formatEventDate($row['end_date']);
2090
                    $event['end_date_localtime'] = api_get_local_time($row['end_date']);
2091
                }
2092
                $event['allDay'] = isset($row['all_day']) && $row['all_day'] == 1 ? $row['all_day'] : 0;
2093
                $event['parent_event_id'] = 0;
2094
                $event['has_children'] = 0;
2095
                $event['description'] = $row['content'];
2096
2097
                $my_events[] = $event;
2098
                $this->events[] = $event;
2099
            }
2100
        }
2101
2102
        return $my_events;
2103
    }
2104
2105
    /**
2106
     * Format needed for the Fullcalendar js lib
2107
     *
2108
     * @param string $utcTime
2109
     * @return bool|string
2110
     */
2111
    private function formatEventDate($utcTime)
2112
    {
2113
        $utcTimeZone = new DateTimeZone('UTC');
2114
        $platformTimeZone = new DateTimeZone(api_get_timezone());
2115
2116
        $eventDate = new DateTime($utcTime, $utcTimeZone);
2117
        $eventDate->setTimezone($platformTimeZone);
2118
2119
        return $eventDate->format(DateTime::ISO8601);
2120
    }
2121
2122
    /**
2123
     * @param FormValidator $form
2124
     * @param array $groupList
2125
     * @param array $userList
2126
     * @param array $sendTo array('users' => [1, 2], 'groups' => [3, 4])
2127
     * @param array $attributes
2128
     * @param bool $addOnlyItemsInSendTo
2129
     * @param bool $required
2130
     */
2131
    public function setSendToSelect(
2132
        $form,
2133
        $groupList = [],
2134
        $userList = [],
2135
        $sendTo = [],
2136
        $attributes = [],
2137
        $addOnlyItemsInSendTo = false,
2138
        $required = false
2139
    ) {
2140
        $params = [
2141
            'id' => 'users_to_send_id',
2142
            'data-placeholder' => get_lang('Select'),
2143
            'multiple' => 'multiple',
2144
            'class' => 'multiple-select'
2145
        ];
2146
2147
        if (!empty($attributes)) {
2148
            $params = array_merge($params, $attributes);
2149
            if (empty($params['multiple'])) {
2150
                unset($params['multiple']);
2151
            }
2152
        }
2153
2154
        $sendToGroups = isset($sendTo['groups']) ? $sendTo['groups'] : [];
2155
        $sendToUsers = isset($sendTo['users']) ? $sendTo['users'] : [];
2156
2157
        /** @var HTML_QuickForm_select $select */
2158
        $select = $form->addSelect(
2159
            'users_to_send',
2160
            get_lang('To'),
2161
            null,
2162
            $params
2163
        );
2164
2165
        if ($required) {
2166
            $form->setRequired($select);
2167
        }
2168
2169
        $selectedEveryoneOptions = [];
2170
        if (isset($sendTo['everyone']) && $sendTo['everyone']) {
2171
            $selectedEveryoneOptions = ['selected'];
2172
            $sendToUsers = [];
2173
        }
2174
2175
        $select->addOption(
2176
            get_lang('Everyone'),
2177
            'everyone',
2178
            $selectedEveryoneOptions
2179
        );
2180
2181
        $options = [];
2182
        if (is_array($groupList)) {
2183
            foreach ($groupList as $group) {
2184
                $count_users = isset($group['count_users']) ? $group['count_users'] : $group['userNb'];
2185
                $count_users = " &ndash; $count_users ".get_lang('Users');
2186
                $option = [
2187
                    'text' => $group['name'].$count_users,
2188
                    'value' => "GROUP:".$group['id']
2189
                ];
2190
                $selected = in_array(
2191
                    $group['id'],
2192
                    $sendToGroups
2193
                ) ? true : false;
2194
                if ($selected) {
2195
                    $option['selected'] = 'selected';
2196
                }
2197
2198
                if ($addOnlyItemsInSendTo) {
2199
                    if ($selected) {
2200
                        $options[] = $option;
2201
                    }
2202
                } else {
2203
                    $options[] = $option;
2204
                }
2205
            }
2206
            $select->addOptGroup($options, get_lang('Groups'));
2207
        }
2208
2209
        // adding the individual users to the select form
2210
        if (is_array($userList)) {
2211
            $options = [];
2212
            foreach ($userList as $user) {
2213
                if ($user['status'] == ANONYMOUS) {
2214
                    continue;
2215
                }
2216
                $option = [
2217
                    'text' => api_get_person_name(
2218
                            $user['firstname'],
2219
                            $user['lastname']
2220
                        ).' ('.$user['username'].')',
2221
                    'value' => "USER:".$user['user_id']
2222
                ];
2223
2224
                $selected = in_array(
2225
                    $user['user_id'],
2226
                    $sendToUsers
2227
                ) ? true : false;
2228
2229
                if ($selected) {
2230
                    $option['selected'] = 'selected';
2231
                }
2232
2233
                if ($addOnlyItemsInSendTo) {
2234
                    if ($selected) {
2235
                        $options[] = $option;
2236
                    }
2237
                } else {
2238
                    $options[] = $option;
2239
                }
2240
            }
2241
2242
            $select->addOptGroup($options, get_lang('Users'));
2243
        }
2244
    }
2245
2246
    /**
2247
     * Separates the users and groups array
2248
     * users have a value USER:XXX (with XXX the user id
2249
     * groups have a value GROUP:YYY (with YYY the group id)
2250
     * use the 'everyone' key
2251
     * @author Julio Montoya based in separate_users_groups in agenda.inc.php
2252
     * @param array $to
2253
     * @return array
2254
     */
2255
    public function parseSendToArray($to)
2256
    {
2257
        $groupList = [];
2258
        $userList = [];
2259
        $sendTo = null;
2260
2261
        $sendTo['everyone'] = false;
2262
        if (is_array($to) && count($to) > 0) {
2263
            foreach ($to as $item) {
2264
                if ($item == 'everyone') {
2265
                    $sendTo['everyone'] = true;
2266
                } else {
2267
                    list($type, $id) = explode(':', $item);
2268
                    switch ($type) {
2269
                        case 'GROUP':
2270
                            $groupList[] = $id;
2271
                            break;
2272
                        case 'USER':
2273
                            $userList[] = $id;
2274
                            break;
2275
                    }
2276
                }
2277
            }
2278
            $sendTo['groups'] = $groupList;
2279
            $sendTo['users'] = $userList;
2280
        }
2281
2282
        return $sendTo;
2283
    }
2284
2285
    /**
2286
     * @param array $params
2287
     * @return FormValidator
2288
     */
2289
    public function getForm($params = [])
2290
    {
2291
        $action = isset($params['action']) ? Security::remove_XSS($params['action']) : null;
2292
        $id = isset($params['id']) ? intval($params['id']) : null;
2293
2294
        if ($this->type == 'course') {
2295
            $url = api_get_self().'?'.api_get_cidreq().'&action='.$action.'&id='.$id.'&type='.$this->type;
2296
        } else {
2297
            $url = api_get_self().'?action='.$action.'&id='.$id.'&type='.$this->type;
2298
        }
2299
2300
        $form = new FormValidator(
2301
            'add_event',
2302
            'post',
2303
            $url,
2304
            null,
2305
            ['enctype' => 'multipart/form-data']
2306
        );
2307
2308
        $idAttach = isset($params['id_attach']) ? intval(
2309
            $params['id_attach']
2310
        ) : null;
2311
        $groupId = api_get_group_id();
2312
2313
        if ($id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $id of type null|integer is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
2314
            $form_title = get_lang('ModifyCalendarItem');
2315
        } else {
2316
            $form_title = get_lang('AddCalendarItem');
2317
        }
2318
2319
        $form->addElement('header', $form_title);
2320
        $form->addElement('hidden', 'id', $id);
2321
        $form->addElement('hidden', 'action', $action);
2322
        $form->addElement('hidden', 'id_attach', $idAttach);
2323
2324
        $isSubEventEdition = false;
2325
        $isParentFromSerie = false;
2326
        $showAttachmentForm = true;
2327
2328
        if ($this->type == 'course') {
2329
            // Edition mode.
2330
            if (!empty($id)) {
2331
                $showAttachmentForm = false;
2332
                if (isset($params['parent_event_id']) && !empty($params['parent_event_id'])) {
2333
                    $isSubEventEdition = true;
2334
                }
2335
                if (!empty($params['repeat_info'])) {
2336
                    $isParentFromSerie = true;
2337
                }
2338
            }
2339
        }
2340
2341
        if ($isSubEventEdition) {
2342
            $form->addElement(
2343
                'label',
2344
                null,
2345
                Display::return_message(
2346
                    get_lang('EditingThisEventWillRemoveItFromTheSerie'),
2347
                    'warning'
2348
                )
2349
            );
2350
        }
2351
2352
        $form->addElement('text', 'title', get_lang('ItemTitle'));
2353
2354
        if (isset($groupId) && !empty($groupId)) {
2355
            $form->addElement(
2356
                'hidden',
2357
                'users_to_send[]',
2358
                "GROUP:$groupId"
2359
            );
2360
            $form->addElement('hidden', 'to', 'true');
2361
        } else {
2362
            $sendTo = isset($params['send_to']) ? $params['send_to'] : ['everyone' => true];
2363
            if ($this->type == 'course') {
2364
                $this->showToForm($form, $sendTo, [], false, true);
2365
            }
2366
        }
2367
2368
        $form->addDateRangePicker(
2369
            'date_range',
2370
            get_lang('DateRange'),
2371
            false,
2372
            ['id' => 'date_range']
2373
        );
2374
        $form->addElement('checkbox', 'all_day', null, get_lang('AllDay'));
2375
2376
        if ($this->type == 'course') {
2377
            $repeat = $form->addElement(
2378
                'checkbox',
2379
                'repeat',
2380
                null,
2381
                get_lang('RepeatEvent'),
2382
                ['onclick' => 'return plus_repeated_event();']
2383
            );
2384
            $form->addElement(
2385
                'html',
2386
                '<div id="options2" style="display:none">'
2387
            );
2388
            $form->addElement(
2389
                'select',
2390
                'repeat_type',
2391
                get_lang('RepeatType'),
2392
                self::getRepeatTypes()
2393
            );
2394
            $form->addElement(
2395
                'date_picker',
2396
                'repeat_end_day',
2397
                get_lang('RepeatEnd'),
2398
                ['id' => 'repeat_end_date_form']
2399
            );
2400
2401
            if ($isSubEventEdition || $isParentFromSerie) {
2402
                if ($isSubEventEdition) {
2403
                    $parentEvent = $params['parent_info'];
2404
                    $repeatInfo = $parentEvent['repeat_info'];
2405
                } else {
2406
                    $repeatInfo = $params['repeat_info'];
2407
                }
2408
                $params['repeat'] = 1;
2409
                $params['repeat_type'] = $repeatInfo['cal_type'];
2410
                $params['repeat_end_day'] = substr(
2411
                    api_get_local_time($repeatInfo['cal_end']),
2412
                    0,
2413
                    10
2414
                );
2415
2416
                $form->freeze(['repeat_type', 'repeat_end_day']);
2417
                $repeat->_attributes['disabled'] = 'disabled';
2418
            }
2419
            $form->addElement('html', '</div>');
2420
        }
2421
2422
        if (!empty($id)) {
2423
            if (empty($params['end_date'])) {
2424
                $params['date_range'] = $params['end_date'];
2425
            }
2426
2427
            $params['date_range'] =
2428
                substr(api_get_local_time($params['start_date']), 0, 16).' / '.
2429
                substr(api_get_local_time($params['end_date']), 0, 16);
2430
        }
2431
2432
        if (!api_is_allowed_to_edit(null, true)) {
2433
            $toolbar = 'AgendaStudent';
2434
        } else {
2435
            $toolbar = 'Agenda';
2436
        }
2437
2438
        $form->addElement(
2439
            'html_editor',
2440
            'content',
2441
            get_lang('Description'),
2442
            null,
2443
            [
2444
                'ToolbarSet' => $toolbar,
2445
                'Width' => '100%',
2446
                'Height' => '200'
2447
            ]
2448
        );
2449
2450
        if ($this->type == 'course') {
2451
            $form->addElement('textarea', 'comment', get_lang('Comment'));
2452
            $form->addLabel(
2453
                get_lang('FilesAttachment'),
2454
                '<span id="filepaths">
2455
                        <div id="filepath_1">
2456
                            <input type="file" name="attach_1"/><br />
2457
                            '.get_lang('Description').'&nbsp;&nbsp;<input type="text" name="legend[]" /><br /><br />
2458
                        </div>
2459
                    </span>'
2460
            );
2461
2462
            $form->addLabel(
2463
                '',
2464
                '<span id="link-more-attach">
2465
                    <a href="javascript://" onclick="return add_image_form()">'.
2466
                get_lang('AddOneMoreFile').'</a>
2467
                 </span>&nbsp;('.sprintf(
2468
                    get_lang('MaximunFileSizeX'),
2469
                    format_file_size(
2470
                        api_get_setting('message_max_upload_filesize')
2471
                    )
2472
                ).')'
2473
            );
2474
2475
            if (isset($params['attachment']) && !empty($params['attachment'])) {
2476
                $attachmentList = $params['attachment'];
2477
                foreach ($attachmentList as $attachment) {
2478
                    $params['file_comment'] = $attachment['comment'];
2479
                    if (!empty($attachment['path'])) {
2480
                        $form->addElement(
2481
                            'checkbox',
2482
                            'delete_attachment['.$attachment['id'].']',
2483
                            null,
2484
                            get_lang(
2485
                                'DeleteAttachment'
2486
                            ).': '.$attachment['filename']
2487
                        );
2488
                    }
2489
                }
2490
            }
2491
2492
            $form->addElement(
2493
                'textarea',
2494
                'file_comment',
2495
                get_lang('FileComment')
2496
            );
2497
        }
2498
2499
        if (empty($id)) {
2500
            $form->addElement(
2501
                'checkbox',
2502
                'add_announcement',
2503
                null,
2504
                get_lang('AddAnnouncement').'&nbsp('.get_lang('SendMail').')'
2505
            );
2506
        }
2507
2508
        if ($id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $id of type null|integer is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
2509
            $form->addButtonUpdate(get_lang('ModifyEvent'));
2510
        } else {
2511
            $form->addButtonSave(get_lang('AgendaAdd'));
2512
        }
2513
2514
        $form->setDefaults($params);
2515
2516
        $form->addRule(
2517
            'date_range',
2518
            get_lang('ThisFieldIsRequired'),
2519
            'required'
2520
        );
2521
        $form->addRule('title', get_lang('ThisFieldIsRequired'), 'required');
2522
2523
        return $form;
2524
    }
2525
2526
    /**
2527
     * @param FormValidator $form
2528
     * @param array $sendTo array('everyone' => false, 'users' => [1, 2], 'groups' => [3, 4])
2529
     * @param array $attributes
2530
     * @param bool $addOnlyItemsInSendTo
2531
     * @param bool $required
2532
     * @return bool
2533
     */
2534
    public function showToForm(
2535
        $form,
2536
        $sendTo = [],
2537
        $attributes = [],
2538
        $addOnlyItemsInSendTo = false,
2539
        $required = false
2540
    ) {
2541
        if ($this->type != 'course') {
2542
            return false;
2543
        }
2544
2545
        $order = 'lastname';
2546
        if (api_is_western_name_order()) {
2547
            $order = 'firstname';
2548
        }
2549
2550
        $userList = CourseManager::get_user_list_from_course_code(
2551
            api_get_course_id(),
2552
            $this->sessionId,
2553
            null,
2554
            $order
2555
        );
2556
2557
        $groupList = CourseManager::get_group_list_of_course(
2558
            api_get_course_id(),
2559
            $this->sessionId
2560
        );
2561
2562
        $this->setSendToSelect(
2563
            $form,
2564
            $groupList,
2565
            $userList,
0 ignored issues
show
Bug introduced by
It seems like $userList can also be of type integer; however, parameter $userList of Agenda::setSendToSelect() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

2565
            /** @scrutinizer ignore-type */ $userList,
Loading history...
2566
            $sendTo,
2567
            $attributes,
2568
            $addOnlyItemsInSendTo,
2569
            $required
2570
        );
2571
2572
        return true;
2573
    }
2574
2575
    /**
2576
     * @param int $id
2577
     * @param int $visibility 0= invisible, 1 visible
2578
     * @param array $courseInfo
2579
     * @param int $userId
2580
     */
2581
    public static function changeVisibility(
2582
        $id,
2583
        $visibility,
2584
        $courseInfo,
2585
        $userId = null
2586
    ) {
2587
        $id = intval($id);
2588
        if (empty($userId)) {
2589
            $userId = api_get_user_id();
2590
        } else {
2591
            $userId = intval($userId);
2592
        }
2593
2594
        if ($visibility == 0) {
2595
            api_item_property_update(
2596
                $courseInfo,
2597
                TOOL_CALENDAR_EVENT,
2598
                $id,
2599
                'invisible',
2600
                $userId
2601
            );
2602
        } else {
2603
            api_item_property_update(
2604
                $courseInfo,
2605
                TOOL_CALENDAR_EVENT,
2606
                $id,
2607
                'visible',
2608
                $userId
2609
            );
2610
        }
2611
    }
2612
2613
    /**
2614
     * Get repeat types
2615
     * @return array
2616
     */
2617
    public static function getRepeatTypes()
2618
    {
2619
        return [
2620
            'daily' => get_lang('RepeatDaily'),
2621
            'weekly' => get_lang('RepeatWeekly'),
2622
            'monthlyByDate' => get_lang('RepeatMonthlyByDate'),
2623
            //monthlyByDay"> get_lang('RepeatMonthlyByDay');
2624
            //monthlyByDayR' => get_lang('RepeatMonthlyByDayR'),
2625
            'yearly' => get_lang('RepeatYearly')
2626
        ];
2627
    }
2628
2629
    /**
2630
     * Show a list with all the attachments according to the post's id
2631
     * @param int $eventId
2632
     * @param array $courseInfo
2633
     * @return array with the post info
2634
     */
2635
    public function getAttachmentList($eventId, $courseInfo)
2636
    {
2637
        $tableAttachment = Database::get_course_table(TABLE_AGENDA_ATTACHMENT);
2638
        $courseId = intval($courseInfo['real_id']);
2639
        $eventId = intval($eventId);
2640
2641
        $sql = "SELECT id, path, filename, comment
2642
                FROM $tableAttachment
2643
                WHERE
2644
                    c_id = $courseId AND
2645
                    agenda_id = $eventId";
2646
        $result = Database::query($sql);
2647
        $list = [];
2648
        if (Database::num_rows($result) != 0) {
2649
            $list = Database::store_result($result, 'ASSOC');
2650
        }
2651
2652
        return $list;
2653
    }
2654
2655
    /**
2656
     * Show a list with all the attachments according to the post's id
2657
     * @param int $attachmentId
2658
     * @param int $eventId
2659
     * @param array $courseInfo
2660
     * @return array with the post info
2661
     */
2662
    public function getAttachment($attachmentId, $eventId, $courseInfo)
2663
    {
2664
        $tableAttachment = Database::get_course_table(TABLE_AGENDA_ATTACHMENT);
2665
        $courseId = intval($courseInfo['real_id']);
2666
        $eventId = intval($eventId);
2667
        $attachmentId = intval($attachmentId);
2668
2669
        $row = [];
2670
        $sql = "SELECT id, path, filename, comment
2671
                FROM $tableAttachment
2672
                WHERE
2673
                    c_id = $courseId AND
2674
                    agenda_id = $eventId AND
2675
                    id = $attachmentId
2676
                ";
2677
        $result = Database::query($sql);
2678
        if (Database::num_rows($result) != 0) {
2679
            $row = Database::fetch_array($result, 'ASSOC');
2680
        }
2681
2682
        return $row;
2683
    }
2684
2685
    /**
2686
     * Add an attachment file into agenda
2687
     * @param int $eventId
2688
     * @param array $fileUserUpload ($_FILES['user_upload'])
2689
     * @param string $comment about file
2690
     * @param array $courseInfo
2691
     * @return string
2692
     */
2693
    public function addAttachment(
2694
        $eventId,
2695
        $fileUserUpload,
2696
        $comment,
2697
        $courseInfo
2698
    ) {
2699
        $agenda_table_attachment = Database::get_course_table(
2700
            TABLE_AGENDA_ATTACHMENT
2701
        );
2702
        $eventId = intval($eventId);
2703
2704
        // Storing the attachments
2705
        $upload_ok = false;
2706
        if (!empty($fileUserUpload['name'])) {
2707
            $upload_ok = process_uploaded_file($fileUserUpload);
2708
        }
2709
2710
        if (!empty($upload_ok)) {
2711
            $courseDir = $courseInfo['directory'].'/upload/calendar';
2712
            $sys_course_path = api_get_path(SYS_COURSE_PATH);
2713
            $uploadDir = $sys_course_path.$courseDir;
2714
2715
            // Try to add an extension to the file if it hasn't one
2716
            $new_file_name = add_ext_on_mime(
2717
                stripslashes($fileUserUpload['name']),
2718
                $fileUserUpload['type']
2719
            );
2720
2721
            // user's file name
2722
            $file_name = $fileUserUpload['name'];
2723
2724
            if (!filter_extension($new_file_name)) {
2725
                return Display::return_message(
2726
                    get_lang('UplUnableToSaveFileFilteredExtension'),
2727
                    'error'
2728
                );
2729
            } else {
2730
                $new_file_name = uniqid('');
2731
                $new_path = $uploadDir.'/'.$new_file_name;
2732
                $result = @move_uploaded_file(
2733
                    $fileUserUpload['tmp_name'],
2734
                    $new_path
2735
                );
2736
                $course_id = api_get_course_int_id();
2737
                $size = intval($fileUserUpload['size']);
2738
                // Storing the attachments if any
2739
                if ($result) {
2740
                    $params = [
2741
                        'c_id' => $course_id,
2742
                        'filename' => $file_name,
2743
                        'comment' => $comment,
2744
                        'path' => $new_file_name,
2745
                        'agenda_id' => $eventId,
2746
                        'size' => $size
2747
                    ];
2748
                    $id = Database::insert($agenda_table_attachment, $params);
2749
                    if ($id) {
2750
                        $sql = "UPDATE $agenda_table_attachment
2751
                                SET id = iid WHERE iid = $id";
2752
                        Database::query($sql);
2753
2754
                        api_item_property_update(
2755
                            $courseInfo,
2756
                            'calendar_event_attachment',
2757
                            $id,
2758
                            'AgendaAttachmentAdded',
2759
                            api_get_user_id()
2760
                        );
2761
                    }
2762
                }
2763
            }
2764
        }
2765
    }
2766
2767
    /**
2768
     * @param int $attachmentId
2769
     * @param int $eventId
2770
     * @param array $fileUserUpload
2771
     * @param string $comment
2772
     * @param array $courseInfo
2773
     */
2774
    public function updateAttachment(
2775
        $attachmentId,
2776
        $eventId,
2777
        $fileUserUpload,
2778
        $comment,
2779
        $courseInfo
2780
    ) {
2781
        $attachment = $this->getAttachment(
2782
            $attachmentId,
2783
            $eventId,
2784
            $courseInfo
2785
        );
2786
        if (!empty($attachment)) {
2787
            $this->deleteAttachmentFile($attachmentId, $courseInfo);
2788
        }
2789
        $this->addAttachment($eventId, $fileUserUpload, $comment, $courseInfo);
2790
    }
2791
2792
    /**
2793
     * This function delete a attachment file by id
2794
     * @param int $attachmentId
2795
     * @param array $courseInfo
2796
     * @return string
2797
     */
2798
    public function deleteAttachmentFile($attachmentId, $courseInfo)
2799
    {
2800
        $agenda_table_attachment = Database::get_course_table(
2801
            TABLE_AGENDA_ATTACHMENT
2802
        );
2803
        $attachmentId = intval($attachmentId);
2804
        $courseId = $courseInfo['real_id'];
2805
2806
        if (empty($courseId) || empty($attachmentId)) {
2807
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type string.
Loading history...
2808
        }
2809
2810
        $sql = "DELETE FROM $agenda_table_attachment
2811
                WHERE c_id = $courseId AND id = ".$attachmentId;
2812
        $result = Database::query($sql);
2813
2814
        // update item_property
2815
        api_item_property_update(
2816
            $courseInfo,
2817
            'calendar_event_attachment',
2818
            $attachmentId,
2819
            'AgendaAttachmentDeleted',
2820
            api_get_user_id()
2821
        );
2822
2823
        if (!empty($result)) {
2824
            return Display::return_message(
2825
                get_lang("AttachmentFileDeleteSuccess"),
2826
                'confirmation'
2827
            );
2828
        }
2829
    }
2830
2831
    /**
2832
     * Adds x weeks to a UNIX timestamp
2833
     * @param   int     The timestamp
2834
     * @param   int     The number of weeks to add
2835
     * @param integer $timestamp
2836
     * @return  int     The new timestamp
2837
     */
2838
    public function addWeek($timestamp, $num = 1)
2839
    {
2840
        return $timestamp + $num * 604800;
2841
    }
2842
2843
    /**
2844
     * Adds x months to a UNIX timestamp
2845
     * @param   int     The timestamp
2846
     * @param   int     The number of years to add
2847
     * @param integer $timestamp
2848
     * @return  int     The new timestamp
2849
     */
2850
    public function addMonth($timestamp, $num = 1)
2851
    {
2852
        list($y, $m, $d, $h, $n, $s) = split(
0 ignored issues
show
Deprecated Code introduced by
The function split() has been deprecated: 5.3.0 Use preg_split() instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

2852
        list($y, $m, $d, $h, $n, $s) = /** @scrutinizer ignore-deprecated */ split(

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
2853
            '/',
2854
            date('Y/m/d/h/i/s', $timestamp)
2855
        );
2856
        if ($m + $num > 12) {
2857
            $y += floor($num / 12);
2858
            $m += $num % 12;
2859
        } else {
2860
            $m += $num;
2861
        }
2862
2863
        return mktime($h, $n, $s, $m, $d, $y);
2864
    }
2865
2866
    /**
2867
     * Adds x years to a UNIX timestamp
2868
     * @param   int     The timestamp
2869
     * @param   int     The number of years to add
2870
     * @param integer $timestamp
2871
     * @return  int     The new timestamp
2872
     */
2873
    public function addYear($timestamp, $num = 1)
2874
    {
2875
        list($y, $m, $d, $h, $n, $s) = split(
0 ignored issues
show
Deprecated Code introduced by
The function split() has been deprecated: 5.3.0 Use preg_split() instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

2875
        list($y, $m, $d, $h, $n, $s) = /** @scrutinizer ignore-deprecated */ split(

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
2876
            '/',
2877
            date('Y/m/d/h/i/s', $timestamp)
2878
        );
2879
2880
        return mktime($h, $n, $s, $m, $d, $y + $num);
2881
    }
2882
2883
    /**
2884
     * @param int $eventId
2885
     * @return array
2886
     */
2887
    public function getAllRepeatEvents($eventId)
2888
    {
2889
        $events = [];
2890
        switch ($this->type) {
2891
            case 'personal':
2892
                break;
2893
            case 'course':
2894
                if (!empty($this->course['real_id'])) {
2895
                    $sql = "SELECT * FROM ".$this->tbl_course_agenda."
2896
                            WHERE
2897
                                c_id = ".$this->course['real_id']." AND
2898
                                parent_event_id = ".$eventId;
2899
                    $result = Database::query($sql);
2900
                    if (Database::num_rows($result)) {
2901
                        while ($row = Database::fetch_array($result, 'ASSOC')) {
2902
                            $events[] = $row;
2903
                        }
2904
                    }
2905
                }
2906
                break;
2907
        }
2908
2909
        return $events;
2910
    }
2911
2912
    /**
2913
     * @param int $eventId
2914
     * @param int $courseId
2915
     *
2916
     * @return bool
2917
     */
2918
    public function hasChildren($eventId, $courseId)
2919
    {
2920
        $eventId = intval($eventId);
2921
        $courseId = intval($courseId);
2922
2923
        $sql = "SELECT count(DISTINCT(id)) as count
2924
                FROM ".$this->tbl_course_agenda."
2925
                WHERE
2926
                    c_id = $courseId AND
2927
                    parent_event_id = $eventId";
2928
        $result = Database::query($sql);
2929
        if (Database::num_rows($result)) {
2930
            $row = Database::fetch_array($result, 'ASSOC');
2931
2932
            return $row['count'] > 0;
2933
        }
2934
2935
        return false;
2936
    }
2937
2938
    /**
2939
     * @param int $filter
2940
     * @param string $view
2941
     * @return string
2942
     */
2943
    public function displayActions($view, $filter = 0)
2944
    {
2945
        $courseInfo = api_get_course_info();
2946
        $groupInfo = GroupManager::get_group_properties(api_get_group_id());
2947
        $groupIid = isset($groupInfo['iid']) ? $groupInfo['iid'] : 0;
2948
2949
        $courseCondition = '';
2950
        if (!empty($courseInfo)) {
2951
            $courseCondition = api_get_cidreq();
2952
        }
2953
2954
        $actionsLeft = '';
2955
        $actionsLeft .= "<a href='".api_get_path(WEB_CODE_PATH)."calendar/agenda_js.php?type={$this->type}&".$courseCondition."'>".
2956
            Display::return_icon(
2957
                'calendar.png',
2958
                get_lang('Calendar'),
2959
                '',
2960
                ICON_SIZE_MEDIUM
2961
            )."</a>";
2962
2963
        $actionsLeft .= "<a href='".api_get_path(WEB_CODE_PATH)."calendar/agenda_list.php?type={$this->type}&".$courseCondition."'>".
2964
            Display::return_icon(
2965
                'week.png',
2966
                get_lang('AgendaList'),
2967
                '',
2968
                ICON_SIZE_MEDIUM
2969
            )."</a>";
2970
2971
        $form = '';
2972
        if (api_is_allowed_to_edit(false, true) ||
2973
            (api_get_course_setting('allow_user_edit_agenda') == '1' &&
2974
                !api_is_anonymous()) &&
2975
            api_is_allowed_to_session_edit(false, true) ||
2976
            (GroupManager::user_has_access(
2977
                api_get_user_id(),
2978
                $groupIid,
2979
                GroupManager::GROUP_TOOL_CALENDAR
2980
            ) &&
2981
            GroupManager::is_tutor_of_group(api_get_user_id(), $groupInfo))
2982
        ) {
2983
            $actionsLeft .= Display::url(
2984
                Display::return_icon(
2985
                    'new_event.png',
2986
                    get_lang('AgendaAdd'),
2987
                    '',
2988
                    ICON_SIZE_MEDIUM
2989
                ),
2990
                api_get_path(WEB_CODE_PATH)."calendar/agenda.php?".api_get_cidreq()."&action=add&type=".$this->type
2991
            );
2992
2993
            $actionsLeft .= Display::url(
2994
                Display::return_icon(
2995
                    'import_calendar.png',
2996
                    get_lang('ICalFileImport'),
2997
                    '',
2998
                    ICON_SIZE_MEDIUM
2999
                ),
3000
                api_get_path(WEB_CODE_PATH)."calendar/agenda.php?".api_get_cidreq()."&action=importical&type=".$this->type
3001
            );
3002
3003
            if ($this->type === 'course') {
3004
                if (!isset($_GET['action'])) {
3005
                    $form = new FormValidator(
3006
                        'form-search',
3007
                        'post',
3008
                        '',
3009
                        '',
3010
                        [],
3011
                        FormValidator::LAYOUT_INLINE
3012
                    );
3013
                    $attributes = [
3014
                        'multiple' => false,
3015
                        'id' => 'select_form_id_search'
3016
                    ];
3017
                    $selectedValues = $this->parseAgendaFilter($filter);
3018
                    $this->showToForm($form, $selectedValues, $attributes);
3019
                    $form = $form->returnForm();
3020
                }
3021
            }
3022
        }
3023
3024
        if (api_is_platform_admin() ||
3025
            api_is_teacher() ||
3026
            api_is_student_boss() ||
3027
            api_is_drh() ||
3028
            api_is_session_admin() ||
3029
            api_is_coach()
3030
        ) {
3031
            if ($this->type == 'personal') {
3032
                $form = null;
3033
                if (!isset($_GET['action'])) {
3034
                    $form = new FormValidator(
3035
                        'form-search',
3036
                        'get',
3037
                        api_get_self().'?type=personal&',
3038
                        '',
3039
                        [],
3040
                        FormValidator::LAYOUT_INLINE
3041
                    );
3042
3043
                    if (api_is_drh()) {
3044
                        $sessionList = SessionManager::get_sessions_followed_by_drh(
3045
                            api_get_user_id()
3046
                        );
3047
                        if (!empty($sessionList)) {
3048
                            $sessions = [];
3049
                            foreach ($sessionList as $sessionItem) {
3050
                                $sessions[$sessionItem['id']] = strip_tags($sessionItem['name']);
3051
                            }
3052
                        }
3053
                    } else {
3054
                        $sessions = SessionManager::get_sessions_by_user(
3055
                            api_get_user_id()
3056
                        );
3057
                        $sessions = array_column(
3058
                            $sessions,
3059
                            'session_name',
3060
                            'session_id'
3061
                        );
3062
                    }
3063
                    $form->addHidden('type', 'personal');
3064
                    $sessions = ['0' => get_lang('SelectAnOption')] + $sessions;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $sessions does not seem to be defined for all execution paths leading up to this point.
Loading history...
3065
3066
                    $form->addSelect(
3067
                        'session_id',
3068
                        get_lang('Session'),
3069
                        $sessions,
3070
                        ['id' => 'session_id', 'onchange' => 'submit();']
3071
                    );
3072
3073
                    $form->addButtonReset(get_lang('Reset'));
3074
                    $form = $form->returnForm();
3075
                }
3076
            }
3077
        }
3078
3079
        $actionsRight = '';
3080
        if ($view == 'calendar') {
3081
            $actionsRight .= $form;
3082
        }
3083
3084
        $toolbar = Display::toolbarAction(
3085
            'toolbar-agenda',
3086
            [$actionsLeft, $actionsRight]
3087
        );
3088
3089
        return $toolbar;
3090
    }
3091
3092
    /**
3093
     * @return FormValidator
3094
     */
3095
    public function getImportCalendarForm()
3096
    {
3097
        $form = new FormValidator(
3098
            'frm_import_ical',
3099
            'post',
3100
            api_get_self().'?action=importical&type='.$this->type,
3101
            ['enctype' => 'multipart/form-data']
3102
        );
3103
        $form->addElement('header', get_lang('ICalFileImport'));
3104
        $form->addElement('file', 'ical_import', get_lang('ICalFileImport'));
3105
        $form->addRule(
3106
            'ical_import',
3107
            get_lang('ThisFieldIsRequired'),
3108
            'required'
3109
        );
3110
        $form->addButtonImport(get_lang('Import'), 'ical_submit');
3111
3112
        return $form;
3113
    }
3114
3115
    /**
3116
     * @param array $courseInfo
3117
     * @param $file
3118
     * @return false|string
3119
     */
3120
    public function importEventFile($courseInfo, $file)
0 ignored issues
show
Unused Code introduced by
The parameter $courseInfo is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

3120
    public function importEventFile(/** @scrutinizer ignore-unused */ $courseInfo, $file)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
3121
    {
3122
        $charset = api_get_system_encoding();
3123
        $filepath = api_get_path(SYS_ARCHIVE_PATH).$file['name'];
3124
        $messages = [];
3125
3126
        if (!@move_uploaded_file($file['tmp_name'], $filepath)) {
3127
            error_log(
3128
                'Problem moving uploaded file: '.$file['error'].' in '.__FILE__.' line '.__LINE__
3129
            );
3130
3131
            return false;
3132
        }
3133
3134
        $data = file_get_contents($filepath);
3135
3136
        $trans = [
3137
            'DAILY' => 'daily',
3138
            'WEEKLY' => 'weekly',
3139
            'MONTHLY' => 'monthlyByDate',
3140
            'YEARLY' => 'yearly'
3141
        ];
3142
        $sentTo = ['everyone' => true];
3143
        $calendar = Sabre\VObject\Reader::read($data);
3144
        $currentTimeZone = api_get_timezone();
3145
        if (!empty($calendar->VEVENT)) {
3146
            foreach ($calendar->VEVENT as $event) {
3147
                $start = $event->DTSTART->getDateTime();
3148
                $end = $event->DTEND->getDateTime();
3149
                //Sabre\VObject\DateTimeParser::parseDateTime(string $dt, \Sabre\VObject\DateTimeZone $tz)
3150
3151
                $startDateTime = api_get_local_time(
3152
                    $start->format('Y-m-d H:i:s'),
3153
                    $currentTimeZone,
3154
                    $start->format('e')
3155
                );
3156
                $endDateTime = api_get_local_time(
3157
                    $end->format('Y-m-d H:i'),
3158
                    $currentTimeZone,
3159
                    $end->format('e')
3160
                );
3161
                $title = api_convert_encoding(
3162
                    (string) $event->summary,
3163
                    $charset,
3164
                    'UTF-8'
3165
                );
3166
                $description = api_convert_encoding(
3167
                    (string) $event->description,
3168
                    $charset,
3169
                    'UTF-8'
3170
                );
3171
3172
                $id = $this->addEvent(
3173
                    $startDateTime,
3174
                    $endDateTime,
3175
                    'false',
3176
                    $title,
3177
                    $description,
3178
                    $sentTo
3179
                );
3180
3181
                $messages[] = " $title - ".$startDateTime." - ".$endDateTime;
3182
3183
                //$attendee = (string)$event->attendee;
3184
                /** @var Sabre\VObject\Property\ICalendar\Recur $repeat */
3185
                $repeat = $event->RRULE;
3186
                if ($id && !empty($repeat)) {
3187
                    $repeat = $repeat->getParts();
3188
                    $freq = $trans[$repeat['FREQ']];
3189
3190
                    if (isset($repeat['UNTIL']) && !empty($repeat['UNTIL'])) {
3191
                        // Check if datetime or just date (strlen == 8)
3192
                        if (strlen($repeat['UNTIL']) == 8) {
3193
                            // Fix the datetime format to avoid exception in the next step
3194
                            $repeat['UNTIL'] .= 'T000000';
3195
                        }
3196
                        $until = Sabre\VObject\DateTimeParser::parseDateTime(
3197
                            $repeat['UNTIL'],
3198
                            new DateTimeZone($currentTimeZone)
3199
                        );
3200
                        $until = $until->format('Y-m-d H:i');
3201
                        //$res = agenda_add_repeat_item($courseInfo, $id, $freq, $until, $attendee);
3202
                        $this->addRepeatedItem(
3203
                            $id,
3204
                            $freq,
3205
                            $until,
3206
                            $sentTo
3207
                        );
3208
                    }
3209
3210
                    if (!empty($repeat['COUNT'])) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
3211
                        /*$count = $repeat['COUNT'];
3212
                        $interval = $repeat['INTERVAL'];
3213
                        $endDate = null;
3214
                        switch($freq) {
3215
                            case 'daily':
3216
                                $start = api_strtotime($startDateTime);
3217
                                $date = new DateTime($startDateTime);
3218
                                $days = $count * $interval;
3219
                                var_dump($days);
3220
                                $date->add(new DateInterval("P".$days."D"));
3221
                                $endDate = $date->format('Y-m-d H:i');
3222
                                //$endDate = $count *
3223
                                for ($i = 0; $i < $count; $i++) {
3224
                                    $days = 86400 * 7
3225
                                }
3226
                            }
3227
                        }*/
3228
                        //$res = agenda_add_repeat_item($courseInfo, $id, $freq, $count, $attendee);
3229
                        /*$this->addRepeatedItem(
3230
                            $id,
3231
                            $freq,
3232
                            $endDate,
3233
                            $sentTo
3234
                        );*/
3235
                    }
3236
                }
3237
            }
3238
        }
3239
3240
        if (!empty($messages)) {
3241
            $messages = implode('<br /> ', $messages);
3242
        } else {
3243
            $messages = get_lang('NoAgendaItems');
3244
        }
3245
3246
        return $messages;
3247
    }
3248
3249
    /**
3250
     * Parse filter turns USER:12 to ['users' => [12])] or G:1 ['groups' => [1]]
3251
     * @param integer $filter
3252
     * @return array
3253
     */
3254
    public function parseAgendaFilter($filter)
3255
    {
3256
        $everyone = false;
3257
        $groupId = null;
3258
        $userId = null;
3259
3260
        if ($filter == 'everyone') {
3261
            $everyone = true;
3262
        } else {
3263
            if (substr($filter, 0, 1) == 'G') {
3264
                $groupId = str_replace('GROUP:', '', $filter);
3265
            } else {
3266
                $userId = str_replace('USER:', '', $filter);
3267
            }
3268
        }
3269
        if (empty($userId) && empty($groupId)) {
3270
            $everyone = true;
3271
        }
3272
3273
        return [
3274
            'everyone' => $everyone,
3275
            'users' => [$userId],
3276
            'groups' => [$groupId]
3277
        ];
3278
    }
3279
3280
    /**
3281
     *    This function retrieves all the agenda items of all the courses the user is subscribed to
3282
     */
3283
    public static function get_myagendaitems(
3284
        $user_id,
3285
        $courses_dbs,
3286
        $month,
3287
        $year
3288
    ) {
3289
        $user_id = intval($user_id);
3290
3291
        $items = [];
3292
        $my_list = [];
3293
3294
        // get agenda-items for every course
3295
        foreach ($courses_dbs as $key => $array_course_info) {
3296
            //databases of the courses
3297
            $TABLEAGENDA = Database::get_course_table(TABLE_AGENDA);
3298
            $TABLE_ITEMPROPERTY = Database::get_course_table(
3299
                TABLE_ITEM_PROPERTY
3300
            );
3301
3302
            $group_memberships = GroupManager::get_group_ids(
3303
                $array_course_info['real_id'],
3304
                $user_id
3305
            );
3306
            $course_user_status = CourseManager::getUserInCourseStatus(
3307
                $user_id,
3308
                $array_course_info['real_id']
3309
            );
3310
            // if the user is administrator of that course we show all the agenda items
3311
            if ($course_user_status == '1') {
3312
                //echo "course admin";
3313
                $sqlquery = "SELECT DISTINCT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref
3314
							FROM ".$TABLEAGENDA." agenda,
3315
								 ".$TABLE_ITEMPROPERTY." ip
3316
							WHERE agenda.id = ip.ref
3317
							AND MONTH(agenda.start_date)='".$month."'
3318
							AND YEAR(agenda.start_date)='".$year."'
3319
							AND ip.tool='".TOOL_CALENDAR_EVENT."'
3320
							AND ip.visibility='1'
3321
							GROUP BY agenda.id
3322
							ORDER BY start_date ";
3323
            } else {
3324
                // if the user is not an administrator of that course
3325
                if (is_array($group_memberships) && count(
3326
                        $group_memberships
3327
                    ) > 0
3328
                ) {
3329
                    $sqlquery = "SELECT	agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref
3330
								FROM ".$TABLEAGENDA." agenda,
3331
									".$TABLE_ITEMPROPERTY." ip
3332
								WHERE agenda.id = ip.ref
3333
								AND MONTH(agenda.start_date)='".$month."'
3334
								AND YEAR(agenda.start_date)='".$year."'
3335
								AND ip.tool='".TOOL_CALENDAR_EVENT."'
3336
								AND	( ip.to_user_id='".$user_id."' OR (ip.to_group_id IS NULL OR ip.to_group_id IN (0, ".implode(
3337
                            ", ",
3338
                            $group_memberships
3339
                        ).")) )
3340
								AND ip.visibility='1'
3341
								ORDER BY start_date ";
3342
                } else {
3343
                    $sqlquery = "SELECT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref
3344
								FROM ".$TABLEAGENDA." agenda,
3345
									".$TABLE_ITEMPROPERTY." ip
3346
								WHERE agenda.id = ip.ref
3347
								AND MONTH(agenda.start_date)='".$month."'
3348
								AND YEAR(agenda.start_date)='".$year."'
3349
								AND ip.tool='".TOOL_CALENDAR_EVENT."'
3350
								AND ( ip.to_user_id='".$user_id."' OR ip.to_group_id='0' OR ip.to_group_id IS NULL)
3351
								AND ip.visibility='1'
3352
								ORDER BY start_date ";
3353
                }
3354
            }
3355
            $result = Database::query($sqlquery);
3356
3357
            while ($item = Database::fetch_array($result, 'ASSOC')) {
3358
                $agendaday = -1;
3359
                if (!empty($item['start_date'])) {
3360
                    $item['start_date'] = api_get_local_time(
3361
                        $item['start_date']
3362
                    );
3363
                    $item['start_date_tms'] = api_strtotime(
3364
                        $item['start_date']
3365
                    );
3366
                    $agendaday = date("j", $item['start_date_tms']);
3367
                }
3368
                if (!empty($item['end_date'])) {
3369
                    $item['end_date'] = api_get_local_time($item['end_date']);
3370
                }
3371
3372
                $url = api_get_path(
3373
                        WEB_CODE_PATH
3374
                    )."calendar/agenda.php?cidReq=".urlencode(
3375
                        $array_course_info["code"]
3376
                    )."&day=$agendaday&month=$month&year=$year#$agendaday";
3377
3378
                $item['url'] = $url;
3379
                $item['course_name'] = $array_course_info['title'];
3380
                $item['calendar_type'] = 'course';
3381
                $item['course_id'] = $array_course_info['course_id'];
3382
3383
                $my_list[$agendaday][] = $item;
3384
            }
3385
        }
3386
3387
        // sorting by hour for every day
3388
        $agendaitems = [];
3389
        while (list($agendaday, $tmpitems) = each($items)) {
0 ignored issues
show
Deprecated Code introduced by
The function each() has been deprecated: 7.2 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

3389
        while (list($agendaday, $tmpitems) = /** @scrutinizer ignore-deprecated */ each($items)) {

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
3390
            if (!isset($agendaitems[$agendaday])) {
3391
                $agendaitems[$agendaday] = '';
3392
            }
3393
            sort($tmpitems);
3394
            while (list($key, $val) = each($tmpitems)) {
0 ignored issues
show
Deprecated Code introduced by
The function each() has been deprecated: 7.2 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

3394
            while (list($key, $val) = /** @scrutinizer ignore-deprecated */ each($tmpitems)) {

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
3395
                $agendaitems[$agendaday] .= $val;
3396
            }
3397
        }
3398
3399
        return $my_list;
3400
    }
3401
3402
    /**
3403
     * This function retrieves one personal agenda item returns it.
3404
     * @param    array    The array containing existing events. We add to this array.
3405
     * @param    int        Day
3406
     * @param    int        Month
3407
     * @param    int        Year (4 digits)
3408
     * @param    int        Week number
3409
     * @param    string    Type of view (month_view, week_view, day_view)
3410
     * @return    array    The results of the database query, or null if not found
3411
     */
3412
    public static function get_global_agenda_items(
3413
        $agendaitems,
3414
        $day = "",
3415
        $month = "",
3416
        $year = "",
3417
        $week = "",
3418
        $type
3419
    ) {
3420
        $tbl_global_agenda = Database::get_main_table(
3421
            TABLE_MAIN_SYSTEM_CALENDAR
3422
        );
3423
        $month = intval($month);
3424
        $year = intval($year);
3425
        $week = intval($week);
3426
        $day = intval($day);
3427
        // 1. creating the SQL statement for getting the personal agenda items in MONTH view
3428
3429
        $current_access_url_id = api_get_current_access_url_id();
3430
3431
        if ($type == "month_view" or $type == "") {
3432
            // We are in month view
3433
            $sql = "SELECT * FROM ".$tbl_global_agenda." WHERE MONTH(start_date) = ".$month." AND YEAR(start_date) = ".$year."  AND access_url_id = $current_access_url_id ORDER BY start_date ASC";
3434
        }
3435
        // 2. creating the SQL statement for getting the personal agenda items in WEEK view
3436
        if ($type == "week_view") { // we are in week view
3437
            $start_end_day_of_week = self::calculate_start_end_of_week(
3438
                $week,
3439
                $year
3440
            );
3441
            $start_day = $start_end_day_of_week['start']['day'];
3442
            $start_month = $start_end_day_of_week['start']['month'];
3443
            $start_year = $start_end_day_of_week['start']['year'];
3444
            $end_day = $start_end_day_of_week['end']['day'];
3445
            $end_month = $start_end_day_of_week['end']['month'];
3446
            $end_year = $start_end_day_of_week['end']['year'];
3447
            // in sql statements you have to use year-month-day for date calculations
3448
            $start_filter = $start_year."-".$start_month."-".$start_day." 00:00:00";
3449
            $start_filter = api_get_utc_datetime($start_filter);
3450
3451
            $end_filter = $end_year."-".$end_month."-".$end_day." 23:59:59";
3452
            $end_filter = api_get_utc_datetime($end_filter);
3453
            $sql = " SELECT * FROM ".$tbl_global_agenda." WHERE start_date>='".$start_filter."' AND start_date<='".$end_filter."' AND  access_url_id = $current_access_url_id ";
3454
        }
3455
        // 3. creating the SQL statement for getting the personal agenda items in DAY view
3456
        if ($type == "day_view") { // we are in day view
3457
            // we could use mysql date() function but this is only available from 4.1 and higher
3458
            $start_filter = $year."-".$month."-".$day." 00:00:00";
3459
            $start_filter = api_get_utc_datetime($start_filter);
3460
3461
            $end_filter = $year."-".$month."-".$day." 23:59:59";
3462
            $end_filter = api_get_utc_datetime($end_filter);
3463
            $sql = " SELECT * FROM ".$tbl_global_agenda." WHERE start_date>='".$start_filter."' AND start_date<='".$end_filter."'  AND  access_url_id = $current_access_url_id";
3464
        }
3465
3466
        $result = Database::query($sql);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $sql does not seem to be defined for all execution paths leading up to this point.
Loading history...
3467
3468
        while ($item = Database::fetch_array($result)) {
3469
            if (!empty($item['start_date'])) {
3470
                $item['start_date'] = api_get_local_time($item['start_date']);
3471
                $item['start_date_tms'] = api_strtotime($item['start_date']);
3472
            }
3473
            if (!empty($item['end_date'])) {
3474
                $item['end_date'] = api_get_local_time($item['end_date']);
3475
            }
3476
3477
            // we break the date field in the database into a date and a time part
3478
            $agenda_db_date = explode(" ", $item['start_date']);
3479
            $date = $agenda_db_date[0];
3480
            $time = $agenda_db_date[1];
3481
            // we divide the date part into a day, a month and a year
3482
            $agendadate = explode("-", $date);
3483
            $year = intval($agendadate[0]);
3484
            $month = intval($agendadate[1]);
3485
            $day = intval($agendadate[2]);
3486
            // we divide the time part into hour, minutes, seconds
3487
            $agendatime = explode(":", $time);
3488
            $hour = $agendatime[0];
3489
            $minute = $agendatime[1];
3490
            $second = $agendatime[2];
3491
3492
            if ($type == 'month_view') {
3493
                $item['calendar_type'] = 'global';
3494
                $agendaitems[$day][] = $item;
3495
                continue;
3496
            }
3497
3498
            $start_time = api_format_date(
3499
                $item['start_date'],
3500
                TIME_NO_SEC_FORMAT
3501
            );
3502
            $end_time = '';
3503
            if (!empty($item['end_date'])) {
3504
                $end_time = ' - '.api_format_date(
3505
                        $item['end_date'],
3506
                        DATE_TIME_FORMAT_LONG
3507
                    );
3508
            }
3509
3510
            // if the student has specified a course we a add a link to that course
3511
            if ($item['course'] <> "") {
3512
                $url = api_get_path(
3513
                        WEB_CODE_PATH
3514
                    )."admin/agenda.php?cidReq=".urlencode(
3515
                        $item['course']
3516
                    )."&day=$day&month=$month&year=$year#$day"; // RH  //Patrick Cool: to highlight the relevant agenda item
3517
                $course_link = "<a href=\"$url\" title=\"".$item['course']."\">".$item['course']."</a>";
3518
            } else {
3519
                $course_link = "";
3520
            }
3521
            // Creating the array that will be returned. If we have week or month view we have an array with the date as the key
3522
            // if we have a day_view we use a half hour as index => key 33 = 16h30
3523
            if ($type !== "day_view") {
3524
                // This is the array construction for the WEEK or MONTH view
3525
                //Display the Agenda global in the tab agenda (administrator)
3526
                $agendaitems[$day] .= "<i>$start_time $end_time</i>&nbsp;-&nbsp;";
3527
                $agendaitems[$day] .= "<b>".get_lang('GlobalEvent')."</b>";
3528
                $agendaitems[$day] .= "<div>".$item['title']."</div><br>";
3529
            } else {
3530
                // this is the array construction for the DAY view
3531
                $halfhour = 2 * $agendatime['0'];
3532
                if ($agendatime['1'] >= '30') {
3533
                    $halfhour = $halfhour + 1;
3534
                }
3535
                if (!is_array($agendaitems[$halfhour])) {
3536
                    $content = $agendaitems[$halfhour];
3537
                }
3538
                $agendaitems[$halfhour] = $content."<div><i>$hour:$minute</i> <b>".get_lang(
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $content does not seem to be defined for all execution paths leading up to this point.
Loading history...
3539
                        'GlobalEvent'
3540
                    ).":  </b>".$item['title']."</div>";
3541
            }
3542
        }
3543
3544
        return $agendaitems;
3545
    }
3546
3547
    /**
3548
     * This function retrieves all the personal agenda items and add them to the agenda items found by the other functions.
3549
     */
3550
    public static function get_personal_agenda_items(
3551
        $user_id,
3552
        $agendaitems,
3553
        $day = "",
3554
        $month = "",
3555
        $year = "",
3556
        $week = "",
3557
        $type
3558
    ) {
3559
        $tbl_personal_agenda = Database::get_main_table(TABLE_PERSONAL_AGENDA);
3560
        $user_id = intval($user_id);
3561
3562
        // 1. creating the SQL statement for getting the personal agenda items in MONTH view
3563
        if ($type == "month_view" or $type == "") {
3564
            // we are in month view
3565
            $sql = "SELECT * FROM ".$tbl_personal_agenda." WHERE user='".$user_id."' and MONTH(date)='".$month."' AND YEAR(date) = '".$year."'  ORDER BY date ASC";
3566
        }
3567
3568
        // 2. creating the SQL statement for getting the personal agenda items in WEEK view
3569
        // we are in week view
3570
        if ($type == "week_view") {
3571
            $start_end_day_of_week = self::calculate_start_end_of_week(
3572
                $week,
3573
                $year
3574
            );
3575
            $start_day = $start_end_day_of_week['start']['day'];
3576
            $start_month = $start_end_day_of_week['start']['month'];
3577
            $start_year = $start_end_day_of_week['start']['year'];
3578
            $end_day = $start_end_day_of_week['end']['day'];
3579
            $end_month = $start_end_day_of_week['end']['month'];
3580
            $end_year = $start_end_day_of_week['end']['year'];
3581
            // in sql statements you have to use year-month-day for date calculations
3582
            $start_filter = $start_year."-".$start_month."-".$start_day." 00:00:00";
3583
            $start_filter = api_get_utc_datetime($start_filter);
3584
            $end_filter = $end_year."-".$end_month."-".$end_day." 23:59:59";
3585
            $end_filter = api_get_utc_datetime($end_filter);
3586
            $sql = " SELECT * FROM ".$tbl_personal_agenda." WHERE user='".$user_id."' AND date>='".$start_filter."' AND date<='".$end_filter."'";
3587
        }
3588
        // 3. creating the SQL statement for getting the personal agenda items in DAY view
3589
        if ($type == "day_view") {
3590
            // we are in day view
3591
            // we could use mysql date() function but this is only available from 4.1 and higher
3592
            $start_filter = $year."-".$month."-".$day." 00:00:00";
3593
            $start_filter = api_get_utc_datetime($start_filter);
3594
            $end_filter = $year."-".$month."-".$day." 23:59:59";
3595
            $end_filter = api_get_utc_datetime($end_filter);
3596
            $sql = " SELECT * FROM ".$tbl_personal_agenda." WHERE user='".$user_id."' AND date>='".$start_filter."' AND date<='".$end_filter."'";
3597
        }
3598
3599
        $result = Database::query($sql);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $sql does not seem to be defined for all execution paths leading up to this point.
Loading history...
3600
        while ($item = Database::fetch_array($result, 'ASSOC')) {
3601
            $time_minute = api_convert_and_format_date(
3602
                $item['date'],
3603
                TIME_NO_SEC_FORMAT
3604
            );
3605
            $item['date'] = api_get_local_time($item['date']);
3606
            $item['start_date_tms'] = api_strtotime($item['date']);
3607
            $item['content'] = $item['text'];
3608
3609
            // we break the date field in the database into a date and a time part
3610
            $agenda_db_date = explode(" ", $item['date']);
3611
            $date = $agenda_db_date[0];
3612
            $time = $agenda_db_date[1];
3613
            // we divide the date part into a day, a month and a year
3614
            $agendadate = explode("-", $item['date']);
3615
            $year = intval($agendadate[0]);
3616
            $month = intval($agendadate[1]);
3617
            $day = intval($agendadate[2]);
3618
            // we divide the time part into hour, minutes, seconds
3619
            $agendatime = explode(":", $time);
3620
3621
            $hour = $agendatime[0];
3622
            $minute = $agendatime[1];
3623
            $second = $agendatime[2];
3624
3625
            if ($type == 'month_view') {
3626
                $item['calendar_type'] = 'personal';
3627
                $item['start_date'] = $item['date'];
3628
                $agendaitems[$day][] = $item;
3629
                continue;
3630
            }
3631
3632
            // if the student has specified a course we a add a link to that course
3633
            if ($item['course'] <> "") {
3634
                $url = api_get_path(
3635
                        WEB_CODE_PATH
3636
                    )."calendar/agenda.php?cidReq=".urlencode(
3637
                        $item['course']
3638
                    )."&day=$day&month=$month&year=$year#$day"; // RH  //Patrick Cool: to highlight the relevant agenda item
3639
                $course_link = "<a href=\"$url\" title=\"".$item['course']."\">".$item['course']."</a>";
3640
            } else {
3641
                $course_link = "";
3642
            }
3643
            // Creating the array that will be returned. If we have week or month view we have an array with the date as the key
3644
            // if we have a day_view we use a half hour as index => key 33 = 16h30
3645
            if ($type !== "day_view") {
3646
                // This is the array construction for the WEEK or MONTH view
3647
3648
                //Display events in agenda
3649
                $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 />";
3650
            } else {
3651
                // this is the array construction for the DAY view
3652
                $halfhour = 2 * $agendatime['0'];
3653
                if ($agendatime['1'] >= '30') {
3654
                    $halfhour = $halfhour + 1;
3655
                }
3656
3657
                //Display events by list
3658
                $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>";
3659
            }
3660
        }
3661
3662
        return $agendaitems;
3663
    }
3664
3665
3666
    /**
3667
     * Show the monthcalender of the given month
3668
     * @param    array    Agendaitems
3669
     * @param    int    Month number
3670
     * @param    int    Year number
3671
     * @param    array    Array of strings containing long week day names (deprecated, you can send an empty array instead)
3672
     * @param    string    The month name
3673
     * @return    void    Direct output
3674
     */
3675
    public static function display_mymonthcalendar(
3676
        $user_id,
3677
        $agendaitems,
3678
        $month,
3679
        $year,
3680
        $weekdaynames = [],
0 ignored issues
show
Unused Code introduced by
The parameter $weekdaynames is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

3680
        /** @scrutinizer ignore-unused */ $weekdaynames = [],

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
3681
        $monthName,
3682
        $show_content = true
3683
    ) {
3684
        global $DaysShort, $course_path;
3685
        //Handle leap year
3686
        $numberofdays = [
3687
            0,
3688
            31,
3689
            28,
3690
            31,
3691
            30,
3692
            31,
3693
            30,
3694
            31,
3695
            31,
3696
            30,
3697
            31,
3698
            30,
3699
            31
3700
        ];
3701
        if (($year % 400 == 0) or ($year % 4 == 0 and $year % 100 <> 0)) {
3702
            $numberofdays[2] = 29;
3703
        }
3704
        //Get the first day of the month
3705
        $dayone = getdate(mktime(0, 0, 0, $month, 1, $year));
3706
        //Start the week on monday
3707
        $startdayofweek = $dayone['wday'] <> 0 ? ($dayone['wday'] - 1) : 6;
3708
        $g_cc = (isset($_GET['courseCode']) ? $_GET['courseCode'] : '');
3709
3710
        $next_month = ($month == 1 ? 12 : $month - 1);
3711
        $prev_month = ($month == 12 ? 1 : $month + 1);
3712
3713
        $next_year = ($month == 1 ? $year - 1 : $year);
3714
        $prev_year = ($month == 12 ? $year + 1 : $year);
3715
3716
        if ($show_content) {
3717
            $back_url = Display::url(
3718
                get_lang('Previous'),
3719
                api_get_self()."?coursePath=".urlencode(
3720
                    $course_path
3721
                )."&courseCode=".Security::remove_XSS(
3722
                    $g_cc
3723
                )."&action=view&view=month&month=".$next_month."&year=".$next_year
3724
            );
3725
            $next_url = Display::url(
3726
                get_lang('Next'),
3727
                api_get_self()."?coursePath=".urlencode(
3728
                    $course_path
3729
                )."&courseCode=".Security::remove_XSS(
3730
                    $g_cc
3731
                )."&action=view&view=month&month=".$prev_month."&year=".$prev_year
3732
            );
3733
        } else {
3734
            $back_url = Display::url(
3735
                get_lang('Previous'),
3736
                '',
3737
                [
3738
                    'onclick' => "load_calendar('".$user_id."','".$next_month."', '".$next_year."'); ",
3739
                    'class' => 'btn ui-button ui-widget ui-state-default'
3740
                ]
3741
            );
3742
            $next_url = Display::url(
3743
                get_lang('Next'),
3744
                '',
3745
                [
3746
                    'onclick' => "load_calendar('".$user_id."','".$prev_month."', '".$prev_year."'); ",
3747
                    'class' => 'pull-right btn ui-button ui-widget ui-state-default'
3748
                ]
3749
            );
3750
        }
3751
        $html = '';
3752
        $html .= '<div class="actions">';
3753
        $html .= '<div class="row">';
3754
        $html .= '<div class="col-md-4">'.$back_url.'</div>';
3755
        $html .= '<div class="col-md-4"><p class="agenda-title text-center">'.$monthName." ".$year.'</p></div>';
3756
        $html .= '<div class="col-md-4">'.$next_url.'</div>';
3757
        $html .= '</div>';
3758
        $html .= '</div>';
3759
        $html .= '<table id="agenda_list2" class="table table-bordered">';
3760
        $html .= '<tr>';
3761
        for ($ii = 1; $ii < 8; $ii++) {
3762
            $html .= '<td class="weekdays">'.$DaysShort[$ii % 7].'</td>';
3763
        }
3764
        $html .= '</tr>';
3765
3766
        $curday = -1;
3767
        $today = getdate();
3768
        while ($curday <= $numberofdays[$month]) {
3769
            $html .= "<tr>";
3770
            for ($ii = 0; $ii < 7; $ii++) {
3771
                if (($curday == -1) && ($ii == $startdayofweek)) {
3772
                    $curday = 1;
3773
                }
3774
                if (($curday > 0) && ($curday <= $numberofdays[$month])) {
3775
                    $bgcolor = $class = 'class="days_week"';
3776
                    $dayheader = Display::div(
3777
                        $curday,
3778
                        ['class' => 'agenda_day']
3779
                    );
3780
                    if (($curday == $today['mday']) && ($year == $today['year']) && ($month == $today['mon'])) {
3781
                        $class = "class=\"days_today\" style=\"width:10%;\"";
3782
                    }
3783
3784
                    $html .= "<td ".$class.">".$dayheader;
3785
3786
                    if (!empty($agendaitems[$curday])) {
3787
                        $items = $agendaitems[$curday];
3788
                        $items = msort($items, 'start_date_tms');
3789
3790
                        foreach ($items as $value) {
3791
                            $value['title'] = Security::remove_XSS(
3792
                                $value['title']
3793
                            );
3794
                            $start_time = api_format_date(
3795
                                $value['start_date'],
3796
                                TIME_NO_SEC_FORMAT
3797
                            );
3798
                            $end_time = '';
3799
3800
                            if (!empty($value['end_date'])) {
3801
                                $end_time = '-&nbsp;<i>'.api_format_date(
3802
                                        $value['end_date'],
3803
                                        DATE_TIME_FORMAT_LONG
3804
                                    ).'</i>';
3805
                            }
3806
                            $complete_time = '<i>'.api_format_date(
3807
                                    $value['start_date'],
3808
                                    DATE_TIME_FORMAT_LONG
3809
                                ).'</i>&nbsp;'.$end_time;
3810
                            $time = '<i>'.$start_time.'</i>';
3811
3812
                            switch ($value['calendar_type']) {
3813
                                case 'personal':
3814
                                    $bg_color = '#D0E7F4';
3815
                                    $icon = Display::return_icon(
3816
                                        'user.png',
3817
                                        get_lang('MyAgenda'),
3818
                                        [],
3819
                                        ICON_SIZE_SMALL
3820
                                    );
3821
                                    break;
3822
                                case 'global':
3823
                                    $bg_color = '#FFBC89';
3824
                                    $icon = Display::return_icon(
3825
                                        'view_remove.png',
3826
                                        get_lang('GlobalEvent'),
3827
                                        [],
3828
                                        ICON_SIZE_SMALL
3829
                                    );
3830
                                    break;
3831
                                case 'course':
3832
                                    $bg_color = '#CAFFAA';
3833
                                    $icon_name = 'course.png';
3834
                                    if (!empty($value['session_id'])) {
3835
                                        $icon_name = 'session.png';
3836
                                    }
3837
                                    if ($show_content) {
3838
                                        $icon = Display::url(
3839
                                            Display::return_icon(
3840
                                                $icon_name,
3841
                                                $value['course_name'].' '.get_lang(
3842
                                                    'Course'
3843
                                                ),
3844
                                                [],
3845
                                                ICON_SIZE_SMALL
3846
                                            ),
3847
                                            $value['url']
3848
                                        );
3849
                                    } else {
3850
                                        $icon = Display::return_icon(
3851
                                            $icon_name,
3852
                                            $value['course_name'].' '.get_lang(
3853
                                                'Course'
3854
                                            ),
3855
                                            [],
3856
                                            ICON_SIZE_SMALL
3857
                                        );
3858
                                    }
3859
                                    break;
3860
                                default:
3861
                                    break;
3862
                            }
3863
3864
                            $result = '<div class="rounded_div_agenda" style="background-color:'.$bg_color.';">';
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $bg_color does not seem to be defined for all execution paths leading up to this point.
Loading history...
3865
3866
                            if ($show_content) {
3867
3868
                                //Setting a personal event to green
3869
                                $icon = Display::div(
3870
                                    $icon,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $icon does not seem to be defined for all execution paths leading up to this point.
Loading history...
3871
                                    ['style' => 'float:right']
3872
                                );
3873
3874
                                $link = $value['calendar_type'].'_'.$value['id'].'_'.$value['course_id'].'_'.$value['session_id'];
3875
3876
                                //Link to bubble
3877
                                $url = Display::url(
3878
                                    cut($value['title'], 40),
3879
                                    '#',
3880
                                    ['id' => $link, 'class' => 'opener']
3881
                                );
3882
                                $result .= $time.' '.$icon.' '.Display::div(
3883
                                        $url
3884
                                    );
3885
3886
                                //Hidden content
3887
                                $content = Display::div(
3888
                                    $icon.Display::tag(
3889
                                        'h2',
3890
                                        $value['course_name']
3891
                                    ).'<hr />'.Display::tag(
3892
                                        'h3',
3893
                                        $value['title']
3894
                                    ).$complete_time.'<hr />'.Security::remove_XSS(
3895
                                        $value['content']
3896
                                    )
3897
                                );
3898
3899
                                //Main div
3900
                                $result .= Display::div(
3901
                                    $content,
3902
                                    [
3903
                                        'id' => 'main_'.$link,
3904
                                        'class' => 'dialog',
3905
                                        'style' => 'display:none'
3906
                                    ]
3907
                                );
3908
                                $result .= '</div>';
3909
                                $html .= $result;
3910
                                //echo Display::div($content, array('id'=>'main_'.$value['calendar_type'].'_'.$value['id'], 'class' => 'dialog'));
3911
                            } else {
3912
                                $html .= $result .= $icon.'</div>';
3913
                            }
3914
                        }
3915
                    }
3916
                    $html .= "</td>";
3917
                    $curday++;
3918
                } else {
3919
                    $html .= "<td></td>";
3920
                }
3921
            }
3922
            $html .= "</tr>";
3923
        }
3924
        $html .= "</table>";
3925
        echo $html;
3926
    }
3927
3928
    /**
3929
     * Get personal agenda items between two dates (=all events from all registered courses)
3930
     * @param    int        $user_id user ID of the user
3931
     * @param    string    Optional start date in datetime format (if no start date is given, uses today)
3932
     * @param    string    Optional end date in datetime format (if no date is given, uses one year from now)
3933
     * @return    array    Array of events ordered by start date, in
3934
     * [0]('datestart','dateend','title'),[1]('datestart','dateend','title','link','coursetitle') format,
3935
     * where datestart and dateend are in yyyyMMddhhmmss format.
3936
     * @deprecated use agenda events
3937
     */
3938
    public static function get_personal_agenda_items_between_dates(
3939
        $user_id,
3940
        $date_start = '',
3941
        $date_end = ''
3942
    ) {
3943
        $items = [];
3944
        if ($user_id != strval(intval($user_id))) {
3945
            return $items;
3946
        }
3947
        if (empty($date_start)) {
3948
            $date_start = date('Y-m-d H:i:s');
3949
        }
3950
        if (empty($date_end)) {
3951
            $date_end = date(
3952
                'Y-m-d H:i:s',
3953
                mktime(0, 0, 0, date("m"), date("d"), date("Y") + 1)
3954
            );
3955
        }
3956
        $expr = '/\d{4}-\d{2}-\d{2}\ \d{2}:\d{2}:\d{2}/';
3957
        if (!preg_match($expr, $date_start)) {
3958
            return $items;
3959
        }
3960
        if (!preg_match($expr, $date_end)) {
3961
            return $items;
3962
        }
3963
3964
        // get agenda-items for every course
3965
        $courses = api_get_user_courses($user_id, false);
0 ignored issues
show
Deprecated Code introduced by
The function api_get_user_courses() has been deprecated: use CourseManager::get_courses_list_by_user_id() ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

3965
        $courses = /** @scrutinizer ignore-deprecated */ api_get_user_courses($user_id, false);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
3966
        foreach ($courses as $id => $course) {
3967
            $c = api_get_course_info_by_id($course['real_id']);
3968
            //databases of the courses
3969
            $t_a = Database::get_course_table(TABLE_AGENDA, $course['db']);
3970
            $t_ip = Database::get_course_table(
3971
                TABLE_ITEM_PROPERTY,
3972
                $course['db']
3973
            );
3974
            // get the groups to which the user belong
3975
            $group_memberships = GroupManager:: get_group_ids(
3976
                $course['db'],
3977
                $user_id
3978
            );
3979
            // if the user is administrator of that course we show all the agenda items
3980
            if ($course['status'] == '1') {
3981
                //echo "course admin";
3982
                $sqlquery = "SELECT ".
3983
                    " DISTINCT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref ".
3984
                    " FROM ".$t_a." agenda, ".
3985
                    $t_ip." ip ".
3986
                    " WHERE agenda.id = ip.ref ".
3987
                    " AND agenda.start_date>='$date_start' ".
3988
                    " AND agenda.end_date<='$date_end' ".
3989
                    " AND ip.tool='".TOOL_CALENDAR_EVENT."' ".
3990
                    " AND ip.visibility='1' ".
3991
                    " GROUP BY agenda.id ".
3992
                    " ORDER BY start_date ";
3993
            } else {
3994
                // if the user is not an administrator of that course, then...
3995
                if (is_array($group_memberships) && count(
3996
                        $group_memberships
3997
                    ) > 0
3998
                ) {
3999
                    $sqlquery = "SELECT ".
4000
                        "DISTINCT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref ".
4001
                        " FROM ".$t_a." agenda, ".
4002
                        $t_ip." ip ".
4003
                        " WHERE agenda.id = ip.ref ".
4004
                        " AND agenda.start_date>='$date_start' ".
4005
                        " AND agenda.end_date<='$date_end' ".
4006
                        " AND ip.tool='".TOOL_CALENDAR_EVENT."' ".
4007
                        " AND	( ip.to_user_id='".$user_id."' OR (ip.to_group_id IS NULL OR ip.to_group_id IN (0, ".implode(
4008
                            ", ",
4009
                            $group_memberships
4010
                        ).")) ) ".
4011
                        " AND ip.visibility='1' ".
4012
                        " ORDER BY start_date ";
4013
                } else {
4014
                    $sqlquery = "SELECT ".
4015
                        "DISTINCT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref ".
4016
                        " FROM ".$t_a." agenda, ".
4017
                        $t_ip." ip ".
4018
                        " WHERE agenda.id = ip.ref ".
4019
                        " AND agenda.start_date>='$date_start' ".
4020
                        " AND agenda.end_date<='$date_end' ".
4021
                        " AND ip.tool='".TOOL_CALENDAR_EVENT."' ".
4022
                        " AND ( ip.to_user_id='".$user_id."' OR ip.to_group_id='0' OR ip.to_group_id IS NULL) ".
4023
                        " AND ip.visibility='1' ".
4024
                        " ORDER BY start_date ";
4025
                }
4026
            }
4027
4028
            $result = Database::query($sqlquery);
4029
            while ($item = Database::fetch_array($result)) {
4030
                $agendaday = date("j", strtotime($item['start_date']));
4031
                $month = date("n", strtotime($item['start_date']));
4032
                $year = date("Y", strtotime($item['start_date']));
4033
                $URL = api_get_path(
4034
                        WEB_PATH
4035
                    )."main/calendar/agenda.php?cidReq=".urlencode(
4036
                        $course["code"]
4037
                    )."&day=$agendaday&month=$month&year=$year#$agendaday";
4038
                list($year, $month, $day, $hour, $min, $sec) = split(
0 ignored issues
show
Deprecated Code introduced by
The function split() has been deprecated: 5.3.0 Use preg_split() instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

4038
                list($year, $month, $day, $hour, $min, $sec) = /** @scrutinizer ignore-deprecated */ split(

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
4039
                    '[-: ]',
4040
                    $item['start_date']
4041
                );
4042
                $start_date = $year.$month.$day.$hour.$min;
4043
                list($year, $month, $day, $hour, $min, $sec) = split(
0 ignored issues
show
Deprecated Code introduced by
The function split() has been deprecated: 5.3.0 Use preg_split() instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

4043
                list($year, $month, $day, $hour, $min, $sec) = /** @scrutinizer ignore-deprecated */ split(

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
4044
                    '[-: ]',
4045
                    $item['end_date']
4046
                );
4047
                $end_date = $year.$month.$day.$hour.$min;
4048
4049
                $items[] = [
4050
                    'datestart' => $start_date,
4051
                    'dateend' => $end_date,
4052
                    'title' => $item['title'],
4053
                    'link' => $URL,
4054
                    'coursetitle' => $c['name'],
4055
                ];
4056
            }
4057
        }
4058
4059
        return $items;
4060
    }
4061
4062
    /**
4063
     * This function retrieves one personal agenda item returns it.
4064
     * @param    int $id The agenda item ID
4065
     * @return    array    The results of the database query, or null if not found
4066
     */
4067
    public static function get_personal_agenda_item($id)
4068
    {
4069
        $tbl_personal_agenda = Database::get_main_table(TABLE_PERSONAL_AGENDA);
4070
        $id = intval($id);
4071
        // make sure events of the personal agenda can only be seen by the user himself
4072
        $user = api_get_user_id();
4073
        $sql = " SELECT * FROM ".$tbl_personal_agenda." WHERE id=".$id." AND user = ".$user;
4074
        $result = Database::query($sql);
4075
        if (Database::num_rows($result) == 1) {
4076
            $item = Database::fetch_array($result);
4077
        } else {
4078
            $item = null;
4079
        }
4080
4081
        return $item;
4082
    }
4083
4084
    /**
4085
     * This function calculates the startdate of the week (monday)
4086
     * and the enddate of the week (sunday)
4087
     * and returns it as an array
4088
     */
4089
    public static function calculate_start_end_of_week($week_number, $year)
4090
    {
4091
        // determine the start and end date
4092
        // step 1: we calculate a timestamp for a day in this week
4093
        $random_day_in_week = mktime(
4094
                0,
4095
                0,
4096
                0,
4097
                1,
4098
                1,
4099
                $year
4100
            ) + ($week_number) * (7 * 24 * 60 * 60); // we calculate a random day in this week
4101
        // step 2: we which day this is (0=sunday, 1=monday, ...)
4102
        $number_day_in_week = date('w', $random_day_in_week);
4103
        // step 3: we calculate the timestamp of the monday of the week we are in
4104
        $start_timestamp = $random_day_in_week - (($number_day_in_week - 1) * 24 * 60 * 60);
4105
        // step 4: we calculate the timestamp of the sunday of the week we are in
4106
        $end_timestamp = $random_day_in_week + ((7 - $number_day_in_week + 1) * 24 * 60 * 60) - 3600;
4107
        // step 5: calculating the start_day, end_day, start_month, end_month, start_year, end_year
4108
        $start_day = date('j', $start_timestamp);
4109
        $start_month = date('n', $start_timestamp);
4110
        $start_year = date('Y', $start_timestamp);
4111
        $end_day = date('j', $end_timestamp);
4112
        $end_month = date('n', $end_timestamp);
4113
        $end_year = date('Y', $end_timestamp);
4114
        $start_end_array['start']['day'] = $start_day;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$start_end_array was never initialized. Although not strictly required by PHP, it is generally a good practice to add $start_end_array = array(); before regardless.
Loading history...
4115
        $start_end_array['start']['month'] = $start_month;
4116
        $start_end_array['start']['year'] = $start_year;
4117
        $start_end_array['end']['day'] = $end_day;
4118
        $start_end_array['end']['month'] = $end_month;
4119
        $start_end_array['end']['year'] = $end_year;
4120
4121
        return $start_end_array;
4122
    }
4123
4124
    /**
4125
     * @return bool
4126
     */
4127
    public function getIsAllowedToEdit()
4128
    {
4129
        return $this->isAllowedToEdit;
4130
    }
4131
4132
    /**
4133
     * @param bool $isAllowedToEdit
4134
     */
4135
    public function setIsAllowedToEdit($isAllowedToEdit)
4136
    {
4137
        $this->isAllowedToEdit = $isAllowedToEdit;
4138
    }
4139
4140
    /**
4141
     * @param int $userId
4142
     * @param array $event
4143
     *
4144
     * @return bool
4145
     */
4146
    public function sendEmail($userId, $event)
0 ignored issues
show
Unused Code introduced by
The parameter $event is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

4146
    public function sendEmail($userId, /** @scrutinizer ignore-unused */ $event)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
4147
    {
4148
        $userInfo = api_get_user_info($userId);
4149
4150
        if (!empty($this->sessionInfo)) {
4151
            $courseTitle = $this->course['name'].' ('.$this->sessionInfo['title'].')';
4152
        } else {
4153
            $courseTitle = $this->course['name'];
4154
        }
4155
4156
        api_mail_html(
4157
            $userInfo['complete_name'],
4158
            $userInfo['mail'],
4159
            $subject,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $subject seems to be never defined.
Loading history...
4160
            $emailBody
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $emailBody seems to be never defined.
Loading history...
4161
        );
4162
4163
        return true;
4164
    }
4165
}
4166