Passed
Push — master ( 6d3a7a...482b77 )
by Julito
12:08 queued 02:23
created

SystemAnnouncementManager::getAnnouncements()   D

Complexity

Conditions 22
Paths 16

Size

Total Lines 103
Code Lines 62

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 22
eloc 62
nc 16
nop 2
dl 0
loc 103
rs 4.1666
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
2
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
    public const VISIBLE_DRH = 'visible_drh';
14
    public const VISIBLE_SESSION_ADMIN = 'visible_session_admin';
15
    public const VISIBLE_STUDENT_BOSS = 'visible_boss';
16
17
    public static function getVisibilityList(): array
18
    {
19
        $visibleToUsers = [
20
            self::VISIBLE_TEACHER => get_lang('Trainer'),
21
            self::VISIBLE_STUDENT => get_lang('Learner'),
22
            self::VISIBLE_GUEST => get_lang('Guest'),
23
        ];
24
        $visibleToUsers[self::VISIBLE_DRH] = get_lang('Human Resources Manager');
25
        $visibleToUsers[self::VISIBLE_SESSION_ADMIN] = get_lang('Session administrator');
26
        $visibleToUsers[self::VISIBLE_STUDENT_BOSS] = get_lang('LearnerBoss');
27
28
        return $visibleToUsers;
29
    }
30
31
    /**
32
     * @param string $visibility
33
     *
34
     * @return string
35
     */
36
    public static function getVisibilityCondition($visibility)
37
    {
38
        $list = self::getVisibilityList();
39
        $visibilityCondition = " AND ".self::VISIBLE_GUEST." = 1 ";
40
        if (in_array($visibility, array_keys($list))) {
41
            $visibilityCondition = " AND $visibility = 1 ";
42
        }
43
44
        return $visibilityCondition;
45
    }
46
47
    /**
48
     * Displays all announcements.
49
     *
50
     * @param string $visibility VISIBLE_GUEST, VISIBLE_STUDENT or VISIBLE_TEACHER
51
     * @param int    $id         The identifier of the announcement to display
52
     */
53
    public static function display_announcements($visibility, $id = -1)
54
    {
55
        $user_selected_language = api_get_interface_language();
56
        $db_table = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS);
57
        $tbl_announcement_group = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS_GROUPS);
58
        $userGroup = new UserGroup();
59
60
        $temp_user_groups = $userGroup->get_groups_by_user(api_get_user_id(), 0);
61
        $groups = [];
62
        foreach ($temp_user_groups as $user_group) {
63
            $groups = array_merge($groups, [$user_group['id']]);
64
            $groups = array_merge(
65
                $groups,
66
                $userGroup->get_parent_groups($user_group['id'])
67
            );
68
        }
69
70
        $groups_string = '('.implode($groups, ',').')';
71
        $now = api_get_utc_datetime();
72
        $sql = "SELECT *, DATE_FORMAT(date_start,'%d-%m-%Y %h:%i:%s') AS display_date
73
                FROM  $db_table
74
                WHERE
75
                    (lang='$user_selected_language' OR lang IS NULL) AND
76
                    (('$now' BETWEEN date_start AND date_end) OR date_end='0000-00-00') ";
77
78
        $sql .= self::getVisibilityCondition($visibility);
79
80
        if (count($groups) > 0) {
81
            $sql .= " OR id IN (
82
                        SELECT announcement_id FROM $tbl_announcement_group
83
                        WHERE group_id in $groups_string
84
                    ) ";
85
        }
86
        $current_access_url_id = 1;
87
        if (api_is_multiple_url_enabled()) {
88
            $current_access_url_id = api_get_current_access_url_id();
89
        }
90
        $sql .= " AND access_url_id = '$current_access_url_id' ";
91
        $sql .= " ORDER BY date_start DESC LIMIT 0,7";
92
93
        $announcements = Database::query($sql);
