Test Setup Failed
Push — master ( f71949...6c6bd7 )
by Julito
55:21
created

getVisibilityCondition()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 6
nc 2
nop 1
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/* For licensing terms, see /license.txt */
3
4
/**
5
 * Class SystemAnnouncementManager
6
 */
7
class SystemAnnouncementManager
8
{
9
    const VISIBLE_GUEST = 'visible_guest';
10
    const VISIBLE_STUDENT = 'visible_student';
11
    const VISIBLE_TEACHER = 'visible_teacher';
12
    // Requires DB change
13
    const VISIBLE_DRH = 'visible_drh';
14
    const VISIBLE_SESSION_ADMIN = 'visible_session_admin';
15
    const VISIBLE_STUDENT_BOSS = 'visible_boss';
16
17
    /**
18
     * @return array
19
     */
20
    public static function getVisibilityList()
21
    {
22
        $extraRoles = self::newRolesActivated();
23
24
        $visibleToUsers = [
25
            self::VISIBLE_TEACHER => get_lang('Teacher'),
26
            self::VISIBLE_STUDENT => get_lang('Student'),
27
            self::VISIBLE_GUEST => get_lang('Guest')
28
        ];
29
30
        if ($extraRoles) {
31
            $visibleToUsers[self::VISIBLE_DRH] = get_lang('DRH');
32
            $visibleToUsers[self::VISIBLE_SESSION_ADMIN] = get_lang('SessionAdministrator');
33
            $visibleToUsers[self::VISIBLE_STUDENT_BOSS] = get_lang('StudentBoss');
34
        }
35
36
        return $visibleToUsers;
37
    }
38
39
    /**
40
     * @param string $visibility
41
     * @return string
42
     */
43
    public static function getVisibilityCondition($visibility)
44
    {
45
        $list = self::getVisibilityList();
46
        $visibilityCondition = " AND ".self::VISIBLE_GUEST." = 1 ";
47
        if (in_array($visibility, array_keys($list))) {
48
            $visibilityCondition = " AND $visibility = 1 ";
49
        }
50
51
        return $visibilityCondition;
52
    }
53
54
    /**
55
     * Displays all announcements
56
     * @param string $visibility VISIBLE_GUEST, VISIBLE_STUDENT or VISIBLE_TEACHER
57
     * @param int $id The identifier of the announcement to display
58
     */
59
    public static function display_announcements($visibility, $id = -1)
60
    {
61
        $user_selected_language = api_get_interface_language();
62
        $db_table = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS);
63
        $tbl_announcement_group = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS_GROUPS);
64
        $userGroup = new UserGroup();
65
66
        $temp_user_groups = $userGroup->get_groups_by_user(api_get_user_id(), 0);
67
        $groups = array();
68 View Code Duplication
        foreach ($temp_user_groups as $user_group) {
69
            $groups = array_merge($groups, array($user_group['id']));
70
            $groups = array_merge($groups, $userGroup->get_parent_groups($user_group['id']));
71
        }
72
73
        $groups_string = '('.implode($groups, ',').')';
74
        $now = api_get_utc_datetime();
75
        $sql = "SELECT *, DATE_FORMAT(date_start,'%d-%m-%Y %h:%i:%s') AS display_date
76
                FROM  $db_table
77
                WHERE
78
                    (lang='$user_selected_language' OR lang IS NULL) AND
79
                    (('$now' BETWEEN date_start AND date_end) OR date_end='0000-00-00') ";
80
81
82
        $sql .= self::getVisibilityCondition($visibility);
83
84
        if (count($groups) > 0) {
85
            $sql .= " OR id IN (
86
                        SELECT announcement_id FROM $tbl_announcement_group
87
                        WHERE group_id in $groups_string
88
                    ) ";
89
        }
90
        $current_access_url_id = 1;
91
        if (api_is_multiple_url_enabled()) {
92
            $current_access_url_id = api_get_current_access_url_id();
93
        }
94
        $sql .= " AND access_url_id = '$current_access_url_id' ";
95
        $sql .= " ORDER BY date_start DESC LIMIT 0,7";
96
97
        $announcements = Database::query($sql);
