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

SystemAnnouncementManager::add_announcement()   D

Complexity

Conditions 16
Paths 115

Size

Total Lines 143
Code Lines 82

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 82
c 0
b 0
f 0
dl 0
loc 143
rs 4.746
cc 16
nop 12
nc 115

How to fix   Long Method    Complexity    Many Parameters   

Long Method

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

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

Commonly applied refactorings include:

Many Parameters

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

There are several approaches to avoid long parameter lists:

1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
/**
6
 * Class SystemAnnouncementManager.
7
 */
8
class SystemAnnouncementManager
9
{
10
    public const VISIBLE_GUEST = 'visible_guest';
11
    public const VISIBLE_STUDENT = 'visible_student';
12
    public const VISIBLE_TEACHER = 'visible_teacher';
13
    // Requires DB change
14
    public const VISIBLE_DRH = 'visible_drh';
15
    public const VISIBLE_SESSION_ADMIN = 'visible_session_admin';
16
    public const VISIBLE_STUDENT_BOSS = 'visible_boss';
17
18
    /**
19
     * @return array
20
     */
21
    public static function getVisibilityList()
22
    {
23
        $extraRoles = self::newRolesActivated();
24
25
        $visibleToUsers = [
26
            self::VISIBLE_TEACHER => get_lang('Teacher'),
27
            self::VISIBLE_STUDENT => get_lang('Student'),
28
            self::VISIBLE_GUEST => get_lang('Guest'),
29
        ];
30
31
        if ($extraRoles) {
32
            $visibleToUsers[self::VISIBLE_DRH] = get_lang('DRH');
33
            $visibleToUsers[self::VISIBLE_SESSION_ADMIN] = get_lang('SessionAdministrator');
34
            $visibleToUsers[self::VISIBLE_STUDENT_BOSS] = get_lang('StudentBoss');
35
        }
36
37
        return $visibleToUsers;
38
    }
39
40
    /**
41
     * @param string $visibility
42
     *
43
     * @return string
44
     */
45
    public static function getVisibilityCondition($visibility)
46
    {
47
        $list = self::getVisibilityList();
48
        $visibilityCondition = " AND ".self::VISIBLE_GUEST." = 1 ";
49
        if (in_array($visibility, array_keys($list))) {
50
            $visibilityCondition = " AND $visibility = 1 ";
51
        }
52
53
        return $visibilityCondition;
54
    }
55
56
    /**
57
     * @param string $visibility
58
     * @param int    $id
59
     * @param int    $start
60
     * @param string $user_id
61
     *
62
     * @return string
63
     */
64
    public static function displayAllAnnouncements(
65
        $visibility,
66
        $id = -1,
67
        $start = 0,
68
        $user_id = ''
69
    ) {
70
        $user_selected_language = api_get_interface_language();
71
        $start = (int) $start;
72
        $userGroup = new UserGroup();
73
        $tbl_announcement_group = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS_GROUPS);
74
        $temp_user_groups = $userGroup->get_groups_by_user(api_get_user_id(), 0);
75
        $groups = [];
76
        foreach ($temp_user_groups as $user_group) {
77
            $groups = array_merge($groups, [$user_group['id']]);
78
            $groups = array_merge($groups, $userGroup->get_parent_groups($user_group['id']));
79
        }
80
81
        // Checks if tables exists to not break platform not updated
82
        $groups_string = '('.implode($groups, ',').')';
83
84
        $table = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS);
85
        $now = api_get_utc_datetime();
86
87
        $sql = "SELECT * FROM $table
88
                WHERE
89
                    (lang = '$user_selected_language' OR lang IS NULL) AND
90
                    ( '$now' >= date_start AND '$now' <= date_end) ";
91
92
        $sql .= self::getVisibilityCondition($visibility);
93
94
        if (count($groups) > 0) {
95
            $sql .= " OR id IN (
96
                    SELECT announcement_id FROM $tbl_announcement_group
97
                    WHERE group_id in $groups_string
98
                    ) ";
99
        }
100
101
        if (api_is_multiple_url_enabled()) {
102
            $current_access_url_id = api_get_current_access_url_id();
103
            $sql .= " AND access_url_id IN ('1', '$current_access_url_id')";
104
        }
105
106
        if (!isset($_GET['start']) || $_GET['start'] == 0) {
107
            $sql .= " ORDER BY date_start DESC LIMIT ".$start.",20";
108
        } else {
109
            $sql .= " ORDER BY date_start DESC LIMIT ".($start + 1).",20";
110
        }
111
        $announcements = Database::query($sql);
112
        $content = '';
