Passed
Push — master ( c22b6a...5f79f5 )
by Julito
11:21
created

get_number_of_courses()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
/**
6
 * This script shows a list of courses and allows searching for courses codes
7
 * and names.
8
 */
9
$cidReset = true;
10
require_once __DIR__.'/../inc/global.inc.php';
11
$this_section = SECTION_PLATFORM_ADMIN;
12
api_protect_admin_script();
13
$sessionId = isset($_GET['session_id']) ? $_GET['session_id'] : null;
14
15
/**
16
 * Get the number of courses which will be displayed.
17
 *
18
 * @throws Exception
19
 *
20
 * @return int The number of matching courses
21
 */
22
function get_number_of_courses()
23
{
24
    return get_course_data(0, 0, 0, 0, null, true);
25
}
26
27
/**
28
 * Get course data to display.
29
 *
30
 * @param int    $from
31
 * @param int    $number_of_items
32
 * @param int    $column
33
 * @param string $direction
34
 *
35
 * @throws Exception
36
 *
37
 * @return array
38
 */
39
function get_course_data($from, $number_of_items, $column, $direction, $dataFunctions = [], $getCount = false)
40
{
41
    $course_table = Database::get_main_table(TABLE_MAIN_COURSE);
42
    $tblCourseCategory = Database::get_main_table(TABLE_MAIN_CATEGORY);
43
44
    $select = "SELECT
45
                course.code AS col0,
46
                title AS col1,
47
                course.code AS col2,
48
                course_language AS col3,
49
                category.code AS col4,
50
                subscribe AS col5,
51
                unsubscribe AS col6,
52
                course.code AS col7,
53
                visibility AS col8,
54
                directory as col9,
55
                visual_code,
56
                directory,
57
                course.id";
58
59
    if ($getCount) {
60
        $select = 'SELECT COUNT(DISTINCT(course.id)) as count ';
61
    }
62
63
    $sql = "$select FROM $course_table course
64
    		LEFT JOIN $tblCourseCategory category ON course.category_id = category.id ";
65
66
    if ((api_is_platform_admin() || api_is_session_admin()) &&
67
        api_is_multiple_url_enabled() && -1 != api_get_current_access_url_id()
68
    ) {
69
        $access_url_rel_course_table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
70
        $sql .= " INNER JOIN $access_url_rel_course_table url_rel_course
71
                 ON (course.id = url_rel_course.c_id)";
72
    }
73
74
    if (isset($_GET['keyword'])) {
75
        $keyword = Database::escape_string('%'.trim($_GET['keyword']).'%');
76
        $sql .= " WHERE (
77
            title LIKE '".$keyword."' OR
78
            course.code LIKE '".$keyword."' OR
79
            visual_code LIKE '".$keyword."'
80
        )
81
        ";
82
    } elseif (isset($_GET['keyword_code'])) {
83
        $keyword_code = Database::escape_string('%'.$_GET['keyword_code'].'%');
84
        $keyword_title = Database::escape_string('%'.$_GET['keyword_title'].'%');
85
        $keyword_category = isset($_GET['keyword_category'])
86
            ? Database::escape_string('%'.$_GET['keyword_category'].'%')
87
            : null;
88
        $keyword_language = Database::escape_string('%'.$_GET['keyword_language'].'%');
89
        $keyword_visibility = Database::escape_string('%'.$_GET['keyword_visibility'].'%');
90
        $keyword_subscribe = Database::escape_string($_GET['keyword_subscribe']);
91
        $keyword_unsubscribe = Database::escape_string($_GET['keyword_unsubscribe']);
92
93
        $sql .= " WHERE
94
                (course.code LIKE '".$keyword_code."' OR visual_code LIKE '".$keyword_code."') AND
95
                title LIKE '".$keyword_title."' AND
96
                course_language LIKE '".$keyword_language."' AND
97
                visibility LIKE '".$keyword_visibility."' AND
98
                subscribe LIKE '".$keyword_subscribe."' AND
99
                unsubscribe LIKE '".$keyword_unsubscribe."'";
100
101
        if (!empty($keyword_category)) {
102
            $sql .= " AND category.code LIKE '".$keyword_category."' ";
103
        }
104
    }
105
106
    // Adding the filter to see the user's only of the current access_url.
107
    if ((api_is_platform_admin() || api_is_session_admin()) &&
108
        api_is_multiple_url_enabled() && -1 != api_get_current_access_url_id()
109
    ) {
110
        $sql .= ' AND url_rel_course.access_url_id='.api_get_current_access_url_id();
111
    }