98
        if (Database::num_rows($announcements) > 0) {
99
            $query_string = ereg_replace('announcement=[1-9]+', '', $_SERVER['QUERY_STRING']);
100
            $query_string = ereg_replace('&$', '', $query_string);
101
            $url = api_get_self();
102
            echo '<div class="system_announcements">';
103
            echo '<h3>'.get_lang('SystemAnnouncements').'</h3>';
104
            echo '<div style="margin:10px;text-align:right;"><a href="news_list.php">'.get_lang('More').'</a></div>';
105
106
            while ($announcement = Database::fetch_object($announcements)) {
107
                if ($id != $announcement->id) {
108
                    if (strlen($query_string) > 0) {
109
                        $show_url = 'news_list.php#'.$announcement->id;
110
                    } else {
111
                        $show_url = 'news_list.php#'.$announcement->id;
112
                    }
113
                    $display_date = api_convert_and_format_date($announcement->display_date, DATE_FORMAT_LONG);
114
                    echo '<a name="'.$announcement->id.'"></a>
115
                        <div class="system_announcement">
116
                            <div class="system_announcement_title"><a name="ann'.$announcement->id.'" href="'.$show_url.'">'.$announcement->title.'</a></div><div class="system_announcement_date">'.$display_date.'</div>
117
                        </div>';
118
                } else {
119
                    echo '<div class="system_announcement">
120
                            <div class="system_announcement_title">'
121
                                .$announcement->display_date.'
122
                                <a name="ann'.$announcement->id.'" href="'.$url.'?'.$query_string.'#ann'.$announcement->id.'">'.$announcement->title.'</a>
123
                            </div>';
124
                }
125
                echo '<br />';
126
            }
127
            echo '</div>';
128
        }
129
        return;
130
    }
131
132
    /**
133
     * @param string $visibility
134
     * @param int $id
135
     * @param int $start
136
     * @param string $user_id
137
     * @return string
138
     */
139
    public static function displayAllAnnouncements($visibility, $id = -1, $start = 0, $user_id = '')
140
    {
141
        $user_selected_language = api_get_interface_language();
142
        $start = intval($start);
143
        $userGroup = new UserGroup();
144
        $tbl_announcement_group = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS_GROUPS);
145
        $temp_user_groups = $userGroup->get_groups_by_user(api_get_user_id(), 0);
146
        $groups = array();
147 View Code Duplication
        foreach ($temp_user_groups as $user_group) {
148
            $groups = array_merge($groups, array($user_group['id']));
149
            $groups = array_merge($groups, $userGroup->get_parent_groups($user_group['id']));
150
        }
151
152
        // Checks if tables exists to not break platform not updated
153
        $groups_string = '('.implode($groups, ',').')';
154
155
        $table = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS);
156
        $now = api_get_utc_datetime();
157
158
        $sql = "SELECT * FROM $table
159
                WHERE
160
                    (lang = '$user_selected_language' OR lang IS NULL) AND
161
                    ( '$now' >= date_start AND '$now' <= date_end) ";
162
163
        $sql .= self::getVisibilityCondition($visibility);
164
165
        if (count($groups) > 0) {
166
            $sql .= " OR id IN (
167
                    SELECT announcement_id FROM $tbl_announcement_group
168
                    WHERE group_id in $groups_string
169
                    ) ";
170
        }
171
172
        if (api_is_multiple_url_enabled()) {
173
            $current_access_url_id = api_get_current_access_url_id();
174
            $sql .= " AND access_url_id IN ('1', '$current_access_url_id')";
175
        }
176
177
        if (!isset($_GET['start']) || $_GET['start'] == 0) {
178
            $sql .= " ORDER BY date_start DESC LIMIT ".$start.",20";
179
        } else {
180
            $sql .= " ORDER BY date_start DESC LIMIT ".($start + 1).",20";
181
        }
182
        $announcements = Database::query($sql);
183
        $content = '';
184
        if (Database::num_rows($announcements) > 0) {
185
            $content .= '<div class="system_announcements">';
186
            $content .= '<h3>'.get_lang('SystemAnnouncements').'</h3>';
187
            $content .= '<table align="center">';
188
                $content .= '<tr>';
189
                    $content .= '<td>';
190
                        $content .= self::display_arrow($user_id);
191
                    $content .= '</td>';
192
                $content .= '</tr>';
193
            $content .= '</table>';
194
            $content .= '<table align="center" border="0" width="900px">';
195
            while ($announcement = Database::fetch_object($announcements)) {
196
                $display_date = api_convert_and_format_date($announcement->display_date, DATE_FORMAT_LONG);
197
                $content .= '<tr><td>';
198
                $content .= '<a name="'.$announcement->id.'"></a>
199
                        <div class="system_announcement">
200
                        <h2>'.$announcement->title.'</h2><div class="system_announcement_date">'.$display_date.'</div>
201
                        <br />
202
                        <div class="system_announcement_content">'
203
                                .$announcement->content.'
204
                        </div>
205
                      </div><br />';
206
                $content .= '</tr></td>';
207
            }
208
            $content .= '</table>';
209
210
            $content .= '<table align="center">';
211
                $content .= '<tr>';
212
                    $content .= '<td>';
213
                        $content .= self::display_arrow($user_id);
214
                    $content .= '</td>';
215
                $content .= '</tr>';
216
            $content .= '</table>';
217
            $content .= '</div>';
218
        }
219
220
        return $content;
221
    }
222
223
    /**
224
     * @param int $user_id
225
     * @return string
226
     */
227
    public static function display_arrow($user_id)
