Passed
Push — 1.11.x ( 1c9973...df255e )
by Julito
13:56
created

SystemAnnouncementManager::update_announcement()   C

Complexity

Conditions 16
Paths 67

Size

Total Lines 127
Code Lines 73

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 16
eloc 73
c 2
b 0
f 0
nc 67
nop 12
dl 0
loc 127
rs 5.5666

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
            }
384
385
            return $resultId;
386
        }
387
388
        return false;
389
    }
390
391
    /**
392
     * Makes the announcement id visible only for groups in groups_array.
393
     *
394
     * @param int   $announcement_id
395
     * @param array $groups array of group id
396
     *
397
     * @return bool
398
     */
399
    public static function announcement_for_groups($announcement_id, $groups)
400
    {
401
        $tbl_announcement_group = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS_GROUPS);
402
        $announcement_id = (int) $announcement_id;
403
404
        if (empty($announcement_id)) {
405
            return false;
406
        }
407
408
        // First delete all group associations for this announcement
409
        $sql = "DELETE FROM $tbl_announcement_group WHERE announcement_id= $announcement_id";
410
        Database::query($sql);
411
412
        if (!empty($groups)) {
413
            foreach ($groups as $group_id) {
414
                if (intval($group_id) != 0) {
415
                    $sql = "INSERT INTO $tbl_announcement_group SET
416
                            announcement_id=".$announcement_id.",
417
                            group_id=".intval($group_id);
418
                    Database::query($sql);
419
                }
420
            }
421
        }
422
423
        return true;
424
    }
425
426
    /**
427
     * Gets the groups of this announce.
428
     *
429
     * @param int announcement id
430
     *
431
     * @return array array of group id
432
     */
433
    public static function get_announcement_groups($announcement_id)
434
    {
435
        $tbl_announcement_group = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS_GROUPS);
436
        $tbl_group = Database::get_main_table(TABLE_USERGROUP);
437
        //first delete all group associations for this announcement
438
        $sql = "SELECT
439
                    g.id as group_id,
440
                    g.name as group_name
441
                FROM $tbl_group g , $tbl_announcement_group ag
442
                WHERE
443
                    announcement_id =".intval($announcement_id)." AND
444
                    ag.group_id = g.id";
445
        $res = Database::query($sql);
446
447
        return Database::store_result($res);
448
    }
449
450
    /**
451
     * Updates an announcement to the database.
452
     *
453
     * @param int    $id            of the announcement
454
     * @param string $title         title of the announcement
455
     * @param string $content       content of the announcement
456
     * @param array  $date_start    start date (0 => day ; 1 => month ; 2 => year ; 3 => hour ; 4 => minute)
457
     * @param array  $date_end      end date of (0 => day ; 1 => month ; 2 => year ; 3 => hour ; 4 => minute)
458
     * @param array  $visibility
459
     * @param array  $lang
460
     * @param int    $send_mail
461
     * @param bool   $sendEmailTest
462
     * @param int    $careerId
463
     * @param int    $promotionId
464
     * @param array  $groups
465
     *
466
     * @return bool True on success, false on failure
467
     */