113
        if (Database::num_rows($announcements) > 0) {
114
            $content .= '<div class="system_announcements">';
115
            $content .= '<h3>'.get_lang('SystemAnnouncements').'</h3>';
116
            $content .= '<table align="center">';
117
            $content .= '<tr>';
118
            $content .= '<td>';
119
            $content .= self::display_arrow($user_id);
120
            $content .= '</td>';
121
            $content .= '</tr>';
122
            $content .= '</table>';
123
            $content .= '<table align="center" border="0" width="900px">';
124
            while ($announcement = Database::fetch_object($announcements)) {
125
                $display_date = api_convert_and_format_date($announcement->display_date, DATE_FORMAT_LONG);
126
                $content .= '<tr><td>';
127
                $content .= '<a name="'.$announcement->id.'"></a>
128
                        <div class="system_announcement">
129
                        <h2>'.$announcement->title.'</h2>
130
                        <div class="system_announcement_date">'.$display_date.'</div>
131
                        <br />
132
                        <div class="system_announcement_content">'
133
                            .$announcement->content.'
134
                        </div>
135
                      </div><br />';
136
                $content .= '</tr></td>';
137
            }
138
            $content .= '</table>';
139
140
            $content .= '<table align="center">';
141
            $content .= '<tr>';
142
            $content .= '<td>';
143
            $content .= self::display_arrow($user_id);
144
            $content .= '</td>';
145
            $content .= '</tr>';
146
            $content .= '</table>';
147
            $content .= '</div>';
148
        }
149
150
        return $content;
151
    }
152
153
    /**
154
     * @param int $user_id
155
     *
156
     * @return string
157
     */
158
    public static function display_arrow($user_id)
159
    {
160
        $start = (int) $_GET['start'];
161
        $nb_announcement = self::count_nb_announcement($start, $user_id);
162
        $next = ((int) $_GET['start'] + 19);
163
        $prev = ((int) $_GET['start'] - 19);
164
        $content = '';
165
        if (!isset($_GET['start']) || $_GET['start'] == 0) {
166
            if ($nb_announcement > 20) {
167
                $content .= '<a href="news_list.php?start='.$next.'">'.get_lang('NextBis').' >> </a>';
168
            }
169
        } else {
170
            echo '<a href="news_list.php?start='.$prev.'"> << '.get_lang('Prev').'</a>';
171
            if ($nb_announcement > 20) {
172
                $content .= '<a href="news_list.php?start='.$next.'">'.get_lang('NextBis').' >> </a>';
173
            }
174
        }
175
176
        return $content;
177
    }
178
179
    /**
180
     * @param int    $start
181
     * @param string $user_id
182
     *
183
     * @return int
184
     */
185
    public static function count_nb_announcement($start = 0, $user_id = '')
186
    {
187
        $start = (int) $start;
188
        $user_selected_language = api_get_interface_language();
189
        $db_table = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS);
190
        $sql = 'SELECT id FROM '.$db_table.'
191
                WHERE (lang="'.$user_selected_language.'" OR lang IS NULL) ';
192
193
        $visibility = self::getCurrentUserVisibility();
194
        $sql .= self::getVisibilityCondition($visibility);
195
196
        $current_access_url_id = 1;
197
        if (api_is_multiple_url_enabled()) {
198
            $current_access_url_id = api_get_current_access_url_id();
199
        }
200
        $sql .= " AND access_url_id = '$current_access_url_id' ";
201
        $sql .= 'LIMIT '.$start.', 21';
202
        $announcements = Database::query($sql);
203
        $i = 0;
204
        while ($rows = Database::fetch_array($announcements)) {
205
            $i++;
206
        }
207
208
        return $i;
209
    }
210
211
    /**
212
     * Get all announcements.
213
     *
214
     * @return array An array with all available system announcements (as php
215
     *               objects)
216
     */
217
    public static function get_all_announcements()
218
    {
219
        $table = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS);
220
        $now = api_get_utc_datetime();
221
        $sql = "SELECT *, IF ( '$now'  >= date_start AND '$now' <= date_end, '1', '0') AS visible
222
                FROM $table";
223
224
        $current_access_url_id = 1;
225
        if (api_is_multiple_url_enabled()) {
226
            $current_access_url_id = api_get_current_access_url_id();
227
        }
228
        $sql .= " WHERE access_url_id = '$current_access_url_id' ";
229
        $sql .= " ORDER BY date_start ASC";
230
231
        $result = Database::query($sql);
232
        $announcements = [];
233
        while ($announcement = Database::fetch_object($result)) {
234
            $announcements[] = $announcement;
235
        }
236
237
        return $announcements;
238
    }
239
240
    /**
241
     * Adds an announcement to the database.
242
     *
243
     * @param string $title           Title of the announcement
244
     * @param string $content         Content of the announcement
245
     * @param string $date_start      Start date (YYYY-MM-DD HH:II: SS)
246
     * @param string $date_end        End date (YYYY-MM-DD HH:II: SS)
247
     * @param array  $visibility
248
     * @param string $lang            The language for which the announvement should be shown. Leave null for all langages
249
     * @param int    $send_mail       Whether to send an e-mail to all users (1) or not (0)
250
     * @param bool   $add_to_calendar
251
     * @param bool   $sendEmailTest
252
     * @param int    $careerId
253
     * @param int    $promotionId
254
     * @param array  $groups
255
     *
256
     * @return mixed insert_id on success, false on failure
257
     */