228
    {
229
        $start = (int) $_GET['start'];
230
        $nb_announcement = self::count_nb_announcement($start, $user_id);
231
        $next = ((int) $_GET['start'] + 19);
232
        $prev = ((int) $_GET['start'] - 19);
233
        $content = '';
234
        if (!isset($_GET['start']) || $_GET['start'] == 0) {
235 View Code Duplication
            if ($nb_announcement > 20) {
236
                $content .= '<a href="news_list.php?start='.$next.'">'.get_lang('NextBis').' >> </a>';
237
            }
238
        } else {
239
            echo '<a href="news_list.php?start='.$prev.'"> << '.get_lang('Prev').'</a>';
240 View Code Duplication
            if ($nb_announcement > 20) {
241
                $content .= '<a href="news_list.php?start='.$next.'">'.get_lang('NextBis').' >> </a>';
242
            }
243
        }
244
        return $content;
245
    }
246
247
    /**
248
     * @param int $start
249
     * @param string $user_id
250
     * @return int
251
     */
252
    public static function count_nb_announcement($start = 0, $user_id = '')
253
    {
254
        $start = intval($start);
255
        $user_selected_language = api_get_interface_language();
256
        $db_table = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS);
257
        $sql = 'SELECT id FROM '.$db_table.'
258
                WHERE (lang="'.$user_selected_language.'" OR lang IS NULL) ';
259
260
        $visibility = self::getCurrentUserVisibility();
261
        $sql .= self::getVisibilityCondition($visibility);
262
263
        $current_access_url_id = 1;
264
        if (api_is_multiple_url_enabled()) {
265
            $current_access_url_id = api_get_current_access_url_id();
266
        }
267
        $sql .= " AND access_url_id = '$current_access_url_id' ";
268
        $sql .= 'LIMIT '.$start.', 21';
269
        $announcements = Database::query($sql);
270
        $i = 0;
271
        while ($rows = Database::fetch_array($announcements)) {
272
            $i++;
273
        }
274
275
        return $i;
276
    }
277
278
    /**
279
     * Get all announcements
280
     * @return array An array with all available system announcements (as php
281
     * objects)
282
     */
283
    public static function get_all_announcements()
284
    {
285
        $table = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS);
286
        $now = api_get_utc_datetime();
287
        $sql = "SELECT *, IF ( '$now'  >= date_start AND '$now' <= date_end, '1', '0') AS visible
288
                FROM $table";
289
290
        $current_access_url_id = 1;
291
        if (api_is_multiple_url_enabled()) {
292
            $current_access_url_id = api_get_current_access_url_id();
293
        }
294
        $sql .= " WHERE access_url_id = '$current_access_url_id' ";
295
        $sql .= " ORDER BY date_start ASC";
296
297
        $result = Database::query($sql);
298
        $announcements = array();
299
        while ($announcement = Database::fetch_object($result)) {
300
            $announcements[] = $announcement;
301
        }
302
        return $announcements;
303
    }
304
305
    /**
306
     * Adds an announcement to the database
307
     *
308
     * @param string $title Title of the announcement
309
     * @param string $content Content of the announcement
310
     * @param string $date_start Start date (YYYY-MM-DD HH:II: SS)
311
     * @param string $date_end End date (YYYY-MM-DD HH:II: SS)
312
     * @param array $visibility
313
     * @param string $lang The language for which the announvement should be shown. Leave null for all langages
314
     * @param int    $send_mail Whether to send an e-mail to all users (1) or not (0)
315
     * @param bool  $add_to_calendar
316
     * @param bool  $sendEmailTest
317
     *
318
     * @return mixed  insert_id on success, false on failure
319
     */
320
    public static function add_announcement(
321
        $title,
322
        $content,
323
        $date_start,
324
        $date_end,
325
        $visibility,
326
        $lang = '',
327
        $send_mail = 0,
328
        $add_to_calendar = false,
329
        $sendEmailTest = false
330
    ) {
331
        $original_content = $content;
332
        $a_dateS = explode(' ', $date_start);
333
        $a_arraySD = explode('-', $a_dateS[0]);
334
        $a_arraySH = explode(':', $a_dateS[1]);
335
        $date_start_to_compare = array_merge($a_arraySD, $a_arraySH);
336
337
        $a_dateE = explode(' ', $date_end);
338
        $a_arrayED = explode('-', $a_dateE[0]);
339
        $a_arrayEH = explode(':', $a_dateE[1]);
340
        $date_end_to_compare = array_merge($a_arrayED, $a_arrayEH);
341
342
        $db_table = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS);
343
344 View Code Duplication
        if (!checkdate($date_start_to_compare[1], $date_start_to_compare[2], $date_start_to_compare[0])) {
345
            Display::addFlash(Display::return_message(get_lang('InvalidStartDate'), 'warning'));
346
347
            return false;
348
        }
349
350 View Code Duplication
        if (($date_end_to_compare[1] ||
351
            $date_end_to_compare[2] ||
352
            $date_end_to_compare[0]) &&
353
            !checkdate($date_end_to_compare[1], $date_end_to_compare[2], $date_end_to_compare[0])
354
        ) {
355
            Display::addFlash(Display::return_message(get_lang('InvalidEndDate'), 'warning'));
356
357
            return false;
358
        }