468
    public static function update_announcement(
469
        $id,
470
        $title,
471
        $content,
472
        $date_start,
473
        $date_end,
474
        $visibility,
475
        $lang = null,
476
        $send_mail = 0,
477
        $sendEmailTest = false,
478
        $careerId = 0,
479
        $promotionId = 0,
480
        $groups = []
481
    ) {
482
        $em = Database::getManager();
483
        $announcement = $em->find('ChamiloCoreBundle:SysAnnouncement', $id);
484
        if (!$announcement) {
485
            return false;
486
        }
487
488
        $a_dateS = explode(' ', $date_start);
489
        $a_arraySD = explode('-', $a_dateS[0]);
490
        $a_arraySH = explode(':', $a_dateS[1]);
491
        $date_start_to_compare = array_merge($a_arraySD, $a_arraySH);
492
493
        $a_dateE = explode(' ', $date_end);
494
        $a_arrayED = explode('-', $a_dateE[0]);
495
        $a_arrayEH = explode(':', $a_dateE[1]);
496
        $date_end_to_compare = array_merge($a_arrayED, $a_arrayEH);
497
498
        $lang = is_null($lang) ? '' : $lang;
499
500
        if (!checkdate($date_start_to_compare[1], $date_start_to_compare[2], $date_start_to_compare[0])) {
501
            echo Display::return_message(get_lang('InvalidStartDate'));
502
503
            return false;
504
        }
505
506
        if (($date_end_to_compare[1] ||
507
            $date_end_to_compare[2] ||
508
            $date_end_to_compare[0]) &&
509
            !checkdate($date_end_to_compare[1], $date_end_to_compare[2], $date_end_to_compare[0])
510
        ) {
511
            echo Display::return_message(get_lang('InvalidEndDate'));
512
513
            return false;
514
        }
515
516
        if (strlen(trim($title)) == 0) {
517
            echo Display::return_message(get_lang('InvalidTitle'));
518
519
            return false;
520
        }
521
522
        $start = api_get_utc_datetime($date_start);
523
        $end = api_get_utc_datetime($date_end);
524
525
        //Fixing urls that are sent by email
526
        //$content = str_replace('src=\"/home/', 'src=\"'.api_get_path(WEB_PATH).'home/', $content);
527
        //$content = str_replace('file=/home/', 'file='.api_get_path(WEB_PATH).'home/', $content);
528
        $content = str_replace(
529
            'src=\"'.api_get_path(REL_HOME_PATH),
530
            'src=\"'.api_get_path(WEB_PATH).api_get_path(REL_HOME_PATH),
531
            $content
532
        );
533
        $content = str_replace(
534
            'file='.api_get_path(REL_HOME_PATH),
535
            'file='.api_get_path(WEB_PATH).api_get_path(REL_HOME_PATH),
536
            $content
537
        );
538
539
        $dateStart = new DateTime($start, new DateTimeZone('UTC'));
540
        $dateEnd = new DateTime($end, new DateTimeZone('UTC'));
541
542
        $announcement
543
            ->setLang($lang)
544
            ->setTitle($title)
545
            ->setContent($content)
546
            ->setDateStart($dateStart)
547
            ->setDateEnd($dateEnd)
548
            //->setVisibleTeacher($visible_teacher)
549
            //->setVisibleStudent($visible_student)
550
            //->setVisibleGuest($visible_guest)
551
            ->setAccessUrlId(api_get_current_access_url_id());
552
553
        $em->persist($announcement);
554
        $em->flush();
555
556
        // Update visibility
557
        $list = self::getVisibilityList();
558
        $table = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS);
559
560
        if (api_get_configuration_value('allow_careers_in_global_announcements') && !empty($careerId)) {
561
            $params = [];
562
            $params['career_id'] = (int) $careerId;
563
            $params['promotion_id'] = (int) $promotionId;
564
            Database::update(
565
                $table,
566
                $params,
567
                ['id = ? ' => $id]
568
            );
569
        }
570
571
        foreach ($list as $key => $title) {
0 ignored issues
show
introduced by
$title is overwriting one of the parameters of this function.
Loading history...
572
            $value = isset($visibility[$key]) && $visibility[$key] ? 1 : 0;
573
            $sql = "UPDATE $table SET $key = '$value' WHERE id = $id";
574
            Database::query($sql);
575
        }
576
577
        if ($sendEmailTest) {
578
            self::send_system_announcement_by_email(
579
                $id,
580
                $visibility,
581
                true
582
            );
583
        } else {
584
            if ($send_mail == 1) {
585
                self::send_system_announcement_by_email(
586
                    $id,
587
                    $visibility,
588
                    false,
589
                    $groups
590
                );
591
            }
592
        }
593
594
        return true;
595
    }
596
597
    /**
598
     * Deletes an announcement.
599
     *
600
     * @param int $id The identifier of the announcement that should be
601
     *
602
     * @return bool True on success, false on failure
603
     */
604
    public static function delete_announcement($id)
605
    {
606
        $table = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS);
607
        $id = (int) $id;
608
        $sql = "DELETE FROM $table WHERE id =".$id;
609
        $res = Database::query($sql);
610
        if ($res === false) {
611
            return false;
612
        }
613
614
        return true;
615
    }
616
617
    /**
618
     * Gets an announcement.
619
     *
620
     * @param int $id The identifier of the announcement that should be
621
     *
622
     * @return object Object of class StdClass or the required class, containing the query result row
623
     */
624
    public static function get_announcement($id)
625
    {
626
        $table = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS);
627
        $id = (int) $id;
628
        $sql = "SELECT * FROM ".$table." WHERE id = ".$id;