258
    public static function add_announcement(
259
        $title,
260
        $content,
261
        $date_start,
262
        $date_end,
263
        $visibility,
264
        $lang = '',
265
        $send_mail = 0,
266
        $add_to_calendar = false,
267
        $sendEmailTest = false,
268
        $careerId = 0,
269
        $promotionId = 0,
270
        $groups = []
271
    ) {
272
        $original_content = $content;
273
        $a_dateS = explode(' ', $date_start);
274
        $a_arraySD = explode('-', $a_dateS[0]);
275
        $a_arraySH = explode(':', $a_dateS[1]);
276
        $date_start_to_compare = array_merge($a_arraySD, $a_arraySH);
277
278
        $a_dateE = explode(' ', $date_end);
279
        $a_arrayED = explode('-', $a_dateE[0]);
280
        $a_arrayEH = explode(':', $a_dateE[1]);
281
        $date_end_to_compare = array_merge($a_arrayED, $a_arrayEH);
282
283
        $db_table = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS);
284
285
        if (!checkdate($date_start_to_compare[1], $date_start_to_compare[2], $date_start_to_compare[0])) {
286
            Display::addFlash(
287
                Display::return_message(get_lang('InvalidStartDate'), 'warning')
288
            );
289
290
            return false;
291
        }
292
293
        if (($date_end_to_compare[1] ||
294
            $date_end_to_compare[2] ||
295
            $date_end_to_compare[0]) &&
296
            !checkdate($date_end_to_compare[1], $date_end_to_compare[2], $date_end_to_compare[0])
297
        ) {
298
            Display::addFlash(
299
                Display::return_message(get_lang('InvalidEndDate'), 'warning')
300
            );
301
302
            return false;
303
        }
304
305
        if (strlen(trim($title)) == 0) {
306
            Display::addFlash(
307
                Display::return_message(get_lang('InvalidTitle'), 'warning')
308
            );
309
310
            return false;
311
        }
312
313
        $start = api_get_utc_datetime($date_start);
314
        $end = api_get_utc_datetime($date_end);
315
316
        //Fixing urls that are sent by email
317
        //$content = str_replace('src=\"/home/', 'src=\"'.api_get_path(WEB_PATH).'home/', $content);
318
        //$content = str_replace('file=/home/', 'file='.api_get_path(WEB_PATH).'home/', $content);
319
        $content = str_replace(
320
            'src=\"'.api_get_path(REL_HOME_PATH),
321
            'src=\"'.api_get_path(WEB_PATH).api_get_path(REL_HOME_PATH),
322
            $content
323
        );
324
        $content = str_replace(
325
            'file='.api_get_path(REL_HOME_PATH),
326
            'file='.api_get_path(WEB_PATH).api_get_path(REL_HOME_PATH),
327
            $content
328
        );
329
        $lang = is_null($lang) ? '' : $lang;
330
331
        $current_access_url_id = 1;
332
        if (api_is_multiple_url_enabled()) {
333
            $current_access_url_id = api_get_current_access_url_id();
334
        }
335
336
        $params = [
337
            'title' => $title,
338
            'content' => $content,
339
            'date_start' => $start,
340
            'date_end' => $end,
341
            'lang' => $lang,
342
            'access_url_id' => $current_access_url_id,
343
        ];
344
345
        if (api_get_configuration_value('allow_careers_in_global_announcements') && !empty($careerId)) {
346
            $params['career_id'] = (int) $careerId;
347
            $params['promotion_id'] = (int) $promotionId;
348
        }
349
350
        foreach ($visibility as $key => $value) {
351
            $params[$key] = $value;
352
        }
353
354
        $resultId = Database::insert($db_table, $params);
355
356
        if ($resultId) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $resultId of type false|integer 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...
357
            if ($sendEmailTest) {
358
                self::send_system_announcement_by_email(
359
                    $resultId,
360
                    $visibility,
361
                    true
362
                );
363
            } else {
364
                if ($send_mail == 1) {
365
                    self::send_system_announcement_by_email(
366
                        $resultId,
367
                        $visibility,
368
                        false,
369
                        $groups
370
                    );
371
                }
372
            }
373
374
            if ($add_to_calendar) {
375
                $agenda = new Agenda('admin');
376
                $agenda->addEvent(
377
                    $date_start,
378
                    $date_end,
379
                    false,
380
                    $title,
381
                    $original_content,
382
                    [],
383
                    false,
384
                    null,
385
                    [],
386
                    [],
387
                    null,
388
                    '',
389
                    [],
390
                    false,
391
                    [],
392
                    $params['career_id'] ?? 0,
393
                    $params['promotion_id'] ?? 0
394
                );
395
            }
396
397
            return $resultId;
398
        }
399
400
        return false;
401
    }
402
403
    /**
404
     * Makes the announcement id visible only for groups in groups_array.
405
     *
406
     * @param int   $announcement_id
407
     * @param array $groups          array of group id
408
     *
409
     * @return bool
410
     */
411
    public static function announcement_for_groups($announcement_id, $groups)
412
    {
413
        $tbl_announcement_group = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS_GROUPS);
414
        $announcement_id = (int) $announcement_id;