359
360
        if (strlen(trim($title)) == 0) {
361
            Display::addFlash(Display::return_message(get_lang('InvalidTitle'), 'warning'));
362
363
            return false;
364
        }
365
366
        $start = api_get_utc_datetime($date_start);
367
        $end = api_get_utc_datetime($date_end);
368
369
        //Fixing urls that are sent by email
370
        //$content = str_replace('src=\"/home/', 'src=\"'.api_get_path(WEB_PATH).'home/', $content);
371
        //$content = str_replace('file=/home/', 'file='.api_get_path(WEB_PATH).'home/', $content);
372
        $content = str_replace('src=\"'.api_get_path(REL_HOME_PATH), 'src=\"'.api_get_path(WEB_PATH).api_get_path(REL_HOME_PATH), $content);
373
        $content = str_replace('file='.api_get_path(REL_HOME_PATH), 'file='.api_get_path(WEB_PATH).api_get_path(REL_HOME_PATH), $content);
374
        $lang = is_null($lang) ? '' : $lang;
375
376
        $current_access_url_id = 1;
377
        if (api_is_multiple_url_enabled()) {
378
            $current_access_url_id = api_get_current_access_url_id();
379
        }
380
381
        $params = [
382
            'title' => $title,
383
            'content' => $content,
384
            'date_start' => $start,
385
            'date_end' => $end,
386
            'lang' => $lang,
387
            'access_url_id' => $current_access_url_id
388
        ];
389
390
        foreach ($visibility as $key => $value) {
391
            $params[$key] = $value;
392
        }
393
394
        $resultId = Database::insert($db_table, $params);
395
396
        if ($resultId) {
397 View Code Duplication
            if ($sendEmailTest) {
398
                self::send_system_announcement_by_email(
399
                    $title,
400
                    $content,
401
                    $visibility,
402
                    $lang,
403
                    true
404
                );
405
            } else {
406
                if ($send_mail == 1) {
407
                    self::send_system_announcement_by_email(
408
                        $title,
409
                        $content,
410
                        $visibility,
411
                        $lang
412
                    );
413
                }
414
            }
415
416
            if ($add_to_calendar) {
417
                $agenda = new Agenda('admin');
418
                $agenda->addEvent(
419
                    $date_start,
420
                    $date_end,
421
                    false,
422
                    $title,
423
                    $original_content
424
                );
425
            }
426
427
            return $resultId;
428
429
        }
430
431
        return false;
432
    }
433
434
    /**
435
     * Makes the announcement id visible only for groups in groups_array
436
     * @param int $announcement_id
437
     * @param array $group_array array of group id
438
     * @return bool
439
     **/
440
    public static function announcement_for_groups($announcement_id, $group_array)
441
    {
442
        $tbl_announcement_group = Database::get_main_table(
443
            TABLE_MAIN_SYSTEM_ANNOUNCEMENTS_GROUPS
444
        );
445
        //first delete all group associations for this announcement
446
        $res = Database::query(
447
            "DELETE FROM $tbl_announcement_group 
448
             WHERE announcement_id=".intval($announcement_id)
449
        );
450
451
        if ($res === false) {
452
            return false;
453
        }
454
455
        foreach ($group_array as $group_id) {
456
            if (intval($group_id) != 0) {
457
                $sql = "INSERT INTO $tbl_announcement_group SET
458
                        announcement_id=".intval($announcement_id).",
459
                        group_id=".intval($group_id);
460
                $res = Database::query($sql);
461
                if ($res === false) {
462
                    return false;
463
                }
464
            }
465
        }
466
467
        return true;
468
    }
469
470
    /**
471
    * Gets the groups of this announce
472
    * @param int announcement id
473
    * @return array array of group id
474
    **/
475
    public static function get_announcement_groups($announcement_id)
476
    {
477
        $tbl_announcement_group = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS_GROUPS);
478
        $tbl_group = Database::get_main_table(TABLE_USERGROUP);
479
        //first delete all group associations for this announcement
480
        $sql = "SELECT
481
                    g.id as group_id,
482
                    g.name as group_name
483
                FROM $tbl_group g , $tbl_announcement_group ag
484
                WHERE
485
                    announcement_id =".intval($announcement_id)." AND
486
                    ag.group_id = g.id";
487
        $res = Database::query($sql);
488
        $groups = Database::fetch_array($res);
489
490
        return $groups;
491
    }
492
493
    /**
494
     * Updates an announcement to the database
495
     *
496
     * @param integer $id of the announcement
497
     * @param string $title title of the announcement
498
     * @param string $content content of the announcement
499
     * @param array $date_start start date (0 => day ; 1 => month ; 2 => year ; 3 => hour ; 4 => minute)
500
     * @param array $date_end end date of (0 => day ; 1 => month ; 2 => year ; 3 => hour ; 4 => minute)
501
     * @param array $visibility
502
     * @return bool    True on success, false on failure
503
     */