629
        $announcement = Database::fetch_object(Database::query($sql));
630
631
        return $announcement;
632
    }
633
634
    /**
635
     * Change the visibility of an announcement.
636
     *
637
     * @param int  $id
638
     * @param int  $user    For who should the visibility be changed
639
     * @param bool $visible
640
     *
641
     * @return bool True on success, false on failure
642
     */
643
    public static function set_visibility($id, $user, $visible)
644
    {
645
        $table = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS);
646
        $id = (int) $id;
647
        $list = array_keys(self::getVisibilityList());
648
        $user = trim($user);
649
        $visible = (int) $visible;
650
        if (!in_array($user, $list)) {
651
            return false;
652
        }
653
654
        $field = $user;
655
        $sql = "UPDATE $table SET ".$field." = '".$visible."'
656
                WHERE id='".$id."'";
657
        $res = Database::query($sql);
658
659
        if ($res === false) {
660
            return false;
661
        }
662
663
        return true;
664
    }
665
666
    /**
667
     * Send a system announcement by e-mail to all teachers/students depending on parameters.
668
     *
669
     * @param int   $id
670
     * @param array $visibility
671
     * @param bool  $sendEmailTest
672
     * @param array $groups
673
     *
674
     * @return bool True if the message was sent or there was no destination matching.
675
     *              False on database or e-mail sending error.
676
     */
677
    public static function send_system_announcement_by_email($id, $visibility, $sendEmailTest = false, $groups = [])
678
    {
679
        $announcement = self::get_announcement($id);
680
681
        if (empty($announcement)) {
682
            return false;
683
        }
684
685
        $title = $announcement->title;
686
        $content = $announcement->content;
687
        $language = $announcement->lang;
688
        $content = str_replace(['\r\n', '\n', '\r'], '', $content);
689
        $now = api_get_utc_datetime();
690
        $teacher = $visibility['visible_teacher'];
691
        $student = $visibility['visible_student'];
692
        if ($sendEmailTest) {
693
            MessageManager::send_message_simple(api_get_user_id(), $title, $content);
694
695
            return true;
696
        }
697
698
        $whereUsersInGroup = '';
699
        $usersId = [];
700
        foreach ($groups as $groupId) {
701
            if (0 != $groupId) {
702
                $tblGroupRelUser = Database::get_main_table(TABLE_USERGROUP_REL_USER);
703
                $sql = "SELECT user_id FROM $tblGroupRelUser WHERE usergroup_id = $groupId";
704
                $result = Database::query($sql);
705
                $data = Database::store_result($result);
706
                foreach ($data as $userArray) {
707
                    $usersId[] = $userArray['user_id'];
708
                }
709
            }
710
        }
711
712
        if (!empty($usersId)) {
713
            $usersId = implode(',', $usersId);
714
            $whereUsersInGroup = " AND u.user_id in ($usersId) ";
715
        }
716
717
        $urlJoin = '';
718
        $urlCondition = '';
719
        $user_table = Database::get_main_table(TABLE_MAIN_USER);
720
        if (api_is_multiple_url_enabled()) {
721
            $current_access_url_id = api_get_current_access_url_id();
722
            $url_rel_user = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
723
            $urlJoin = " INNER JOIN $url_rel_user uu ON uu.user_id = u.user_id ";
724
            $urlCondition = " AND access_url_id = '".$current_access_url_id."' ";
725
        }
726
727
        if ($teacher != 0 && $student == 0) {
728
            $sql = "SELECT DISTINCT u.user_id FROM $user_table u $urlJoin
729
                    WHERE status = '1' $urlCondition $whereUsersInGroup";
730
        }
731
732
        if ($teacher == 0 && $student != 0) {
733
            $sql = "SELECT DISTINCT u.user_id FROM $user_table u $urlJoin
734
                    WHERE status = '5' $urlCondition $whereUsersInGroup";
735
        }
736
737
        if ($teacher != 0 && $student != 0) {
738
            $sql = "SELECT DISTINCT u.user_id FROM $user_table u $urlJoin
739
                    WHERE 1 = 1 $urlCondition $whereUsersInGroup";
740
        }
741
742
        if (!isset($sql)) {
743
            return false;
744
        }
745
746
        if (!empty($language)) {
747
            //special condition because language was already treated for SQL insert before
748
            $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...
749
        }
750
751
        // Sent to active users.
752
        $sql .= " AND email <>'' AND active = 1 ";
753
754
        // Expiration date
755
        $sql .= " AND (expiration_date = '' OR expiration_date IS NULL OR expiration_date > '$now') ";
756
757
        if ((empty($teacher) || $teacher == '0') && (empty($student) || $student == '0')) {
758
            return true;
759
        }
760
761
        $userListToFilter = [];
762
        // @todo check if other filters will apply for the career/promotion option.
763
        if (isset($announcement->career_id) && !empty($announcement->career_id)) {
764
            $promotion = new Promotion();
765
            $promotionList = $promotion->get_all_promotions_by_career_id($announcement->career_id);
766
            if (isset($announcement->promotion_id) && !empty($announcement->promotion_id)) {
767
                $promotionList = [];
768
                $promotionList[] = $promotion->get($announcement->promotion_id);
769
            }
770
771
            if (!empty($promotionList)) {
772
                foreach ($promotionList as $promotion) {
773
                    $sessionList = SessionManager::get_all_sessions_by_promotion($promotion['id']);
774
                    foreach ($sessionList as $session) {
775
                        if ($teacher) {
776
                            $users = SessionManager::get_users_by_session($session['id'], 2);
777
                            if (!empty($users)) {
778
                                $userListToFilter = array_merge($users, $userListToFilter);
779
                            }
780
                        }
781
782
                        if ($student) {
783
                            $users = SessionManager::get_users_by_session($session['id'], 0);
784
                            if (!empty($users)) {
785
                                $userListToFilter = array_merge($users, $userListToFilter);
786
                            }
787
                        }
788
                    }
789
                }
790
            }
791
        }
792
793
        if (!empty($userListToFilter)) {
794
            $userListToFilter = array_column($userListToFilter, 'user_id');
795
            $userListToFilterToString = implode("', '", $userListToFilter);
796
            $sql .= " AND (u.user_id IN ('$userListToFilterToString') ) ";
797
        }
798
799
        $result = Database::query($sql);
800
        if ($result === false) {
801
            return false;
802
        }
803
804
        $message_sent = false;
805
        while ($row = Database::fetch_array($result, 'ASSOC')) {
806
            MessageManager::send_message_simple($row['user_id'], $title, $content);
807
            $message_sent = true;
808
        }
809
810
        // Minor validation to clean up the attachment files in the announcement
811
        if (!empty($_FILES)) {
812
            $attachments = $_FILES;
813
            foreach ($attachments as $attachment) {
814
                unlink($attachment['tmp_name']);
815
            }
816
        }
817
818
        return $message_sent; //true if at least one e-mail was sent
819
    }