112
113
    if ($getCount) {
114
        $res = Database::query($sql);
115
        $row = Database::fetch_array($res);
116
        if ($row) {
117
            return (int) $row['count'];
118
        }
119
120
        return 0;
121
    }
122
123
    $sql .= " ORDER BY col$column $direction ";
124
    $sql .= " LIMIT $from, $number_of_items";
125
126
    $res = Database::query($sql);
127
    $courses = [];
128
    $languages = api_get_languages_to_array();
129
130
    $path = api_get_path(WEB_CODE_PATH);
131
132
    while ($course = Database::fetch_array($res)) {
133
        $courseInfo = api_get_course_info_by_id($course['id']);
134
135
        // Place colour icons in front of courses.
136
        $show_visual_code = $course['visual_code'] != $course[2] ? Display::label($course['visual_code'], 'info') : null;
137
        $course[1] = get_course_visibility_icon($course[8]).PHP_EOL
138
            .Display::url(Security::remove_XSS($course[1]), $courseInfo['course_public_url']).PHP_EOL
139
            .$show_visual_code;
140
        $course[5] = SUBSCRIBE_ALLOWED == $course[5] ? get_lang('Yes') : get_lang('No');
141
        $course[6] = UNSUBSCRIBE_ALLOWED == $course[6] ? get_lang('Yes') : get_lang('No');
142
        $language = isset($languages[$course[3]]) ? $languages[$course[3]] : $course[3];
143
144
        $courseCode = $course[0];
145
        $courseId = $course['id'];
146
147
        $actions = [];
148
        $actions[] = Display::url(
149
            Display::return_icon('info2.png', get_lang('Information')),
150
            "course_information.php?code=$courseCode"
151
        );
152
        $actions[] = Display::url(
153
            Display::return_icon('course_home.png', get_lang('Course home')),
154
            $courseInfo['course_public_url']
155
        );
156
        $actions[] = Display::url(
157
            Display::return_icon('statistics.png', get_lang('Reporting')),
158
            $path.'tracking/courseLog.php?'.api_get_cidreq_params($courseCode)
159
        );
160
        $actions[] = Display::url(
161
            Display::return_icon('edit.png', get_lang('Edit')),
162
            $path.'admin/course_edit.php?id='.$courseId
163
        );
164
        $actions[] = Display::url(
165
            Display::return_icon('backup.png', get_lang('Create a backup')),
166
            $path.'coursecopy/create_backup.php?'.api_get_cidreq_params($courseCode)
167
        );
168
        $actions[] = Display::url(
169
            Display::return_icon('delete.png', get_lang('Delete')),
170
            $path.'admin/course_list.php?delete_course='.$courseCode,
171
            [
172
                'onclick' => "javascript: if (!confirm('"
173
                    .addslashes(api_htmlentities(get_lang('Please confirm your choice'), ENT_QUOTES))."')) return false;",
174
            ]
175
        );
176
177
        $courseItem = [
178
            $course[0],
179
            $course[1],
180
            $course[2],
181
            $language,
182
            $course[4],
183
            $course[5],
184
            $course[6],
185
            implode(PHP_EOL, $actions),
186
        ];
187
        $courses[] = $courseItem;
188
    }
189
190
    return $courses;
191
}
192
193
/**
194
 * Get course data to display filtered by session name.
195
 *
196
 * @param int    $from
197
 * @param int    $number_of_items
198
 * @param int    $column
199
 * @param string $direction
200
 *
201
 * @throws Exception
202
 *
203
 * @return array
204
 */