504
    public static function update_announcement(
505
        $id,
506
        $title,
507
        $content,
508
        $date_start,
509
        $date_end,
510
        $visibility,
511
        $lang = null,
512
        $send_mail = 0,
513
        $sendEmailTest = false
514
    ) {
515
        $em = Database::getManager();
516
        $announcement = $em->find('ChamiloCoreBundle:SysAnnouncement', $id);
517
        if (!$announcement) {
518
            return false;
519
        }
520
521
        $a_dateS = explode(' ', $date_start);
522
        $a_arraySD = explode('-', $a_dateS[0]);
523
        $a_arraySH = explode(':', $a_dateS[1]);
524
        $date_start_to_compare = array_merge($a_arraySD, $a_arraySH);
525
526
        $a_dateE = explode(' ', $date_end);
527
        $a_arrayED = explode('-', $a_dateE[0]);
528
        $a_arrayEH = explode(':', $a_dateE[1]);
529
        $date_end_to_compare = array_merge($a_arrayED, $a_arrayEH);
530
531
        $lang = is_null($lang) ? '' : $lang;
532
533 View Code Duplication
        if (!checkdate($date_start_to_compare[1], $date_start_to_compare[2], $date_start_to_compare[0])) {
534
            echo Display::return_message(get_lang('InvalidStartDate'));
535
536
            return false;
537
        }
538
539 View Code Duplication
        if (($date_end_to_compare[1] ||
540
            $date_end_to_compare[2] ||
541
            $date_end_to_compare[0]) &&
542
            !checkdate($date_end_to_compare[1], $date_end_to_compare[2], $date_end_to_compare[0])
543
        ) {
544
            echo Display::return_message(get_lang('InvalidEndDate'));
545
546
            return false;
547
        }
548
549
        if (strlen(trim($title)) == 0) {
550
            echo Display::return_message(get_lang('InvalidTitle'));
551
552
            return false;
553
        }
554
555
        $start = api_get_utc_datetime($date_start);
556
        $end = api_get_utc_datetime($date_end);
557
558
        //Fixing urls that are sent by email
559
        //$content = str_replace('src=\"/home/', 'src=\"'.api_get_path(WEB_PATH).'home/', $content);
560
        //$content = str_replace('file=/home/', 'file='.api_get_path(WEB_PATH).'home/', $content);
561
        $content = str_replace('src=\"'.api_get_path(REL_HOME_PATH), 'src=\"'.api_get_path(WEB_PATH).api_get_path(REL_HOME_PATH), $content);
562
        $content = str_replace('file='.api_get_path(REL_HOME_PATH), 'file='.api_get_path(WEB_PATH).api_get_path(REL_HOME_PATH), $content);
563
564 View Code Duplication
        if ($sendEmailTest) {
565
            self::send_system_announcement_by_email(
566
                $title,
567
                $content,
568
                null,
569
                null,
570
                $lang,
571
                $sendEmailTest
572
            );
573
        } else {
574
            if ($send_mail == 1) {
575
                self::send_system_announcement_by_email(
576
                    $title,
577
                    $content,
578
                    $visibility,
579
                    $lang
580
                );
581
            }
582
        }
583
584
        $dateStart = new DateTime($start, new DateTimeZone('UTC'));
585
        $dateEnd = new DateTime($end, new DateTimeZone('UTC'));
586
587
        $announcement
588
            ->setLang($lang)
589
            ->setTitle($title)
590
            ->setContent($content)
591
            ->setDateStart($dateStart)
592
            ->setDateEnd($dateEnd)
593
            //->setVisibleTeacher($visible_teacher)
594
            //->setVisibleStudent($visible_student)
595
            //->setVisibleGuest($visible_guest)
596
            ->setAccessUrlId(api_get_current_access_url_id());
597
598
        $em->merge($announcement);
599
        $em->flush();
600
601
        // Update visibility
602
        $list = self::getVisibilityList();
603
        $table = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS);
604
        foreach ($list as $key => $title) {
605
            $value = isset($visibility[$key]) && $visibility[$key] ? 1 : 0;
606
            $sql = "UPDATE $table SET $key = '$value' WHERE id = $id";
607
            Database::query($sql);
608
        }
609
        return true;
610
    }
611
612
    /**
613
     * Deletes an announcement
614
     * @param int $id The identifier of the announcement that should be
615
     * @return bool    True on success, false on failure
616
     */
617
    public static function delete_announcement($id)
618
    {
619
        $table = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS);
620
        $id = intval($id);
621
        $sql = "DELETE FROM $table WHERE id =".$id;
622
        $res = Database::query($sql);
623
        if ($res === false) {
624
            return false;
625
        }
626
        return true;
627
    }