94
        if (Database::num_rows($announcements) > 0) {
95
            $query_string = ereg_replace('announcement=[1-9]+', '', $_SERVER['QUERY_STRING']);
0 ignored issues
show
Deprecated Code introduced by
The function ereg_replace() has been deprecated: 5.3.0 Use preg_replace() instead ( Ignorable by Annotation )

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

95
            $query_string = /** @scrutinizer ignore-deprecated */ ereg_replace('announcement=[1-9]+', '', $_SERVER['QUERY_STRING']);

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

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

Loading history...
96
            $query_string = ereg_replace('&$', '', $query_string);
0 ignored issues
show
Deprecated Code introduced by
The function ereg_replace() has been deprecated: 5.3.0 Use preg_replace() instead ( Ignorable by Annotation )

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

96
            $query_string = /** @scrutinizer ignore-deprecated */ ereg_replace('&$', '', $query_string);

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

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

Loading history...
97
            $url = api_get_self();
98
            echo '<div class="system_announcements">';
99
            echo '<h3>'.get_lang('Portal news').'</h3>';
100
            echo '<div style="margin:10px;text-align:right;"><a href="news_list.php">'.get_lang('More').'</a></div>';
101
102
            while ($announcement = Database::fetch_object($announcements)) {
103
                if ($id != $announcement->id) {
104
                    if (strlen($query_string) > 0) {
105
                        $show_url = 'news_list.php#'.$announcement->id;
106
                    } else {
107
                        $show_url = 'news_list.php#'.$announcement->id;
108
                    }
109
                    $display_date = api_convert_and_format_date($announcement->display_date, DATE_FORMAT_LONG);
110
                    echo '<a name="'.$announcement->id.'"></a>
111
                        <div class="system_announcement">
112
                            <div class="system_announcement_title">
113
                                <a name="ann'.$announcement->id.'" href="'.$show_url.'">'.
114
                        $announcement->title.'</a>
115
                            </div>
116
                            <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.'">'.
123
                        $announcement->title.'
124
                                </a>
125
                            </div>';
126
                }
127
                echo '<br />';
128
            }
129
            echo '</div>';
130
        }
131
    }
132
133
    /**
134
     * @param string $visibility
135
     * @param int    $id
136
     * @param int    $start
137
     * @param string $user_id
138
     *
139
     * @return string
140
     */
141
    public static function displayAllAnnouncements(
142
        $visibility,
143
        $id = -1,
0 ignored issues
show
Unused Code introduced by
The parameter $id is not used and could be removed. ( Ignorable by Annotation )

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

143
        /** @scrutinizer ignore-unused */ $id = -1,

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

Loading history...
144
        $start = 0,
145
        $user_id = ''
146
    ) {
147
        $user_selected_language = api_get_interface_language();
148
        $start = intval($start);
149
        $userGroup = new UserGroup();
150
        $tbl_announcement_group = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS_GROUPS);
151
        $temp_user_groups = $userGroup->get_groups_by_user(api_get_user_id(), 0);
152
        $groups = [];
153
        foreach ($temp_user_groups as $user_group) {
154
            $groups = array_merge($groups, [$user_group['id']]);
155
            $groups = array_merge($groups, $userGroup->get_parent_groups($user_group['id']));
156
        }
157
158
        // Checks if tables exists to not break platform not updated
159
        $groups_string = '('.implode($groups, ',').')';
160
161
        $table = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS);
162
        $now = api_get_utc_datetime();
163
164
        $sql = "SELECT * FROM $table
165
                WHERE
166
                    (lang = '$user_selected_language' OR lang IS NULL) AND
167
                    ( '$now' >= date_start AND '$now' <= date_end) ";
168
169
        $sql .= self::getVisibilityCondition($visibility);
170
171
        if (count($groups) > 0) {
172
            $sql .= " OR id IN (
173
                    SELECT announcement_id FROM $tbl_announcement_group
174
                    WHERE group_id in $groups_string
175
                    ) ";
176
        }
177
178
        if (api_is_multiple_url_enabled()) {
179
            $current_access_url_id = api_get_current_access_url_id();
180
            $sql .= " AND access_url_id IN ('1', '$current_access_url_id')";
181
        }
182
183
        if (!isset($_GET['start']) || 0 == $_GET['start']) {
184
            $sql .= " ORDER BY date_start DESC LIMIT ".$start.",20";
185
        } else {
186
            $sql .= " ORDER BY date_start DESC LIMIT ".($start + 1).",20";
187
        }
188
        $announcements = Database::query($sql);
189
        $content = '';
190
        if (Database::num_rows($announcements) > 0) {
191
            $content .= '<div class="system_announcements">';
192
            $content .= '<h3>'.get_lang('Portal news').'</h3>';
193
            $content .= '<table align="center">';
194
            $content .= '<tr>';
195
            $content .= '<td>';
196
            $content .= self::display_arrow($user_id);
197
            $content .= '</td>';
198
            $content .= '</tr>';
199
            $content .= '</table>';
200
            $content .= '<table align="center" border="0" width="900px">';
201
            while ($announcement = Database::fetch_object($announcements)) {
202
                $display_date = api_convert_and_format_date($announcement->display_date, DATE_FORMAT_LONG);
203
                $content .= '<tr><td>';
204
                $content .= '<a name="'.$announcement->id.'"></a>
205
                        <div class="system_announcement">
206
                        <h2>'.$announcement->title.'</h2>
207
                        <div class="system_announcement_date">'.$display_date.'</div>
208
                        <br />
209
                        <div class="system_announcement_content">'
210
                    .$announcement->content.'
211
                        </div>
212
                      </div><br />';
213
                $content .= '</tr></td>';
214
            }
215
            $content .= '</table>';
216
217
            $content .= '<table align="center">';
218
            $content .= '<tr>';
219
            $content .= '<td>';
220
            $content .= self::display_arrow($user_id);
221
            $content .= '</td>';
222
            $content .= '</tr>';
223
            $content .= '</table>';
224
            $content .= '</div>';
225
        }