205
function get_course_data_by_session($from, $number_of_items, $column, $direction)
206
{
207
    $course_table = Database::get_main_table(TABLE_MAIN_COURSE);
208
    $session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
209
    $session = Database::get_main_table(TABLE_MAIN_SESSION);
210
    $tblCourseCategory = Database::get_main_table(TABLE_MAIN_CATEGORY);
211
212
    $sql = "SELECT
213
                c.code AS col0,
214
                c.title AS col1,
215
                c.code AS col2,
216
                c.course_language AS col3,
217
                course_category.code AS col4,
218
                c.subscribe AS col5,
219
                c.unsubscribe AS col6,
220
                c.code AS col7,
221
                c.visibility AS col8,
222
                c.directory as col9,
223
                c.visual_code
224
            FROM $course_table c
225
            INNER JOIN $session_rel_course r
226
            ON c.id = r.c_id
227
            INNER JOIN $session s
228
            ON r.session_id = s.id
229
            LEFT JOIN $tblCourseCategory ON c.category_id = course_category.id
230
            ";
231
232
    if (isset($_GET['session_id']) && !empty($_GET['session_id'])) {
233
        $sessionId = (int) ($_GET['session_id']);
234
        $sql .= ' WHERE s.id = '.$sessionId;
235
    }
236
237
    $sql .= " ORDER BY col$column $direction ";
238
    $sql .= " LIMIT $from,$number_of_items";
239
    $res = Database::query($sql);
240
241
    $courseUrl = api_get_path(WEB_COURSE_PATH);
242
    $courses = [];
243
    while ($course = Database::fetch_array($res)) {
244
        // Place colour icons in front of courses.
245
        $showVisualCode = $course['visual_code'] != $course[2] ? Display::label($course['visual_code'], 'info') : null;
246
        $course[1] = get_course_visibility_icon($course[8]).
247
            '<a href="'.$courseUrl.$course[9].'/index.php">'.
248
            $course[1].
249
            '</a> '.
250
            $showVisualCode;
251
        $course[5] = SUBSCRIBE_ALLOWED == $course[5] ? get_lang('Yes') : get_lang('No');
252
        $course[6] = UNSUBSCRIBE_ALLOWED == $course[6] ? get_lang('Yes') : get_lang('No');
253
        $row = [
254
            $course[0],
255
            $course[1],
256
            $course[2],
257
            $course[3],
258
            $course[4],
259
            $course[5],
260
            $course[6],
261
            $course[7],
262
        ];
263
        $courses[] = $row;
264
    }
265
266
    return $courses;
267
}
268
269
/**
270
 * Return an icon representing the visibility of the course.
271
 *
272
 * @param string $visibility
273
 *
274
 * @return string
275
 */