628
629
    /**
630
     * Gets an announcement
631
     * @param int $id The identifier of the announcement that should be
632
     * @return object    Object of class StdClass or the required class, containing the query result row
633
     */
634
    public static function get_announcement($id)
635
    {
636
        $db_table = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS);
637
        $id = intval($id);
638
        $sql = "SELECT * FROM ".$db_table." WHERE id = ".$id;
639
        $announcement = Database::fetch_object(Database::query($sql));
640
641
        return $announcement;
642
    }
643
644
    /**
645
     * Change the visibility of an announcement
646
     * @param int $id
647
     * @param int $user For who should the visibility be changed
648
     * @param bool $visible
649
     * @return bool True on success, false on failure
650
     */
651
    public static function set_visibility($id, $user, $visible)
652
    {
653
        $table = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS);
654
        $id = (int) $id;
655
        $list = array_keys(self::getVisibilityList());
656
        $user = trim($user);
657
        $visible = (int) $visible;
658
        if (!in_array($user, $list)) {
659
            return false;
660
        }
661
662
        $field = $user;
663
        $sql = "UPDATE $table SET ".$field." = '".$visible."'
664
                WHERE id='".$id."'";
665
        $res = Database::query($sql);
666
667
        if ($res === false) {
668
            return false;
669
        }
670
671
        return true;
672
    }
673
674
    /**
675
     * Send a system announcement by e-mail to all teachers/students depending on parameters
676
     * @param string $title
677
     * @param string $content
678
     * @param array $visibility
679
     * @param string $language Language (optional, considered for all languages if left empty)
680
     * @param bool $sendEmailTest
681
     * @return bool True if the message was sent or there was no destination matching.
682
     * False on database or e-mail sending error.
683
     */
684
    public static function send_system_announcement_by_email(
685
        $title,
686
        $content,
687
        $visibility,
688
        $language = null,
689
        $sendEmailTest = false
690
    ) {
691
        $content = str_replace(array('\r\n', '\n', '\r'), '', $content);
692
        $now = api_get_utc_datetime();
693
        $teacher = $visibility['visible_teacher'];
694
        $student = $visibility['visible_student'];
695
        if ($sendEmailTest) {
696
            MessageManager::send_message_simple(api_get_user_id(), $title, $content);
697
698
            return true;
699
        }
700
701
        $user_table = Database::get_main_table(TABLE_MAIN_USER);
702
        if (api_is_multiple_url_enabled()) {
703
            $current_access_url_id = api_get_current_access_url_id();
704
            $url_rel_user = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
705
            $url_condition = " INNER JOIN $url_rel_user uu ON uu.user_id = u.user_id ";
706
        }
707
708
        if ($teacher <> 0 && $student == 0) {
709
            $sql = "SELECT DISTINCT u.user_id FROM $user_table u $url_condition 
710
                    WHERE status = '1' ";
711
        }
712
713
        if ($teacher == 0 && $student <> 0) {
714
            $sql = "SELECT DISTINCT u.user_id FROM $user_table u $url_condition 
715
                    WHERE status = '5' ";
716
        }
717
718
        if ($teacher <> 0 && $student <> 0) {
719
            $sql = "SELECT DISTINCT u.user_id FROM $user_table u $url_condition 
720
                    WHERE 1 = 1 ";
721
        }
722
723
        if (!empty($language)) {
724
            //special condition because language was already treated for SQL insert before
725
            $sql .= " AND language = '".Database::escape_string($language)."' ";
726
        }
727
728
        if (api_is_multiple_url_enabled()) {
729
            $sql .= " AND access_url_id = '".$current_access_url_id."' ";
730
        }
731
732
        // Sent to active users.
733
        $sql .= " AND email <>'' AND active = 1 ";
734
735
        // Expiration date
736
        $sql .= " AND (expiration_date = '' OR expiration_date IS NULL OR expiration_date > '$now') ";
737
738
        if ((empty($teacher) || $teacher == '0') && (empty($student) || $student == '0')) {
739
            return true;
740
        }
741
742
        $result = Database::query($sql);
743
        if ($result === false) {
744
            return false;
745
        }
746
747
        $message_sent = false;
748
        while ($row = Database::fetch_array($result, 'ASSOC')) {
749
            MessageManager::send_message_simple($row['user_id'], $title, $content);
750
            $message_sent = true;
751
        }
752
753
        // Minor validation to clean up the attachment files in the announcement
754
        if (!empty($_FILES)) {
755
            $attachments = $_FILES;
756
            foreach ($attachments as $attachment) {
757
                unlink($attachment['tmp_name']);
758
            }
759
        }
760
761
        return $message_sent; //true if at least one e-mail was sent
762
    }
763
764
    /**
765
     * Displays announcements as an slideshow
766
     * @param string $visible see self::VISIBLE_* constants
767
     * @param int $id The identifier of the announcement to display
768
     *
769
     * @return string
770
     */
771
    public static function displayAnnouncementsSlider($visible, $id = null)