415
416
        if (empty($announcement_id)) {
417
            return false;
418
        }
419
420
        // First delete all group associations for this announcement
421
        $sql = "DELETE FROM $tbl_announcement_group WHERE announcement_id= $announcement_id";
422
        Database::query($sql);
423
424
        if (!empty($groups)) {
425
            foreach ($groups as $group_id) {
426
                if (intval($group_id) != 0) {
427
                    $sql = "INSERT INTO $tbl_announcement_group SET
428
                            announcement_id=".$announcement_id.",
429
                            group_id=".intval($group_id);
430
                    Database::query($sql);
431
                }
432
            }
433
        }
434
435
        return true;
436
    }
437
438
    /**
439
     * Gets the groups of this announce.
440
     *
441
     * @param int announcement id
442
     *
443
     * @return array array of group id
444
     */
445
    public static function get_announcement_groups($announcement_id)
446
    {
447
        $tbl_announcement_group = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS_GROUPS);
448
        $tbl_group = Database::get_main_table(TABLE_USERGROUP);
449
        //first delete all group associations for this announcement
450
        $sql = "SELECT
451
                    g.id as group_id,
452
                    g.name as group_name
453
                FROM $tbl_group g , $tbl_announcement_group ag
454
                WHERE
455
                    announcement_id =".intval($announcement_id)." AND
456
                    ag.group_id = g.id";
457
        $res = Database::query($sql);
458
459
        return Database::store_result($res);
460
    }
461
462
    /**
463
     * Updates an announcement to the database.
464
     *
465
     * @param int    $id            of the announcement
466
     * @param string $title         title of the announcement
467
     * @param string $content       content of the announcement
468
     * @param array  $date_start    start date (0 => day ; 1 => month ; 2 => year ; 3 => hour ; 4 => minute)
469
     * @param array  $date_end      end date of (0 => day ; 1 => month ; 2 => year ; 3 => hour ; 4 => minute)
470
     * @param array  $visibility
471
     * @param array  $lang
472
     * @param int    $send_mail
473
     * @param bool   $sendEmailTest
474
     * @param int    $careerId
475
     * @param int    $promotionId
476
     * @param array  $groups
477
     *
478
     * @return bool True on success, false on failure
479
     */
480
    public static function update_announcement(
481
        $id,
482
        $title,
483
        $content,
484
        $date_start,
485
        $date_end,
486
        $visibility,
487
        $lang = null,
488
        $send_mail = 0,
489
        $sendEmailTest = false,
490
        $careerId = 0,
491
        $promotionId = 0,
492
        $groups = []
493
    ) {
494
        $em = Database::getManager();
495
        $announcement = $em->find('ChamiloCoreBundle:SysAnnouncement', $id);
496
        if (!$announcement) {
497
            return false;
498
        }
499
500
        $a_dateS = explode(' ', $date_start);
501
        $a_arraySD = explode('-', $a_dateS[0]);
502
        $a_arraySH = explode(':', $a_dateS[1]);
503
        $date_start_to_compare = array_merge($a_arraySD, $a_arraySH);
504
505
        $a_dateE = explode(' ', $date_end);
506
        $a_arrayED = explode('-', $a_dateE[0]);
507
        $a_arrayEH = explode(':', $a_dateE[1]);
508
        $date_end_to_compare = array_merge($a_arrayED, $a_arrayEH);
509
510
        $lang = is_null($lang) ? '' : $lang;
511
512
        if (!checkdate($date_start_to_compare[1], $date_start_to_compare[2], $date_start_to_compare[0])) {
513
            echo Display::return_message(get_lang('InvalidStartDate'));
514
515
            return false;
516
        }
517
518
        if (($date_end_to_compare[1] ||
519
            $date_end_to_compare[2] ||
520
            $date_end_to_compare[0]) &&
521
            !checkdate($date_end_to_compare[1], $date_end_to_compare[2], $date_end_to_compare[0])
522
        ) {
523
            echo Display::return_message(get_lang('InvalidEndDate'));
524
525
            return false;
526
        }
527
528
        if (strlen(trim($title)) == 0) {
529
            echo Display::return_message(get_lang('InvalidTitle'));
530
531
            return false;
532
        }
533
534
        $start = api_get_utc_datetime($date_start);
535
        $end = api_get_utc_datetime($date_end);
536
537
        //Fixing urls that are sent by email
538
        //$content = str_replace('src=\"/home/', 'src=\"'.api_get_path(WEB_PATH).'home/', $content);
539
        //$content = str_replace('file=/home/', 'file='.api_get_path(WEB_PATH).'home/', $content);
540
        $content = str_replace(
541
            'src=\"'.api_get_path(REL_HOME_PATH),
542
            'src=\"'.api_get_path(WEB_PATH).api_get_path(REL_HOME_PATH),
543
            $content
544
        );
545
        $content = str_replace(
546
            'file='.api_get_path(REL_HOME_PATH),
547
            'file='.api_get_path(WEB_PATH).api_get_path(REL_HOME_PATH),
548
            $content
549
        );
550
551
        $dateStart = new DateTime($start, new DateTimeZone('UTC'));
552
        $dateEnd = new DateTime($end, new DateTimeZone('UTC'));
553
554
        $announcement
555
            ->setLang($lang)
556
            ->setTitle($title)
557
            ->setContent($content)
558
            ->setDateStart($dateStart)
559
            ->setDateEnd($dateEnd)
560
            //->setVisibleTeacher($visible_teacher)
561
            //->setVisibleStudent($visible_student)
562
            //->setVisibleGuest($visible_guest)
563
            ->setAccessUrlId(api_get_current_access_url_id());
564
565
        $em->persist($announcement);
566
        $em->flush();
567
568
        // Update visibility
569
        $list = self::getVisibilityList();
570
        $table = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS);