226
227
        return $content;
228
    }
229
230
    /**
231
     * @param int $user_id
232
     *
233
     * @return string
234
     */
235
    public static function display_arrow($user_id)
236
    {
237
        $start = (int) $_GET['start'];
238
        $nb_announcement = self::count_nb_announcement($start, $user_id);
239
        $next = ((int) $_GET['start'] + 19);
240
        $prev = ((int) $_GET['start'] - 19);
241
        $content = '';
242
        if (!isset($_GET['start']) || 0 == $_GET['start']) {
243
            if ($nb_announcement > 20) {
244
                $content .= '<a href="news_list.php?start='.$next.'">'.get_lang('Next').' >> </a>';
245
            }
246
        } else {
247
            echo '<a href="news_list.php?start='.$prev.'"> << '.get_lang('Prev').'</a>';
248
            if ($nb_announcement > 20) {
249
                $content .= '<a href="news_list.php?start='.$next.'">'.get_lang('Next').' >> </a>';
250
            }
251
        }
252
253
        return $content;
254
    }
255
256
    /**
257
     * Update announcements picture.
258
     *
259
     * @param int $announcement_id
260
     * @param   string  the full system name of the image
261
     * from which course picture will be created
262
     * @param string $cropParameters Optional string that contents "x,y,width,height" of a cropped image format
263
     *
264
     * @return bool Returns the resulting. In case of internal error or negative validation returns FALSE.
265
     */
266
    public static function update_announcements_picture(
267
        $announcement_id,
268
        $source_file = null,
269
        $cropParameters = null
270
    ) {
271
        if (empty($announcement_id)) {
272
            return false;
273
        }
274
275
        // course path
276
        $store_path = api_get_path(SYS_UPLOAD_PATH).'announcements';
277
278
        if (!file_exists($store_path)) {
279
            mkdir($store_path);
280
        }
281
        // image name
282
        $announcementPicture = $store_path.'/announcement_'.$announcement_id.'.png';
283
        $announcementPictureSmall = $store_path.'/announcement_'.$announcement_id.'_100x100.png';
284
285
        if (file_exists($announcementPicture)) {
286
            unlink($announcementPicture);
287
        }
288
        if (file_exists($announcementPictureSmall)) {
289
            unlink($announcementPictureSmall);
290
        }
291
292
        //Crop the image to adjust 4:3 ratio
293
        $image = new Image($source_file);
294
        $image->crop($cropParameters);
295
296
        $medium = new Image($source_file);
297
        $medium->resize(100);
298
        $medium->send_image($announcementPictureSmall, -1, 'png');
299
300
        $normal = new Image($source_file);
301
        $normal->send_image($announcementPicture, -1, 'png');
302
303
        $result = $normal;
304
305
        return $result ? $result : false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $result ? $result : false returns the type Image which is incompatible with the documented return type boolean.
Loading history...
introduced by
$result is of type Image, thus it always evaluated to true.
Loading history...
306
    }
307
308
    /**
309
     * @param int    $start
310
     * @param string $user_id
311
     *
312
     * @return int
313
     */
314
    public static function count_nb_announcement($start = 0, $user_id = '')
0 ignored issues
show
Unused Code introduced by
The parameter $user_id is not used and could be removed. ( Ignorable by Annotation )

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

314
    public static function count_nb_announcement($start = 0, /** @scrutinizer ignore-unused */ $user_id = '')

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

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

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
1137
    {
1138
        $store_path = api_get_path(SYS_UPLOAD_PATH).'announcements';
1139
        $announcementPicture = $store_path.'/announcement_'.$announcementId.'.png';
1140
        if (file_exists($announcementPicture)) {
1141
            $web_path = api_get_path(WEB_UPLOAD_PATH).'announcements';
1142
            $urlPicture = $web_path.'/announcement_'.$announcementId.'.png';
1143
1144
            return $urlPicture;
1145
        }
1146
1147
        return null;
1148
    }
1149
}
1150