820
821
    /**
822
     * Returns the group announcements where the user is subscribed.
823
     *
824
     * @param $userId
825
     * @param $visible
826
     *
827
     * @throws \Exception
828
     *
829
     * @return array
830
     */
831
    public static function getAnnouncementsForGroups($userId, $visible)
832
    {
833
        $userSelectedLanguage = Database::escape_string(api_get_interface_language());
834
        $tblSysAnnouncements = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS);
835
        $tblGrpAnnouncements = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS_GROUPS);
836
        $tblUsrGrp = Database::get_main_table(TABLE_USERGROUP_REL_USER);
837
        $now = api_get_utc_datetime();
838
839
        $sql = "SELECT sys_announcement.*
840
        FROM $tblSysAnnouncements AS sys_announcement
841
        INNER JOIN $tblGrpAnnouncements AS announcement_rel_group
842
            ON sys_announcement.id = announcement_rel_group.announcement_id
843
        INNER JOIN $tblUsrGrp AS usergroup_rel_user
844
            ON usergroup_rel_user.usergroup_id = announcement_rel_group.group_id
845
        WHERE
846
            usergroup_rel_user.user_id = $userId AND
847
            (sys_announcement.lang = '$userSelectedLanguage' OR sys_announcement.lang = '') AND
848
            ('$now' >= sys_announcement.date_start AND '$now' <= sys_announcement.date_end)";
849
        $sql .= self::getVisibilityCondition($visible);
850
        $result = Database::query($sql);
851
        $data = Database::store_result($result, 'ASSOC');
852
        Database::free_result($result);
853
854
        return $data;
855
    }