571
572
        if (api_get_configuration_value('allow_careers_in_global_announcements') && !empty($careerId)) {
573
            $params = [];
574
            $params['career_id'] = (int) $careerId;
575
            $params['promotion_id'] = (int) $promotionId;
576
            Database::update(
577
                $table,
578
                $params,
579
                ['id = ? ' => $id]
580
            );
581
        }
582
583
        foreach ($list as $key => $title) {
0 ignored issues
show
introduced by
$title is overwriting one of the parameters of this function.
Loading history...
584
            $value = isset($visibility[$key]) && $visibility[$key] ? 1 : 0;
585
            $sql = "UPDATE $table SET $key = '$value' WHERE id = $id";
586
            Database::query($sql);
587
        }
588
589
        if ($sendEmailTest) {
590
            self::send_system_announcement_by_email(
591
                $id,
592
                $visibility,
593
                true
594
            );
595
        } else {
596
            if ($send_mail == 1) {
597
                self::send_system_announcement_by_email(
598
                    $id,
599
                    $visibility,
600
                    false,
601
                    $groups
602
                );
603
            }
604
        }
605
606
        return true;
607
    }
608
609
    /**
610
     * Deletes an announcement.
611
     *
612
     * @param int $id The identifier of the announcement that should be
613
     *
614
     * @return bool True on success, false on failure
615
     */
616
    public static function delete_announcement($id)
617
    {
618
        $table = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS);
619
        $id = (int) $id;
620
        $sql = "DELETE FROM $table WHERE id =".$id;
621
        $res = Database::query($sql);
622
        if ($res === false) {
623
            return false;
624
        }
625
626
        return true;
627
    }
628
629
    /**
630
     * Gets an announcement.
631
     *
632
     * @param int $id The identifier of the announcement that should be
633
     *
634
     * @return object Object of class StdClass or the required class, containing the query result row
635
     */
636
    public static function get_announcement($id)
637
    {
638
        $table = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS);
639
        $id = (int) $id;
640
        $sql = "SELECT * FROM ".$table." WHERE id = ".$id;
641
        $announcement = Database::fetch_object(Database::query($sql));
642
643
        return $announcement;
644
    }
645
646
    /**
647
     * Change the visibility of an announcement.
648
     *
649
     * @param int  $id
650
     * @param int  $user    For who should the visibility be changed
651
     * @param bool $visible
652
     *
653
     * @return bool True on success, false on failure
654
     */
655
    public static function set_visibility($id, $user, $visible)
656
    {
657
        $table = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS);
658
        $id = (int) $id;
659
        $list = array_keys(self::getVisibilityList());
660
        $user = trim($user);
661
        $visible = (int) $visible;
662
        if (!in_array($user, $list)) {
663
            return false;
664
        }
665
666
        $field = $user;
667
        $sql = "UPDATE $table SET ".$field." = '".$visible."'
668
                WHERE id='".$id."'";
669
        $res = Database::query($sql);
670
671
        if ($res === false) {
672
            return false;
673
        }
674
675
        return true;
676
    }
677
678
    /**
679
     * Send a system announcement by e-mail to all teachers/students depending on parameters.
680
     *
681
     * @param int   $id
682
     * @param array $visibility
683
     * @param bool  $sendEmailTest
684
     * @param array $groups
685
     *
686
     * @return bool True if the message was sent or there was no destination matching.
687
     *              False on database or e-mail sending error.
688
     */
689
    public static function send_system_announcement_by_email($id, $visibility, $sendEmailTest = false, $groups = [])