772
    {
773
        $user_selected_language = Database::escape_string(api_get_interface_language());
774
        $table = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS);
775
776
        $cut_size = 500;
777
        $now = api_get_utc_datetime();
778
        $sql = "SELECT * FROM $table
779
                WHERE
780
                    (lang = '$user_selected_language' OR lang = '') AND
781
                    ('$now' >= date_start AND '$now' <= date_end) ";
782
783
        $sql .= self::getVisibilityCondition($visible);
784
785
        if (isset($id) && !empty($id)) {
786
            $id = intval($id);
787
            $sql .= " AND id = $id ";
788
        }
789
790
        if (api_is_multiple_url_enabled()) {
791
            $current_url_id = api_get_current_access_url_id();
792
            $sql .= " AND access_url_id IN ('1', '$current_url_id') ";
793
        }
794
795
        $sql .= " ORDER BY date_start DESC";
796
        $result = Database::query($sql);
797
        $announcements = [];
798
799
        if (Database::num_rows($result) > 0) {
800
            while ($announcement = Database::fetch_object($result)) {
801
                $announcementData = [
802
                    'id' => $announcement->id,
803
                    'title' => $announcement->title,
804
                    'content' => $announcement->content,
805
                    'readMore' => null
806
                ];
807
808
                if (empty($id)) {
809
                    if (api_strlen(strip_tags($announcement->content)) > $cut_size) {
810
                        $announcementData['content'] = cut($announcement->content, $cut_size);
811
                        $announcementData['readMore'] = true;
812
                    }
813
                }
814
815
                $announcements[] = $announcementData;
816
            }
817
        }
818
819
        if (count($announcements) === 0) {
820
            return null;
821
        }
822
823
        $template = new Template(null, false, false);
824
        $template->assign('announcements', $announcements);
825
        $layout = $template->get_template('announcement/slider.tpl');
826
827
        return $template->fetch($layout);
828
    }
829
830
    /**
831
     * Get the HTML code for an announcement
832
     * @param int $announcementId The announcement ID
833
     * @param int $visibility The announcement visibility
834
     * @return string The HTML code
835
     */
836
    public static function displayAnnouncement($announcementId, $visibility)
837
    {
838
        $selectedUserLanguage = Database::escape_string(api_get_interface_language());
839
        $announcementTable = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS);
840
        $now = api_get_utc_datetime();
841
842
        $whereConditions = [
843
            "(lang = ? OR lang IS NULL OR lang = '') " => $selectedUserLanguage,
844
            "AND (? >= date_start AND ? <= date_end) " => [$now, $now],
845
            "AND id = ? " => intval($announcementId)
846
        ];
847
848
        $condition = self::getVisibilityCondition($visibility);
849
        $whereConditions[$condition] = 1;
850
851
        if (api_is_multiple_url_enabled()) {
852
            $whereConditions["AND access_url_id IN (1, ?) "] = api_get_current_access_url_id();
853
        }
854
855
        $announcement = Database::select(
856
            '*',
857
            $announcementTable,
858
            [
859
                'where' => $whereConditions,
860
                'order' => 'date_start',
861
            ],
862
            'first'
863
        );
864
865
        $template = new Template(null, false, false);
866
        $template->assign('announcement', $announcement);
867
        $layout = $template->get_template('announcement/view.tpl');
868
869
        return $template->fetch($layout);
870
    }
871
872
    /**
873
     * @return bool
874
     */
875
    public static function newRolesActivated()
876
    {
877
        /* In order to use this option you need to run this SQL changes :
878
         ALTER TABLE sys_announcement ADD COLUMN visible_drh INT DEFAULT 0;
879
         ALTER TABLE sys_announcement ADD COLUMN visible_session_admin INT DEFAULT 0;
880
         ALTER TABLE sys_announcement ADD COLUMN visible_boss INT DEFAULT 0;
881
        */
882
883
        return api_get_configuration_value('system_announce_extra_roles');
884
    }
885
886
    /**
887
     * @return string
888
     */
889
    public static function getCurrentUserVisibility()