856
857
    /**
858
     * Displays announcements as an slideshow.
859
     *
860
     * @param string $visible see self::VISIBLE_* constants
861
     * @param int    $id      The identifier of the announcement to display
862
     *
863
     * @return string
864
     */
865
    public static function displayAnnouncementsSlider($visible, $id = null)
866
    {
867
        $user_selected_language = Database::escape_string(api_get_interface_language());
868
        $table = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS);
869
        $tblGrpAnnouncements = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS_GROUPS);
870
871
        $cut_size = 500;
872
        $now = api_get_utc_datetime();
873
        //Exclude announcement to groups
874
        $sql = "SELECT sys_announcement.*
875
            FROM $table as sys_announcement
876
            LEFT JOIN $tblGrpAnnouncements AS announcement_rel_group
877
                ON sys_announcement.id = announcement_rel_group.announcement_id
878
            WHERE
879
                (sys_announcement.lang = '$user_selected_language' OR sys_announcement.lang = '') AND
880
                ('$now' >= sys_announcement.date_start AND '$now' <= sys_announcement.date_end) AND
881
                announcement_rel_group.group_id is null";
882
883
        $sql .= self::getVisibilityCondition($visible);
884
885
        if (isset($id) && !empty($id)) {
886
            $id = (int) $id;
887
            $sql .= " AND id = $id ";
888
        }
889
890
        if (api_is_multiple_url_enabled()) {
891
            $current_url_id = api_get_current_access_url_id();
892
            $sql .= " AND access_url_id IN ('1', '$current_url_id') ";
893
        }
894
895
        $checkCareers = api_get_configuration_value('allow_careers_in_global_announcements') === true;
896
897
        $userId = api_get_user_id();
898
899
        $promotion = new Promotion();
900
        $sql .= ' ORDER BY date_start DESC';
901
        $result = Database::query($sql);
902
        $announcements = [];
903
        if (Database::num_rows($result) > 0) {
904
            while ($announcement = Database::fetch_object($result)) {
905
                if ($checkCareers && !empty($announcement->career_id)) {
906
                    $promotionList = [];
907
                    if (!empty($announcement->promotion_id)) {
908
                        $promotionList[] = $announcement->promotion_id;
909
                    } else {
910
                        $promotionList = $promotion->get_all_promotions_by_career_id($announcement->career_id);
911
                        if (!empty($promotionList)) {
912
                            $promotionList = array_column($promotionList, 'id');
913
                        }
914
                    }
915
916
                    $show = false;
917
                    foreach ($promotionList as $promotionId) {
918
                        $sessionList = SessionManager::get_all_sessions_by_promotion($promotionId);
919
                        foreach ($sessionList as $session) {
920
                            $sessionId = $session['id'];
921
                            // Check student
922
                            if ($visible === self::VISIBLE_STUDENT &&
923
                                SessionManager::isUserSubscribedAsStudent($sessionId, $userId)
924
                            ) {
925
                                $show = true;
926
                                break 2;
927
                            }
928
929
                            if ($visible === self::VISIBLE_TEACHER &&
930
                                SessionManager::user_is_general_coach($userId, $sessionId)
931
                            ) {
932
                                $show = true;
933
                                break 2;
934
                            }
935
936
                            // Check course coach
937
                            $coaches = SessionManager::getCoachesBySession($sessionId);
938
939
                            if ($visible === self::VISIBLE_TEACHER && in_array($userId, $coaches)) {
940
                                $show = true;
941
                                break 2;
942
                            }
943
                        }
944
                    }
945
946
                    if (false === $show) {
947
                        continue;
948
                    }
949
                }
950
951
                $announcementData = [
952
                    'id' => $announcement->id,
953
                    'title' => $announcement->title,
954
                    'content' => $announcement->content,
955
                    'readMore' => null,
956
                ];
957
958
                if (empty($id)) {
959
                    if (api_strlen(strip_tags($announcement->content)) > $cut_size) {
960
                        //$announcementData['content'] = cut($announcement->content, $cut_size);
961
                        $announcementData['readMore'] = true;
962
                    }
963
                }
964
965
                $announcements[] = $announcementData;
966
            }
967
        }
968
969
        /** Show announcement of group */
970
        $announcementToGroup = self::getAnnouncementsForGroups($userId, $visible);
971
        $totalAnnouncementToGroup = count($announcementToGroup);