690
    {
691
        $announcement = self::get_announcement($id);
692
693
        if (empty($announcement)) {
694
            return false;
695
        }
696
697
        $title = $announcement->title;
698
        $content = $announcement->content;
699
        $language = $announcement->lang;
700
        $content = str_replace(['\r\n', '\n', '\r'], '', $content);
701
        $now = api_get_utc_datetime();
702
        $teacher = $visibility['visible_teacher'];
703
        $student = $visibility['visible_student'];
704
        if ($sendEmailTest) {
705
            MessageManager::send_message_simple(api_get_user_id(), $title, $content);
706
707
            return true;
708
        }
709
710
        $whereUsersInGroup = '';
711
        $usersId = [];
712
        foreach ($groups as $groupId) {
713
            if (0 != $groupId) {
714
                $tblGroupRelUser = Database::get_main_table(TABLE_USERGROUP_REL_USER);
715
                $sql = "SELECT user_id FROM $tblGroupRelUser WHERE usergroup_id = $groupId";
716
                $result = Database::query($sql);
717
                $data = Database::store_result($result);
718
                foreach ($data as $userArray) {
719
                    $usersId[] = $userArray['user_id'];
720
                }
721
            }
722
        }
723
724
        if (!empty($usersId)) {
725
            $usersId = implode(',', $usersId);
726
            $whereUsersInGroup = " AND u.user_id in ($usersId) ";
727
        }
728
729
        $urlJoin = '';
730
        $urlCondition = '';
731
        $user_table = Database::get_main_table(TABLE_MAIN_USER);
732
        if (api_is_multiple_url_enabled()) {
733
            $current_access_url_id = api_get_current_access_url_id();
734
            $url_rel_user = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
735
            $urlJoin = " INNER JOIN $url_rel_user uu ON uu.user_id = u.user_id ";
736
            $urlCondition = " AND access_url_id = '".$current_access_url_id."' ";
737
        }
738
739
        if ($teacher != 0 && $student == 0) {
740
            $sql = "SELECT DISTINCT u.user_id FROM $user_table u $urlJoin
741
                    WHERE status = '1' $urlCondition $whereUsersInGroup";
742
        }
743
744
        if ($teacher == 0 && $student != 0) {
745
            $sql = "SELECT DISTINCT u.user_id FROM $user_table u $urlJoin
746
                    WHERE status = '5' $urlCondition $whereUsersInGroup";
747
        }
748
749
        if ($teacher != 0 && $student != 0) {
750
            $sql = "SELECT DISTINCT u.user_id FROM $user_table u $urlJoin
751
                    WHERE 1 = 1 $urlCondition $whereUsersInGroup";
752
        }
753
754
        if (!isset($sql)) {
755
            return false;
756
        }
757
758
        if (!empty($language)) {
759
            //special condition because language was already treated for SQL insert before
760
            $sql .= " AND language = '".Database::escape_string($language)."' ";
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...
761
        }
762
763
        // Sent to active users.
764
        $sql .= " AND email <>'' AND active = 1 ";
765
766
        // Expiration date
767
        $sql .= " AND (expiration_date = '' OR expiration_date IS NULL OR expiration_date > '$now') ";
768
769
        if ((empty($teacher) || $teacher == '0') && (empty($student) || $student == '0')) {
770
            return true;
771
        }
772
773
        $userListToFilter = [];
774
        // @todo check if other filters will apply for the career/promotion option.
775
        if (isset($announcement->career_id) && !empty($announcement->career_id)) {
776
            $promotion = new Promotion();
777
            $promotionList = $promotion->get_all_promotions_by_career_id($announcement->career_id);
778
            if (isset($announcement->promotion_id) && !empty($announcement->promotion_id)) {
779
                $promotionList = [];
780
                $promotionList[] = $promotion->get($announcement->promotion_id);
781
            }
782
783
            if (!empty($promotionList)) {
784
                foreach ($promotionList as $promotion) {
785
                    $sessionList = SessionManager::get_all_sessions_by_promotion($promotion['id']);
786
                    foreach ($sessionList as $session) {
787
                        if ($teacher) {
788
                            $users = SessionManager::get_users_by_session($session['id'], 2);
789
                            if (!empty($users)) {
790
                                $userListToFilter = array_merge($users, $userListToFilter);
791
                            }
792
                        }
793
794
                        if ($student) {
795
                            $users = SessionManager::get_users_by_session($session['id'], 0);
796
                            if (!empty($users)) {
797
                                $userListToFilter = array_merge($users, $userListToFilter);
798
                            }
799
                        }
800
                    }
801
                }
802
            }
803
        }
804
805
        if (!empty($userListToFilter)) {
806
            $userListToFilter = array_column($userListToFilter, 'user_id');
807
            $userListToFilterToString = implode("', '", $userListToFilter);
808
            $sql .= " AND (u.user_id IN ('$userListToFilterToString') ) ";
809
        }
810
811
        $result = Database::query($sql);
812
        if ($result === false) {
813
            return false;
814
        }
815
816
        $message_sent = false;
817
        while ($row = Database::fetch_array($result, 'ASSOC')) {
818
            MessageManager::send_message_simple($row['user_id'], $title, $content);
819
            $message_sent = true;
820
        }
821
822
        // Minor validation to clean up the attachment files in the announcement
823
        if (!empty($_FILES)) {
824
            $attachments = $_FILES;
825
            foreach ($attachments as $attachment) {
826
                unlink($attachment['tmp_name']);
827
            }
828
        }
829
830
        return $message_sent; //true if at least one e-mail was sent
831
    }
832
833
    /**
834
     * Returns the group announcements where the user is subscribed.
835
     *
836
     * @param $userId
837
     * @param $visible
838
     *
839
     * @throws \Exception
840
     *
841
     * @return array
842
     */
843
    public static function getAnnouncementsForGroups($userId, $visible)