276
function get_course_visibility_icon($visibility)
277
{
278
    $style = 'margin-bottom:0;margin-right:5px;';
279
    switch ($visibility) {
280
        case 0:
281
            return Display::return_icon(
282
                'bullet_red.png',
283
                get_lang('Closed - the course is only accessible to the teachers'),
284
                ['style' => $style]
285
            );
286
287
            break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
288
        case 1:
289
            return Display::return_icon(
290
                'bullet_orange.png',
291
                get_lang('Private access (access authorized to group members only) access (access authorized to group members only)'),
292
                ['style' => $style]
293
            );
294
295
            break;
296
        case 2:
297
            return Display::return_icon(
298
                'bullet_green.png',
299
                get_lang(' Open - access allowed for users registered on the platform'),
300
                ['style' => $style]
301
            );
302
303
            break;
304
        case 3:
305
            return Display::return_icon(
306
                'bullet_blue.png',
307
                get_lang('Public - access allowed for the whole world'),
308
                ['style' => $style]
309
            );
310
311
            break;
312
        case 4:
313
            return Display::return_icon(
314
                'bullet_grey.png',
315
                get_lang('Hidden - Completely hidden to all users except the administrators'),
316
                ['style' => $style]
317
            );
318
319
            break;
320
        default:
321
            return '';
322
    }
323
}
324
325
if (isset($_POST['action'])) {
326
    switch ($_POST['action']) {
327
        // Delete selected courses
328
        case 'delete_courses':
329
            if (!empty($_POST['course'])) {
330
                $course_codes = $_POST['course'];
331
                if (count($course_codes) > 0) {
332
                    foreach ($course_codes as $course_code) {
333
                        CourseManager::delete_course($course_code);
334
                    }
335
                }
336
337
                Display::addFlash(Display::return_message(get_lang('Deleted')));
338
            }
339
340
            break;
341
    }
342
}
343
$content = '';
344
$message = '';
345
$actions = '';
346
347
if (isset($_GET['search']) && 'advanced' === $_GET['search']) {
348
    // Get all course categories
349
    $interbreadcrumb[] = [
350
        'url' => 'index.php',
351
        'name' => get_lang('Administration'),
352
    ];
353
    $interbreadcrumb[] = [
354
        'url' => 'course_list.php',
355
        'name' => get_lang('Course list'),
356
    ];
357
    $tool_name = get_lang('Search for a course');
358
    $form = new FormValidator('advanced_course_search', 'get');
359
    $form->addElement('header', $tool_name);
360
    $form->addText('keyword_code', get_lang('Course code'), false);
361
    $form->addText('keyword_title', get_lang('Title'), false);
362
363
    // Category code
364
    $url = api_get_path(WEB_AJAX_PATH).'course.ajax.php?a=search_category';
365
366
    $form->addElement(
367
        'select_ajax',
368
        'keyword_category',
369
        get_lang('Category'),
370
        null,
371
        [
372
            'url' => $url,
373
        ]
374
    );
375
376
    $el = $form->addSelectLanguage('keyword_language', get_lang('Course language'));
377
    $el->addOption(get_lang('All'), '%');
378
    $form->addElement('radio', 'keyword_visibility', get_lang('Course access'), get_lang('Public - access allowed for the whole world'), COURSE_VISIBILITY_OPEN_WORLD);
379
    $form->addElement('radio', 'keyword_visibility', null, get_lang(' Open - access allowed for users registered on the platform'), COURSE_VISIBILITY_OPEN_PLATFORM);
380
    $form->addElement('radio', 'keyword_visibility', null, get_lang('Private access (access authorized to group members only) access (access authorized to group members only)'), COURSE_VISIBILITY_REGISTERED);
381
    $form->addElement('radio', 'keyword_visibility', null, get_lang('Closed - the course is only accessible to the teachers'), COURSE_VISIBILITY_CLOSED);
382
    $form->addElement('radio', 'keyword_visibility', null, get_lang('Hidden - Completely hidden to all users except the administrators'), COURSE_VISIBILITY_HIDDEN);
383
    $form->addElement('radio', 'keyword_visibility', null, get_lang('All'), '%');
384
    $form->addElement('radio', 'keyword_subscribe', get_lang('Subscription'), get_lang('Allowed'), 1);
385
    $form->addElement('radio', 'keyword_subscribe', null, get_lang('This function is only available to trainers'), 0);
386
    $form->addElement('radio', 'keyword_subscribe', null, get_lang('All'), '%');
387
    $form->addElement('radio', 'keyword_unsubscribe', get_lang('Unsubscribe'), get_lang('Users are allowed to unsubscribe from this course'), 1);
388
    $form->addElement('radio', 'keyword_unsubscribe', null, get_lang('NotUsers are allowed to unsubscribe from this course'), 0);
389
    $form->addElement('radio', 'keyword_unsubscribe', null, get_lang('All'), '%');
390
    $form->addButtonSearch(get_lang('Search courses'));
391
    $defaults['keyword_language'] = '%';
392
    $defaults['keyword_visibility'] = '%';
393
    $defaults['keyword_subscribe'] = '%';
394
    $defaults['keyword_unsubscribe'] = '%';
395
    $form->setDefaults($defaults);
396
    $content .= $form->returnForm();
397
} else {
398
    $interbreadcrumb[] = [
399
        'url' => 'index.php',
400
        'name' => get_lang('Administration'),
401
    ];
402
    $tool_name = get_lang('Course list');
403
    if (isset($_GET['delete_course'])) {
404
        $result = CourseManager::delete_course($_GET['delete_course']);
405
        if ($result) {
406
            Display::addFlash(Display::return_message(get_lang('Deleted')));
407
        }
408
    }
409
    // Create a search-box
410
    $form = new FormValidator(
411
        'search_simple',
412
        'get',
413
        '',
414
        '',
415
        [],
416
        FormValidator::LAYOUT_INLINE
417
    );
418
    $form->addElement(
419
        'text',
420
        'keyword',
421
        null,
422
        ['id' => 'course-search-keyword', 'aria-label' => get_lang('Search courses')]
423
    );
424
    $form->addButtonSearch(get_lang('Search courses'));
425
    $advanced = '<a class="btn btn-default" href="'.api_get_path(WEB_CODE_PATH).'admin/course_list.php?search=advanced">
426
        <em class="fa fa-search"></em> '.
427
        get_lang('Advanced search').'</a>';
428
429
    // Create a filter by session
430
    $sessionFilter = new FormValidator(
431
        'course_filter',
432
        'get',
433
        '',
434
        '',
435
        [],
436
        FormValidator::LAYOUT_INLINE
437
    );
438
    $url = api_get_path(WEB_AJAX_PATH).'session.ajax.php?a=search_session';
439
    $sessionSelect = $sessionFilter->addElement(
440
        'select_ajax',
441
        'session_name',
442
        get_lang('Search coursesBySession'),
443
        null,
444
        ['id' => 'session_name', 'url' => $url]
445
    );
446
447
    if (!empty($sessionId)) {
448
        $sessionInfo = SessionManager::fetch($sessionId);
449
        $sessionSelect->addOption(
450
            $sessionInfo['name'],
451
            $sessionInfo['id'],
452
            ['selected' => 'selected']
453
        );
454
    }
455
456
    $courseListUrl = api_get_self();
457
    $actions1 = Display::url(
458
        Display::return_icon(
459
            'new_course.png',
460
            get_lang('Create a course'),
461
            [],
462
            ICON_SIZE_MEDIUM
463
        ),
464
        api_get_path(WEB_CODE_PATH).'admin/course_add.php'
465
    );
466
467
    if ('true' === api_get_setting('course_validation')) {
468
        $actions1 .= Display::url(
469
            Display::return_icon(
470
                'course_request_pending.png',
471
                get_lang('Review incoming course requests'),
472
                [],
473
                ICON_SIZE_MEDIUM
474
            ),
475
            api_get_path(WEB_CODE_PATH).'admin/course_request_review.php'
476
        );
477
    }
478
479
    $actions2 = $form->returnForm();
480
    $actions3 = $sessionFilter->returnForm();
481
    $actions4 = $advanced;
482
    $actions4 .= '
483
    <script>
484
        $(function() {
485
            $("#session_name").on("change", function() {
486
                var sessionId = $(this).val();
487
                if (!sessionId) {
488
                    return;
489
                }
490
491
                window.location = "'.$courseListUrl.'?session_id="+sessionId;
492
            });
493
        });
494
    </script>';
495
496
    $actions = Display::toolbarAction(
497
        'toolbar',
498
        [$actions1, $actions2, $actions3, $actions4],
499
        [2, 4, 3, 3]
500
    );
501
502
    if (isset($_GET['session_id']) && !empty($_GET['session_id'])) {
503
        // Create a sortable table with the course data filtered by session
504
        $table = new SortableTable(
505
            'courses',
506
            'get_number_of_courses',
507
            'get_course_data_by_session',
508
            2
509
        );
510
    } else {
511
        // Create a sortable table with the course data
512
        $table = new SortableTable(
513
            'courses',
514
            'get_number_of_courses',
515
            'get_course_data',
516
            2,
517
            20,
518
            'ASC',
519
            'course-list'
520
        );
521
    }
522
523
    $parameters = [];
524
    if (isset($_GET['keyword'])) {
525
        $parameters = ['keyword' => Security::remove_XSS($_GET['keyword'])];
526
    } elseif (isset($_GET['keyword_code'])) {
527
        $parameters['keyword_code'] = Security::remove_XSS($_GET['keyword_code']);
528
        $parameters['keyword_title'] = Security::remove_XSS($_GET['keyword_title']);
529
        if (isset($_GET['keyword_category'])) {
530
            $parameters['keyword_category'] = Security::remove_XSS($_GET['keyword_category']);
531
        }
532
        $parameters['keyword_language'] = Security::remove_XSS($_GET['keyword_language']);
533
        $parameters['keyword_visibility'] = Security::remove_XSS($_GET['keyword_visibility']);
534
        $parameters['keyword_subscribe'] = Security::remove_XSS($_GET['keyword_subscribe']);
535
        $parameters['keyword_unsubscribe'] = Security::remove_XSS($_GET['keyword_unsubscribe']);
536
    }
537
538
    $table->set_additional_parameters($parameters);
539
540
    $table->set_header(0, '', false, 'width="8px"');
541
    $table->set_header(1, get_lang('Title'), true, null, ['class' => 'title']);
542
    $table->set_header(2, get_lang('Course code'));
543
    $table->set_header(3, get_lang('Language'), false, 'width="70px"');
544
    $table->set_header(4, get_lang('Category'));
545
    $table->set_header(5, get_lang('Registr. allowed'), true, 'width="60px"');
546
    $table->set_header(6, get_lang('UnsubscribeAllowed'), false, 'width="50px"');
547
    $table->set_header(
548
        7,
549
        get_lang('Action'),
550
        false,
551
        null,
552
        ['class' => 'td_actions']
553
    );
554
    $table->set_form_actions(
555
        ['delete_courses' => get_lang('Delete selected course(s)')],
556
        'course'
557
    );
558
559
    $tab = CourseManager::getCourseListTabs('simple');
560
561
    $content .= $tab.$table->return_table();
562
}
563
564
$tpl = new Template($tool_name);
565
$tpl->assign('actions', $actions);
566
$tpl->assign('message', $message);
567
$tpl->assign('content', $content);
568
$tpl->display_one_col_template();
569