890
    {
891
        if (api_is_anonymous()) {
892
            return SystemAnnouncementManager::VISIBLE_GUEST;
0 ignored issues
show
Coding Style introduced by
As per coding style, self should be used for accessing local static members.

This check looks for accesses to local static members using the fully qualified name instead of self::.

<?php

class Certificate {
    const TRIPLEDES_CBC = 'ASDFGHJKL';

    private $key;

    public function __construct()
    {
        $this->key = Certificate::TRIPLEDES_CBC;
    }
}

While this is perfectly valid, the fully qualified name of Certificate::TRIPLEDES_CBC could just as well be replaced by self::TRIPLEDES_CBC. Referencing local members with self:: assured the access will still work when the class is renamed, makes it perfectly clear that the member is in fact local and will usually be shorter.

Loading history...
893
        }
894
895
        if (self::newRolesActivated()) {
896
            if (api_is_student_boss()) {
897
                return SystemAnnouncementManager::VISIBLE_STUDENT_BOSS;
0 ignored issues
show
Coding Style introduced by
As per coding style, self should be used for accessing local static members.

This check looks for accesses to local static members using the fully qualified name instead of self::.

<?php

class Certificate {
    const TRIPLEDES_CBC = 'ASDFGHJKL';

    private $key;

    public function __construct()
    {
        $this->key = Certificate::TRIPLEDES_CBC;
    }
}

While this is perfectly valid, the fully qualified name of Certificate::TRIPLEDES_CBC could just as well be replaced by self::TRIPLEDES_CBC. Referencing local members with self:: assured the access will still work when the class is renamed, makes it perfectly clear that the member is in fact local and will usually be shorter.

Loading history...
898
            }
899
900
            if (api_is_session_admin()) {
901
                return SystemAnnouncementManager::VISIBLE_SESSION_ADMIN;
0 ignored issues
show
Coding Style introduced by
As per coding style, self should be used for accessing local static members.

This check looks for accesses to local static members using the fully qualified name instead of self::.

<?php

class Certificate {
    const TRIPLEDES_CBC = 'ASDFGHJKL';

    private $key;

    public function __construct()
    {
        $this->key = Certificate::TRIPLEDES_CBC;
    }
}

While this is perfectly valid, the fully qualified name of Certificate::TRIPLEDES_CBC could just as well be replaced by self::TRIPLEDES_CBC. Referencing local members with self:: assured the access will still work when the class is renamed, makes it perfectly clear that the member is in fact local and will usually be shorter.

Loading history...
902
            }
903
904
            if (api_is_drh()) {
905
                return SystemAnnouncementManager::VISIBLE_DRH;
0 ignored issues
show
Coding Style introduced by
As per coding style, self should be used for accessing local static members.

This check looks for accesses to local static members using the fully qualified name instead of self::.

<?php

class Certificate {
    const TRIPLEDES_CBC = 'ASDFGHJKL';

    private $key;

    public function __construct()
    {
        $this->key = Certificate::TRIPLEDES_CBC;
    }
}

While this is perfectly valid, the fully qualified name of Certificate::TRIPLEDES_CBC could just as well be replaced by self::TRIPLEDES_CBC. Referencing local members with self:: assured the access will still work when the class is renamed, makes it perfectly clear that the member is in fact local and will usually be shorter.

Loading history...
906
            }
907
908
            if (api_is_allowed_to_create_course()) {
909
                return SystemAnnouncementManager::VISIBLE_TEACHER;
0 ignored issues
show
Coding Style introduced by
As per coding style, self should be used for accessing local static members.

This check looks for accesses to local static members using the fully qualified name instead of self::.

<?php

class Certificate {
    const TRIPLEDES_CBC = 'ASDFGHJKL';

    private $key;

    public function __construct()
    {
        $this->key = Certificate::TRIPLEDES_CBC;
    }
}

While this is perfectly valid, the fully qualified name of Certificate::TRIPLEDES_CBC could just as well be replaced by self::TRIPLEDES_CBC. Referencing local members with self:: assured the access will still work when the class is renamed, makes it perfectly clear that the member is in fact local and will usually be shorter.

Loading history...
910
            } else {
911
                return SystemAnnouncementManager::VISIBLE_STUDENT;
0 ignored issues
show
Coding Style introduced by
As per coding style, self should be used for accessing local static members.

This check looks for accesses to local static members using the fully qualified name instead of self::.

<?php

class Certificate {
    const TRIPLEDES_CBC = 'ASDFGHJKL';

    private $key;

    public function __construct()
    {
        $this->key = Certificate::TRIPLEDES_CBC;
    }
}

While this is perfectly valid, the fully qualified name of Certificate::TRIPLEDES_CBC could just as well be replaced by self::TRIPLEDES_CBC. Referencing local members with self:: assured the access will still work when the class is renamed, makes it perfectly clear that the member is in fact local and will usually be shorter.

Loading history...
912
            }
913
        } else {
914
            // Default behaviour
915
            return api_is_allowed_to_create_course() ? SystemAnnouncementManager::VISIBLE_TEACHER : SystemAnnouncementManager::VISIBLE_STUDENT;
0 ignored issues
show
Coding Style introduced by
As per coding style, self should be used for accessing local static members.

This check looks for accesses to local static members using the fully qualified name instead of self::.

<?php

class Certificate {
    const TRIPLEDES_CBC = 'ASDFGHJKL';

    private $key;

    public function __construct()
    {
        $this->key = Certificate::TRIPLEDES_CBC;
    }
}

While this is perfectly valid, the fully qualified name of Certificate::TRIPLEDES_CBC could just as well be replaced by self::TRIPLEDES_CBC. Referencing local members with self:: assured the access will still work when the class is renamed, makes it perfectly clear that the member is in fact local and will usually be shorter.

Loading history...
916
        }
917
    }
918
}
919