844
    {
845
        $userSelectedLanguage = Database::escape_string(api_get_interface_language());
846
        $tblSysAnnouncements = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS);
847
        $tblGrpAnnouncements = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS_GROUPS);
848
        $tblUsrGrp = Database::get_main_table(TABLE_USERGROUP_REL_USER);
849
        $now = api_get_utc_datetime();
850
851
        $sql = "SELECT sys_announcement.*
852
        FROM $tblSysAnnouncements AS sys_announcement
853
        INNER JOIN $tblGrpAnnouncements AS announcement_rel_group
854
            ON sys_announcement.id = announcement_rel_group.announcement_id
855
        INNER JOIN $tblUsrGrp AS usergroup_rel_user
856
            ON usergroup_rel_user.usergroup_id = announcement_rel_group.group_id
857
        WHERE
858
            usergroup_rel_user.user_id = $userId AND
859
            (sys_announcement.lang = '$userSelectedLanguage' OR sys_announcement.lang = '') AND
860
            ('$now' >= sys_announcement.date_start AND '$now' <= sys_announcement.date_end)";
861
        $sql .= self::getVisibilityCondition($visible);
862
        $result = Database::query($sql);
863
        $data = Database::store_result($result, 'ASSOC');
864
        Database::free_result($result);
865
866
        return $data;
867
    }
868
869
    /**
870
     * Displays announcements as an slideshow.
871
     *
872
     * @param string $visible see self::VISIBLE_* constants
873
     * @param int    $id      The identifier of the announcement to display
874
     *
875
     * @return string
876
     */
877
    public static function displayAnnouncementsSlider($visible, $id = null)
878
    {
879
        $user_selected_language = Database::escape_string(api_get_interface_language());
880
        $table = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS);
881
        $tblGrpAnnouncements = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS_GROUPS);
882
883
        $cut_size = 500;
884
        $now = api_get_utc_datetime();
885
        //Exclude announcement to groups
886
        $sql = "SELECT sys_announcement.*
887
            FROM $table as sys_announcement
888
            LEFT JOIN $tblGrpAnnouncements AS announcement_rel_group
889
                ON sys_announcement.id = announcement_rel_group.announcement_id
890
            WHERE
891
                (sys_announcement.lang = '$user_selected_language' OR sys_announcement.lang = '') AND
892
                ('$now' >= sys_announcement.date_start AND '$now' <= sys_announcement.date_end) AND
893
                announcement_rel_group.group_id is null";
894
895
        $sql .= self::getVisibilityCondition($visible);
896
897
        if (isset($id) && !empty($id)) {
898
            $id = (int) $id;
899
            $sql .= " AND id = $id ";
900
        }
901
902
        if (api_is_multiple_url_enabled()) {
903
            $current_url_id = api_get_current_access_url_id();
904
            $sql .= " AND access_url_id IN ('1', '$current_url_id') ";
905
        }
906
907
        $checkCareers = api_get_configuration_value('allow_careers_in_global_announcements') === true;
908
909
        $userId = api_get_user_id();
910
911
        $promotion = new Promotion();
912
        $sql .= ' ORDER BY date_start DESC';
913
        $result = Database::query($sql);
914
        $announcements = [];
915
        if (Database::num_rows($result) > 0) {
916
            while ($announcement = Database::fetch_object($result)) {
917
                if ($checkCareers && !empty($announcement->career_id)) {
918
                    $promotionList = [];
919
                    if (!empty($announcement->promotion_id)) {
920
                        $promotionList[] = $announcement->promotion_id;
921
                    } else {
922
                        $promotionList = $promotion->get_all_promotions_by_career_id($announcement->career_id);
923
                        if (!empty($promotionList)) {
924
                            $promotionList = array_column($promotionList, 'id');
925
                        }
926
                    }
927
928
                    $show = false;
929
                    foreach ($promotionList as $promotionId) {
930
                        $sessionList = SessionManager::get_all_sessions_by_promotion($promotionId);
931
                        foreach ($sessionList as $session) {
932
                            $sessionId = $session['id'];
933
                            // Check student
934
                            if ($visible === self::VISIBLE_STUDENT &&
935
                                SessionManager::isUserSubscribedAsStudent($sessionId, $userId)
936
                            ) {
937
                                $show = true;
938
                                break 2;
939
                            }
940
941
                            if ($visible === self::VISIBLE_TEACHER &&
942
                                SessionManager::user_is_general_coach($userId, $sessionId)
943
                            ) {
944
                                $show = true;
945
                                break 2;
946
                            }
947
948
                            // Check course coach
949
                            $coaches = SessionManager::getCoachesBySession($sessionId);
950
951
                            if ($visible === self::VISIBLE_TEACHER && in_array($userId, $coaches)) {
952
                                $show = true;
953
                                break 2;
954
                            }
955
                        }
956
                    }
957
958
                    if (false === $show) {
959
                        continue;
960
                    }
961
                }
962
963
                $announcementData = [
964
                    'id' => $announcement->id,
965
                    'title' => $announcement->title,
966
                    'content' => $announcement->content,
967
                    'readMore' => null,
968
                ];
969
970
                if (empty($id)) {
971
                    if (api_strlen(strip_tags($announcement->content)) > $cut_size) {
972
                        //$announcementData['content'] = cut($announcement->content, $cut_size);
973
                        $announcementData['readMore'] = true;
974
                    }
975
                }
976
977
                $announcements[] = $announcementData;
978
            }
979
        }