972
        for ($i = 0; $i < $totalAnnouncementToGroup; $i++) {
973
            $announcement = $announcementToGroup[$i];
974
            $announcementData = [
975
                'id' => $announcement['id'],
976
                'title' => $announcement['title'],
977
                'content' => $announcement['content'],
978
                'readMore' => null,
979
            ];
980
            $content = $announcement['content'];
981
            if (api_strlen(strip_tags($content)) > $cut_size) {
982
                //$announcementData['content'] = cut($content, $cut_size);
983
                $announcementData['readMore'] = true;
984
            }
985
            $announcements[] = $announcementData;
986
        }
987
988
        if (count($announcements) === 0) {
989
            return null;
990
        }
991
992
        $template = new Template(null, false, false);
993
        $template->assign('announcements', $announcements);
994
        $layout = $template->get_template('announcement/slider.tpl');
995
996
        return $template->fetch($layout);
997
    }
998
999
    /**
1000
     * Get the HTML code for an announcement.
1001
     *
1002
     * @param int $announcementId The announcement ID
1003
     * @param int $visibility     The announcement visibility
1004
     *
1005
     * @return string The HTML code
1006
     */
1007
    public static function displayAnnouncement($announcementId, $visibility)
1008
    {
1009
        $selectedUserLanguage = Database::escape_string(api_get_interface_language());
1010
        $announcementTable = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS);
1011
        $now = api_get_utc_datetime();
1012
        $announcementId = (int) $announcementId;
1013
1014
        $whereConditions = [
1015
            "(lang = ? OR lang IS NULL OR lang = '') " => $selectedUserLanguage,
1016
            "AND (? >= date_start AND ? <= date_end) " => [$now, $now],
1017
            "AND id = ? " => $announcementId,
1018
        ];
1019
1020
        $condition = self::getVisibilityCondition($visibility);
1021
        $whereConditions[$condition] = 1;
1022
1023
        if (api_is_multiple_url_enabled()) {
1024
            $whereConditions["AND access_url_id IN (1, ?) "] = api_get_current_access_url_id();
1025
        }
1026
1027
        $announcement = Database::select(
1028
            '*',
1029
            $announcementTable,
1030
            [
1031
                'where' => $whereConditions,
1032
                'order' => 'date_start',
1033
            ],
1034
            'first'
1035
        );
1036
1037
        $template = new Template(null, false, false);
1038
        $template->assign('announcement', $announcement);
1039
        $layout = $template->get_template('announcement/view.tpl');
1040
1041
        return $template->fetch($layout);
1042
    }
1043
1044
    /**
1045
     * @return bool
1046
     */
1047
    public static function newRolesActivated()
1048
    {
1049
        /* In order to use this option you need to run this SQL changes :
1050
         ALTER TABLE sys_announcement ADD COLUMN visible_drh INT DEFAULT 0;
1051
         ALTER TABLE sys_announcement ADD COLUMN visible_session_admin INT DEFAULT 0;
1052
         ALTER TABLE sys_announcement ADD COLUMN visible_boss INT DEFAULT 0;
1053
        */
1054
        return api_get_configuration_value('system_announce_extra_roles');
1055
    }
1056
1057
    /**
1058
     * @return string
1059
     */
1060
    public static function getCurrentUserVisibility()
1061
    {
1062
        if (api_is_anonymous()) {
1063
            return SystemAnnouncementManager::VISIBLE_GUEST;
1064
        }
1065
1066
        if (self::newRolesActivated()) {
1067
            if (api_is_student_boss()) {
1068
                return SystemAnnouncementManager::VISIBLE_STUDENT_BOSS;
1069
            }
1070
1071
            if (api_is_session_admin()) {
1072
                return SystemAnnouncementManager::VISIBLE_SESSION_ADMIN;
1073
            }
1074
1075
            if (api_is_drh()) {
1076
                return SystemAnnouncementManager::VISIBLE_DRH;
1077
            }
1078
1079
            if (api_is_teacher()) {
1080
                return SystemAnnouncementManager::VISIBLE_TEACHER;
1081
            } else {
1082
                return SystemAnnouncementManager::VISIBLE_STUDENT;
1083
            }
1084
        } else {
1085
            // Default behaviour
1086
            return api_is_teacher() ? SystemAnnouncementManager::VISIBLE_TEACHER : SystemAnnouncementManager::VISIBLE_STUDENT;
1087
        }
1088
    }
1089
}
1090