980
981
        /** Show announcement of group */
982
        $announcementToGroup = self::getAnnouncementsForGroups($userId, $visible);
983
        $totalAnnouncementToGroup = count($announcementToGroup);
984
        for ($i = 0; $i < $totalAnnouncementToGroup; $i++) {
985
            $announcement = $announcementToGroup[$i];
986
            $announcementData = [
987
                'id' => $announcement['id'],
988
                'title' => $announcement['title'],
989
                'content' => $announcement['content'],
990
                'readMore' => null,
991
            ];
992
            $content = $announcement['content'];
993
            if (api_strlen(strip_tags($content)) > $cut_size) {
994
                //$announcementData['content'] = cut($content, $cut_size);
995
                $announcementData['readMore'] = true;
996
            }
997
            $announcements[] = $announcementData;
998
        }
999
1000
        if (count($announcements) === 0) {
1001
            return null;
1002
        }
1003
1004
        $template = new Template(null, false, false);
1005
        $template->assign('announcements', $announcements);
1006
        $layout = $template->get_template('announcement/slider.tpl');
1007
1008
        return $template->fetch($layout);
1009
    }
1010
1011
    /**
1012
     * Get the HTML code for an announcement.
1013
     *
1014
     * @param int $announcementId The announcement ID
1015
     * @param int $visibility     The announcement visibility
1016
     *
1017
     * @return string The HTML code
1018
     */
1019
    public static function displayAnnouncement($announcementId, $visibility)
1020
    {
1021
        $selectedUserLanguage = Database::escape_string(api_get_interface_language());
1022
        $announcementTable = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS);
1023
        $now = api_get_utc_datetime();
1024
        $announcementId = (int) $announcementId;
1025
1026
        $whereConditions = [
1027
            "(lang = ? OR lang IS NULL OR lang = '') " => $selectedUserLanguage,
1028
            "AND (? >= date_start AND ? <= date_end) " => [$now, $now],
1029
            "AND id = ? " => $announcementId,
1030
        ];
1031
1032
        $condition = self::getVisibilityCondition($visibility);
1033
        $whereConditions[$condition] = 1;
1034
1035
        if (api_is_multiple_url_enabled()) {
1036
            $whereConditions["AND access_url_id IN (1, ?) "] = api_get_current_access_url_id();
1037
        }
1038
1039
        $announcement = Database::select(
1040
            '*',
1041
            $announcementTable,
1042
            [
1043
                'where' => $whereConditions,
1044
                'order' => 'date_start',
1045
            ],
1046
            'first'
1047
        );
1048
1049
        $template = new Template(null, false, false);
1050
        $template->assign('announcement', $announcement);
1051
        $layout = $template->get_template('announcement/view.tpl');
1052
1053
        return $template->fetch($layout);
1054
    }
1055
1056
    /**
1057
     * @return bool
1058
     */
1059
    public static function newRolesActivated()
1060
    {
1061
        /* In order to use this option you need to run this SQL changes :
1062
         ALTER TABLE sys_announcement ADD COLUMN visible_drh INT DEFAULT 0;
1063
         ALTER TABLE sys_announcement ADD COLUMN visible_session_admin INT DEFAULT 0;
1064
         ALTER TABLE sys_announcement ADD COLUMN visible_boss INT DEFAULT 0;
1065
        */
1066
        return api_get_configuration_value('system_announce_extra_roles');
1067
    }
1068
1069
    /**
1070
     * @return string
1071
     */
1072
    public static function getCurrentUserVisibility()
1073
    {
1074
        if (api_is_anonymous()) {
1075
            return SystemAnnouncementManager::VISIBLE_GUEST;
1076
        }
1077
1078
        if (self::newRolesActivated()) {
1079
            if (api_is_student_boss()) {
1080
                return SystemAnnouncementManager::VISIBLE_STUDENT_BOSS;
1081
            }
1082
1083
            if (api_is_session_admin()) {
1084
                return SystemAnnouncementManager::VISIBLE_SESSION_ADMIN;
1085
            }
1086
1087
            if (api_is_drh()) {
1088
                return SystemAnnouncementManager::VISIBLE_DRH;
1089
            }
1090
1091
            if (api_is_teacher()) {
1092
                return SystemAnnouncementManager::VISIBLE_TEACHER;
1093
            } else {
1094
                return SystemAnnouncementManager::VISIBLE_STUDENT;
1095
            }
1096
        } else {
1097
            // Default behaviour
1098
            return api_is_teacher() ? SystemAnnouncementManager::VISIBLE_TEACHER : SystemAnnouncementManager::VISIBLE_STUDENT;
1099
        }
1100
    }
1101
}
1102