Passed
Push — dependabot/npm_and_yarn/microm... ( e84ba6...f2f212 )
by
unknown
10:03
created

Diagnoser::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 0
nc 1
nop 0
dl 0
loc 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
use Chamilo\CoreBundle\Component\Utils\ActionIcon;
6
use Chamilo\CoreBundle\Component\Utils\ObjectIcon;
7
use Chamilo\CoreBundle\Component\Utils\StateIcon;
8
9
/**
10
 * Class Diagnoser
11
 * Class that is responsible for generating diagnostic information about the system.
12
 *
13
 * @author Ivan Tcholakov, 2008, initial proposal and sample code.
14
 * @author spou595, 2009, implementation for Chamilo 2.x
15
 * @author Julio Montoya <[email protected]>, 2010, port to chamilo 1.8.7, Some fixes
16
 */
17
class Diagnoser
18
{
19
    public const STATUS_OK = 1;
20
    public const STATUS_WARNING = 2;
21
    public const STATUS_ERROR = 3;
22
    public const STATUS_INFORMATION = 4;
23
24
    /**
25
     * Contructor.
26
     */
27
    public function __construct()
28
    {
29
    }
30
31
    /**
32
     * Show html table.
33
     */
34
    public function show_html()
35
    {
36
        $sections = [
37
            'chamilo' => [
38
                'lang' => 'Chamilo',
39
                'info' => 'State of Chamilo requirements',
40
            ],
41
            'php' => [
42
                'lang' => 'PHP',
43
                'info' => 'State of PHP settings on the server',
44
            ],
45
            'database' => [
46
                'lang' => 'Database',
47
                'info' => 'Configuration settings of the database server. To check the database consistency after an upgrade, if you have access to the command line, you can use "php bin/doctrine.php orm:schema-tool:update --dump-sql". This will print a list of database changes that should be applied to your system in order to get the right structure. Index name changes can be ignored. Use "--force" instead of "--dump" to try and execute them in order.',
48
            ],
49
            'webserver' => [
50
                'lang' => get_lang('Web server'),
51
                'info' => 'Information about your webserver\'s configuration ',
52
            ],
53
            'paths' => [
54
                'lang' => 'Paths',
55
                'info' => 'The following paths are called by their constant throughout Chamilo\'s code using the api_get_path() function. Here is a list of these paths and what they would be translated to on this portal.',
56
            ],
57
            'courses_space' => [
58
                'lang' => 'Courses space',
59
                'info' => 'Information about space used by courses on disk. The space used on disk represents the total space used, whereas the quota only limits files in the documents tool. Only 1000 courses are shown, by order of last access and alphabetical code order. For more, please go to the courses folder and use "du -sh *" to get the size of the courses.',
60
            ],
61
        ];
62
        $currentSection = isset($_GET['section']) ? $_GET['section'] : '';
63
        if (!in_array(trim($currentSection), array_keys($sections))) {
64
            $currentSection = 'chamilo';
65
        }
66
67
        $html = '<div class="tabbable"><ul class="nav nav-tabs">';
68
69
        foreach ($sections as $section => $details) {
70
            if ($currentSection === $section) {
71
                $html .= '<li class="active">';
72
            } else {
73
                $html .= '<li>';
74
            }
75
            $params['section'] = $section;
76
            $html .= '<a href="system_status.php?section='.$section.'">'.$details['lang'].'</a></li>';
77
        }
78
79
        $html .= '</ul><div class="tab-pane">';
80
81
        $data = call_user_func([$this, 'get_'.$currentSection.'_data']);
82
        echo $html;
83
84
        if ('paths' === $currentSection) {
85
            echo '<br />';
86
            echo Display::return_message($sections[$currentSection]['info'], 'normal');
87
88
            $headers = $data['headers'];
89
            $results = $data['data'];
90
            $table = new HTML_Table(['class' => 'table table-hover table-striped data_table']);
91
92
            $column = 0;
93
            foreach ($headers as $header) {
94
                $table->setHeaderContents(0, $column, $header);
95
                $column++;
96
            }
97
            $row = 1;
98
            foreach ($results as $index => $rowData) {
99
                $table->setCellContents(
100
                    $row,
101
                    0,
102
                    $rowData
103
                );
104
                $table->setCellContents(
105
                    $row,
106
                    1,
107
                    $index
108
                );
109
                $row++;
110
            }
111
            $table->display();
112
        } elseif ('courses_space' == $currentSection) {
113
            echo '<br />';
114
            echo Display::return_message($sections[$currentSection]['info'], 'normal');
115
116
            $table = new SortableTableFromArray($data, 1, 1000);
117
            $table->set_additional_parameters(['section' => 'courses_space']);
118
            $table->set_header(0, '', false);
119
            $table->set_header(1, get_lang('Course code'), true);
120
            $table->set_header(2, 'Space used on disk (MB)', true);
121
            $table->set_header(3, 'Set max course space (MB)', false);
122
            $table->set_header(4, get_lang('Edit'), false);
123
            $table->set_header(5, get_lang('Latest visit'), true);
124
            $table->set_header(6, get_lang('Current folder'), false);
125
126
            $table->display();
127
        } else {
128
            echo '<br />';
129
            echo Display::return_message($sections[$currentSection]['info'], 'normal');
130
131
            $table = new SortableTableFromArray($data, 1, 100);
132
            $table->set_header(0, '', false);
133
            $table->set_header(1, get_lang('Section'), false);
134
            $table->set_header(2, get_lang('Setting'), false);
135
            $table->set_header(3, get_lang('Current'), false);
136
            $table->set_header(4, get_lang('Expected'), false);
137
            $table->set_header(5, get_lang('Comment'), false);
138
139
            $table->display();
140
        }
141
        echo '</div></div>';
142
    }
143
144
    /**
145
     * @return array
146
     */
147
    public function get_paths_data()
148
    {
149
        global $paths;
150
        $list = $paths[api_get_path(WEB_PATH)];
151
        //$list['url_append'] = api_get_configuration_value('url_append');
152
        asort($list);
153
154
        return [
155
            'headers' => ['Path', 'constant'],
156
            'data' => $list,
157
        ];
158
    }
159
160
    /**
161
     * Functions to get the data for the chamilo diagnostics.
162
     *
163
     * @return array of data
164
     */
165
    public function get_chamilo_data()
166
    {
167
        $array = [];
168
        $writable_folders = [
169
            api_get_path(SYS_ARCHIVE_PATH).'cache',
170
            api_get_path(SYS_PATH).'upload/users/',
171
        ];
172
        foreach ($writable_folders as $index => $folder) {
173
            $writable = is_writable($folder);
174
            $status = $writable ? self::STATUS_OK : self::STATUS_ERROR;
175
            $array[] = $this->build_setting(
176
                $status,
177
                '[FILES]',
178
                get_lang('Is writable').': '.$folder,
179
                'http://be2.php.net/manual/en/function.is-writable.php',
180
                $writable,
181
                1,
182
                'yes_no',
183
                get_lang('The directory must be writable by the web server')
184
            );
185
        }
186
187
        $exists = file_exists(api_get_path(SYS_CODE_PATH).'install');
188
        $status = $exists ? self::STATUS_WARNING : self::STATUS_OK;
189
        $array[] = $this->build_setting(
190
            $status,
191
            '[FILES]',
192
            get_lang('The directory exists').': /install',
193
            'http://be2.php.net/file_exists',
194
            $exists,
195
            0,
196
            'yes_no',
197
            get_lang('The directory should be removed (it is no longer necessary)')
198
        );
199
200
        $app_version = api_get_setting('platform.chamilo_database_version');
201
        $array[] = $this->build_setting(
202
            self::STATUS_INFORMATION,
203
            '[DB]',
204
            'chamilo_database_version',
205
            '#',
206
            $app_version,
207
            0,
208
            null,
209
            'Chamilo DB version'
210
        );
211
212
        $access_url_id = api_get_current_access_url_id();
213
214
        if (1 === $access_url_id) {
215
            $size = '-';
216
            $message2 = '';
217
218
            if (api_is_windows_os()) {
219
                $message2 .= get_lang('The space used on disk cannot be measured properly on Windows-based systems.');
220
            } else {
221
                $dir = api_get_path(SYS_PATH);
222
                $du = exec('du -sh ' . $dir, $err);
223
                list($size, $none) = explode("\t", $du);
224
                unset($none);
225
226
                $limit = get_hosting_limit($access_url_id, 'hosting_limit_disk_space');
227
                if ($limit === null) {
228
                    $limit = 0;
229
                }
230
231
                $message2 .= sprintf(get_lang('Total space used by portal %s limit is %s MB'), $size, $limit);
232
            }
233
234
            $array[] = $this->build_setting(
235
                self::STATUS_OK,
236
                '[FILES]',
237
                'hosting_limit_disk_space',
238
                '#',
239
                $size,
240
                0,
241
                null,
242
                $message2
243
            );
244
        }
245
        $new_version = '-';
246
        $new_version_status = '';
247
        $file = api_get_path(SYS_CODE_PATH).'install/version.php';
248
        if (is_file($file)) {
249
            @include $file;
250
        }
251
        $array[] = $this->build_setting(
252
            self::STATUS_INFORMATION,
253
            '[CONFIG]',
254
            get_lang('Version from the version file'),
255
            '#',
256
            $new_version.' '.$new_version_status,
257
            '-',
258
            null,
259
            get_lang('The version from the version.php file is updated with each version but only available if the main/install/ directory is present.')
260
        );
261
        $array[] = $this->build_setting(
262
            self::STATUS_INFORMATION,
263
            '[CONFIG]',
264
            get_lang('Version from the config file'),
265
            '#',
266
            api_get_configuration_value('system_version'),
267
            $new_version,
268
            null,
269
            get_lang('The version from the main configuration file shows on the main administration page, but has to be changed manually on upgrade.')
270
        );
271
272
        return $array;
273
    }
274
275
    /**
276
     * Functions to get the data for the php diagnostics.
277
     *
278
     * @return array of data
279
     */
280
    public function get_php_data()
281
    {
282
        $array = [];
283
284
        // General Functions
285
286
        $version = phpversion();
287
        $status = $version > REQUIRED_PHP_VERSION ? self::STATUS_OK : self::STATUS_ERROR;
288
        $array[] = $this->build_setting(
289
            $status,
290
            '[PHP]',
291
            'phpversion()',
292
            'https://php.net/manual/en/function.phpversion.php',
293
            phpversion(),
294
            '>= '.REQUIRED_PHP_VERSION,
295
            null,
296
            get_lang('PHP version')
297
        );
298
299
        $setting = ini_get('output_buffering');
300
        $req_setting = 1;
301
        $status = $setting >= $req_setting ? self::STATUS_OK : self::STATUS_ERROR;
302
        $array[] = $this->build_setting(
303
            $status,
304
            '[INI]',
305
            'output_buffering',
306
            'https://php.net/manual/en/outcontrol.configuration.php#ini.output-buffering',
307
            $setting,
308
            $req_setting,
309
            'on_off',
310
            get_lang('Output buffering setting is "On" for being enabled or "Off" for being disabled. This setting also may be enabled through an integer value (4096 for example) which is the output buffer size.')
311
        );
312
313
        $setting = ini_get('file_uploads');
314
        $req_setting = 1;
315
        $status = $setting == $req_setting ? self::STATUS_OK : self::STATUS_ERROR;
316
        $array[] = $this->build_setting(
317
            $status,
318
            '[INI]',
319
            'file_uploads',
320
            'https://php.net/manual/en/ini.core.php#ini.file-uploads',
321
            $setting,
322
            $req_setting,
323
            'on_off',
324
            get_lang('File uploads indicate whether file uploads are authorized at all')
325
        );
326
327
        $setting = ini_get('magic_quotes_runtime');
328
        $req_setting = 0;
329
        $status = $setting == $req_setting ? self::STATUS_OK : self::STATUS_ERROR;
330
        $array[] = $this->build_setting(
331
            $status,
332
            '[INI]',
333
            'magic_quotes_runtime',
334
            'https://php.net/manual/en/ini.core.php#ini.magic-quotes-runtime',
335
            $setting,
336
            $req_setting,
337
            'on_off',
338
            get_lang('This is a highly unrecommended feature which converts values returned by all functions that returned external values to slash-escaped values. This feature should *not* be enabled.')
339
        );
340
341
        $setting = ini_get('safe_mode');
342
        $req_setting = 0;
343
        $status = $setting == $req_setting ? self::STATUS_OK : self::STATUS_WARNING;
344
        $array[] = $this->build_setting(
345
            $status,
346
            '[INI]',
347
            'safe_mode',
348
            'https://php.net/manual/en/ini.core.php#ini.safe-mode',
349
            $setting,
350
            $req_setting,
351
            'on_off',
352
            get_lang('Safe mode is a deprecated PHP feature which (badly) limits the access of PHP scripts to other resources. It is recommended to leave it off.')
353
        );
354
355
        $setting = ini_get('register_globals');
356
        $req_setting = 0;
357
        $status = $setting == $req_setting ? self::STATUS_OK : self::STATUS_ERROR;
358
        $array[] = $this->build_setting(
359
            $status,
360
            '[INI]',
361
            'register_globals',
362
            'https://php.net/manual/en/ini.core.php#ini.register-globals',
363
            $setting,
364
            $req_setting,
365
            'on_off',
366
            get_lang('Whether to use the register globals feature or not. Using it represents potential security risks with this software.')
367
        );
368
369
        $setting = ini_get('short_open_tag');
370
        $req_setting = 0;
371
        $status = $setting == $req_setting ? self::STATUS_OK : self::STATUS_WARNING;
372
        $array[] = $this->build_setting(
373
            $status,
374
            '[INI]',
375
            'short_open_tag',
376
            'https://php.net/manual/en/ini.core.php#ini.short-open-tag',
377
            $setting,
378
            $req_setting,
379
            'on_off',
380
            get_lang('Whether to allow for short open tags to be used or not. This feature should not be used.')
381
        );
382
383
        $setting = ini_get('magic_quotes_gpc');
384
        $req_setting = 0;
385
        $status = $setting == $req_setting ? self::STATUS_OK : self::STATUS_ERROR;
386
        $array[] = $this->build_setting(
387
            $status,
388
            '[INI]',
389
            'magic_quotes_gpc',
390
            'https://php.net/manual/en/ini.core.php#ini.magic_quotes_gpc',
391
            $setting,
392
            $req_setting,
393
            'on_off',
394
            get_lang('Whether to automatically escape values from GET, POST and COOKIES arrays. A similar feature is provided for the required data inside this software, so using it provokes double slash-escaping of values.')
395
        );
396
397
        $setting = ini_get('display_errors');
398
        $req_setting = 0;
399
        $status = $setting == $req_setting ? self::STATUS_OK : self::STATUS_WARNING;
400
        $array[] = $this->build_setting(
401
            $status,
402
            '[INI]',
403
            'display_errors',
404
            'https://php.net/manual/en/ini.core.php#ini.display_errors',
405
            $setting,
406
            $req_setting,
407
            'on_off',
408
            get_lang('Show errors on screen. Turn this on on development servers, off on production servers.')
409
        );
410
411
        $setting = ini_get('default_charset');
412
        if ('' == $setting) {
413
            $setting = null;
414
        }
415
        $req_setting = 'UTF-8';
416
        $status = $setting == $req_setting ? self::STATUS_OK : self::STATUS_ERROR;
417
        $array[] = $this->build_setting(
418
            $status,
419
            '[INI]',
420
            'default_charset',
421
            'https://php.net/manual/en/ini.core.php#ini.default-charset',
422
            $setting,
423
            $req_setting,
424
            null,
425
            get_lang('The default character set to be sent when returning pages')
426
        );
427
428
        $setting = ini_get('max_execution_time');
429
        $req_setting = '300 ('.get_lang('minimum').')';
430
        $status = $setting >= 300 ? self::STATUS_OK : self::STATUS_WARNING;
431
        $array[] = $this->build_setting(
432
            $status,
433
            '[INI]',
434
            'max_execution_time',
435
            'https://php.net/manual/en/ini.core.php#ini.max-execution-time',
436
            $setting,
437
            $req_setting,
438
            null,
439
            get_lang('Maximum time a script can take to execute. If using more than that, the script is abandoned to avoid slowing down other users.')
440
        );
441
442
        $setting = ini_get('max_input_time');
443
        $req_setting = '300 ('.get_lang('minimum').')';
444
        $status = $setting >= 300 ? self::STATUS_OK : self::STATUS_WARNING;
445
        $array[] = $this->build_setting(
446
            $status,
447
            '[INI]',
448
            'max_input_time',
449
            'https://php.net/manual/en/ini.core.php#ini.max-input-time',
450
            $setting,
451
            $req_setting,
452
            null,
453
            get_lang('The maximum time allowed for a form to be processed by the server. If it takes longer, the process is abandonned and a blank page is returned.')
454
        );
455
456
        $setting = ini_get('memory_limit');
457
        $req_setting = '>= '.REQUIRED_MIN_MEMORY_LIMIT.'M';
458
        $status = self::STATUS_ERROR;
459
        if ((float) $setting >= REQUIRED_MIN_MEMORY_LIMIT) {
460
            $status = self::STATUS_OK;
461
        }
462
        $array[] = $this->build_setting(
463
            $status,
464
            '[INI]',
465
            'memory_limit',
466
            'https://php.net/manual/en/ini.core.php#ini.memory-limit',
467
            $setting,
468
            $req_setting,
469
            null,
470
            get_lang('Maximum memory limit for one single script run. If the memory needed is higher, the process will stop to avoid consuming all the server\'s available memory and thus slowing down other users.')
471
        );
472
473
        $setting = ini_get('post_max_size');
474
        $req_setting = '>= '.REQUIRED_MIN_POST_MAX_SIZE.'M';
475
        $status = self::STATUS_ERROR;
476
        if ((float) $setting >= REQUIRED_MIN_POST_MAX_SIZE) {
477
            $status = self::STATUS_OK;
478
        }
479
        $array[] = $this->build_setting(
480
            $status,
481
            '[INI]',
482
            'post_max_size',
483
            'https://php.net/manual/en/ini.core.php#ini.post-max-size',
484
            $setting,
485
            $req_setting,
486
            null,
487
            get_lang('This is the maximum size of uploads through forms using the POST method (i.e. classical file upload forms)')
488
        );
489
490
        $setting = ini_get('upload_max_filesize');
491
        $req_setting = '>= '.REQUIRED_MIN_UPLOAD_MAX_FILESIZE.'M';
492
        $status = self::STATUS_ERROR;
493
        if ((float) $setting >= REQUIRED_MIN_UPLOAD_MAX_FILESIZE) {
494
            $status = self::STATUS_OK;
495
        }
496
        $array[] = $this->build_setting(
497
            $status,
498
            '[INI]',
499
            'upload_max_filesize',
500
            'https://php.net/manual/en/ini.core.php#ini.upload_max_filesize',
501
            $setting,
502
            $req_setting,
503
            null,
504
            get_lang('Maximum volume of an uploaded file. This setting should, most of the time, be matched with the post_max_size variable.')
505
        );
506
507
        $setting = ini_get('upload_tmp_dir');
508
        $status = self::STATUS_OK;
509
        $array[] = $this->build_setting(
510
            $status,
511
            '[INI]',
512
            'upload_tmp_dir',
513
            'https://php.net/manual/en/ini.core.php#ini.upload_tmp_dir',
514
            $setting,
515
            '',
516
            null,
517
            get_lang('The temporary upload directory is a space on the server where files are uploaded before being filtered and treated by PHP.')
518
        );
519
520
        $setting = ini_get('variables_order');
521
        $req_setting = 'GPCS';
522
        $status = $setting == $req_setting ? self::STATUS_OK : self::STATUS_ERROR;
523
        $array[] = $this->build_setting(
524
            $status,
525
            '[INI]',
526
            'variables_order',
527
            'https://php.net/manual/en/ini.core.php#ini.variables-order',
528
            $setting,
529
            $req_setting,
530
            null,
531
            get_lang('The order of precedence of Environment, GET, POST, COOKIES and SESSION variables')
532
        );
533
534
        $setting = ini_get('session.gc_maxlifetime');
535
        $req_setting = '4320';
536
        $status = $setting == $req_setting ? self::STATUS_OK : self::STATUS_WARNING;
537
        $array[] = $this->build_setting(
538
            $status,
539
            '[SESSION]',
540
            'session.gc_maxlifetime',
541
            'https://php.net/manual/en/ini.core.php#session.gc-maxlifetime',
542
            $setting,
543
            $req_setting,
544
            null,
545
            get_lang('The session garbage collector maximum lifetime indicates which maximum time is given between two runs of the garbage collector.')
546
        );
547
548
        if (api_check_browscap()) {
549
            $setting = true;
550
        } else {
551
            $setting = false;
552
        }
553
        $req_setting = true;
554
        $status = $setting == $req_setting ? self::STATUS_OK : self::STATUS_WARNING;
555
        $array[] = $this->build_setting(
556
            $status,
557
            '[INI]',
558
            'browscap',
559
            'https://php.net/manual/en/misc.configuration.php#ini.browscap',
560
            $setting,
561
            $req_setting,
562
            'on_off',
563
            get_lang('Browscap loading browscap.ini file that contains a large amount of data on the browser and its capabilities, so it can be used by the function get_browser () PHP')
564
        );
565
566
        // Extensions
567
        $extensions = [
568
            'gd' => [
569
                'link' => 'https://php.net/gd',
570
                'expected' => 1,
571
                'comment' => get_lang('This extension must be loaded.'),
572
            ],
573
            'pdo_mysql' => [
574
                'link' => 'https://php.net/manual/en/ref.pdo-mysql.php',
575
                'expected' => 1,
576
                'comment' => get_lang('This extension must be loaded.'),
577
            ],
578
            'pcre' => [
579
                'link' => 'https://php.net/pcre',
580
                'expected' => 1,
581
                'comment' => get_lang('This extension must be loaded.'),
582
            ],
583
            'session' => [
584
                'link' => 'https://php.net/session',
585
                'expected' => 1,
586
                'comment' => get_lang('This extension must be loaded.'),
587
            ],
588
            'standard' => [
589
                'link' => 'https://php.net/spl',
590
                'expected' => 1,
591
                'comment' => get_lang('This extension must be loaded.'),
592
            ],
593
            'zlib' => [
594
                'link' => 'https://php.net/zlib',
595
                'expected' => 1,
596
                'comment' => get_lang('ExtensionMustBeLoaded'),
597
            ],
598
            'curl' => [
599
                'link' => 'https://php.net/curl',
600
                'expected' => 1,
601
                'comment' => get_lang('ExtensionMustBeLoaded'),
602
            ],
603
            'fileinfo' => [
604
                'link' => 'https://php.net/fileinfo',
605
                'expected' => 1,
606
                'comment' => get_lang('ExtensionMustBeLoaded'),
607
            ],
608
            'xsl' => [
609
                'link' => 'https://php.net/xsl',
610
                'expected' => 2,
611
                'comment' => get_lang('ExtensionShouldBeLoaded'),
612
            ],
613
            'Zend OPcache' => [
614
                'link' => 'https://php.net/opcache',
615
                'expected' => 2,
616
                'comment' => get_lang('This extension should be loaded.'),
617
            ],
618
            'apcu' => [
619
                'link' => 'https://php.net/apcu',
620
                'expected' => 2,
621
                'comment' => get_lang('This extension should be loaded.'),
622
            ],
623
            'exif' => [
624
                'link' => 'https://www.php.net/exif',
625
                'expected' => 1,
626
                'comment' => get_lang('This extension should be loaded.'),
627
            ],
628
            'mbstring' => [
629
                'link' => 'https://www.php.net/mbstring',
630
                'expected' => 1,
631
                'comment' => get_lang('This extension should be loaded.'),
632
            ],
633
            'openssl' => [ //required only for DKIM e-mail signatures
634
                'link' => 'https://php.net/openssl',
635
                'expected' => 2,
636
                'comment' => get_lang('ExtensionShouldBeLoaded'),
637
            ],
638
            'bcmath' => [
639
                'link' => 'https://php.net/bcmath',
640
                'expected' => 2,
641
                'comment' => get_lang('ExtensionShouldBeLoaded'),
642
            ],
643
        ];
644
645
        foreach ($extensions as $extension => $data) {
646
            $url = $data['link'];
647
            $expected_value = $data['expected'];
648
            $comment = $data['comment'];
649
650
            $loaded = extension_loaded($extension);
651
            $status = $loaded ? self::STATUS_OK : self::STATUS_ERROR;
652
            $array[] = $this->build_setting(
653
                $status,
654
                '[EXTENSION]',
655
                get_lang('Extension loaded').': '.$extension,
656
                $url,
657
                $loaded,
658
                $expected_value,
659
                'yes_no_optional',
660
                $comment
661
            );
662
        }
663
664
        return $array;
665
    }
666
667
    /**
668
     * Functions to get the data for the mysql diagnostics.
669
     *
670
     * @return array of data
671
     */
672
    public function get_database_data()
673
    {
674
        $array = [];
675
        $em = Database::getManager();
676
        $connection = $em->getConnection();
677
        $host = $connection->getHost();
678
        $db = $connection->getDatabase();
679
        $port = $connection->getPort();
680
        $driver = $connection->getDriver()->getName();
681
682
        $array[] = $this->build_setting(
683
            self::STATUS_INFORMATION,
684
            '[Database]',
685
            'driver',
686
            '',
687
            $driver,
688
            null,
689
            null,
690
            get_lang('Driver')
691
        );
692
693
        $array[] = $this->build_setting(
694
            self::STATUS_INFORMATION,
695
            '[Database]',
696
            'host',
697
            '',
698
            $host,
699
            null,
700
            null,
701
            get_lang('MySQL server host')
702
        );
703
704
        $array[] = $this->build_setting(
705
            self::STATUS_INFORMATION,
706
            '[Database]',
707
            'port',
708
            '',
709
            $port,
710
            null,
711
            null,
712
            get_lang('Port')
713
        );
714
715
        $array[] = $this->build_setting(
716
            self::STATUS_INFORMATION,
717
            '[Database]',
718
            'Database name',
719
            '',
720
            $db,
721
            null,
722
            null,
723
            get_lang('Name')
724
        );
725
726
        return $array;
727
    }
728
729
    /**
730
     * Functions to get the data for the webserver diagnostics.
731
     *
732
     * @return array of data
733
     */
734
    public function get_webserver_data()
735
    {
736
        $array = [];
737
738
        $array[] = $this->build_setting(
739
            self::STATUS_INFORMATION,
740
            '[SERVER]',
741
            '$_SERVER["SERVER_NAME"]',
742
            'http://be.php.net/reserved.variables.server',
743
            $_SERVER["SERVER_NAME"],
744
            null,
745
            null,
746
            get_lang('Server name (as used in your request)')
747
        );
748
        $array[] = $this->build_setting(
749
            self::STATUS_INFORMATION,
750
            '[SERVER]',
751
            '$_SERVER["SERVER_ADDR"]',
752
            'http://be.php.net/reserved.variables.server',
753
            $_SERVER["SERVER_ADDR"],
754
            null,
755
            null,
756
            get_lang('Server address')
757
        );
758
        $array[] = $this->build_setting(
759
            self::STATUS_INFORMATION,
760
            '[SERVER]',
761
            '$_SERVER["SERVER_PORT"]',
762
            'http://be.php.net/reserved.variables.server',
763
            $_SERVER["SERVER_PORT"],
764
            null,
765
            null,
766
            get_lang('Server port')
767
        );
768
        $array[] = $this->build_setting(
769
            self::STATUS_INFORMATION,
770
            '[SERVER]',
771
            '$_SERVER["SERVER_SOFTWARE"]',
772
            'http://be.php.net/reserved.variables.server',
773
            $_SERVER["SERVER_SOFTWARE"],
774
            null,
775
            null,
776
            get_lang('Software running as a web server')
777
        );
778
        $array[] = $this->build_setting(
779
            self::STATUS_INFORMATION,
780
            '[SERVER]',
781
            '$_SERVER["REMOTE_ADDR"]',
782
            'http://be.php.net/reserved.variables.server',
783
            $_SERVER["REMOTE_ADDR"],
784
            null,
785
            null,
786
            get_lang('Remote address (your address as received by the server)')
787
        );
788
        $array[] = $this->build_setting(
789
            self::STATUS_INFORMATION,
790
            '[SERVER]',
791
            '$_SERVER["HTTP_USER_AGENT"]',
792
            'http://be.php.net/reserved.variables.server',
793
            $_SERVER["HTTP_USER_AGENT"],
794
            null,
795
            null,
796
            get_lang('Your user agent as received by the server')
797
        );
798
        $array[] = $this->build_setting(
799
            self::STATUS_INFORMATION,
800
            '[SERVER]',
801
            '$_SERVER["SERVER_PROTOCOL"]',
802
            'http://be.php.net/reserved.variables.server',
803
            $_SERVER["SERVER_PROTOCOL"],
804
            null,
805
            null,
806
            get_lang('Protocol used by this server')
807
        );
808
        $array[] = $this->build_setting(
809
            self::STATUS_INFORMATION,
810
            '[SERVER]',
811
            'php_uname()',
812
            'http://be2.php.net/php_uname',
813
            php_uname(),
814
            null,
815
            null,
816
            get_lang('Information on the system the current server is running on')
817
        );
818
        $array[] = $this->build_setting(
819
            self::STATUS_INFORMATION,
820
            '[SERVER]',
821
            '$_SERVER["HTTP_X_FORWARDED_FOR"]',
822
            'http://be.php.net/reserved.variables.server',
823
            (!empty($_SERVER["HTTP_X_FORWARDED_FOR"]) ? $_SERVER["HTTP_X_FORWARDED_FOR"] : ''),
824
            null,
825
            null,
826
            get_lang('If the server is behind a proxy or firewall (and only in those cases), it might be using the X_FORWARDED_FOR HTTP header to show the remote user IP (yours, in this case).')
827
        );
828
829
        return $array;
830
    }
831
832
    /**
833
     * Functions to get the data for the courses space usage.
834
     *
835
     * @throws Exception
836
     *
837
     * @return array of data
838
     */
839
    public function get_courses_space_data()
840
    {
841
        $array = [];
842
843
        $em = Database::getManager();
844
        $connection = $em->getConnection();
845
        $res = $connection->query('SELECT id, code, directory, disk_quota, last_visit FROM course ORDER BY last_visit DESC, code LIMIT 500');
846
        $systemPath = api_get_path(SYS_COURSE_PATH);
0 ignored issues
show
Bug introduced by
The constant SYS_COURSE_PATH was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
847
        $webPath = api_get_path(WEB_COURSE_PATH);
848
        $courseHomeIcon = Display::getMdiIcon(ObjectIcon::HOME, 'ch-tool-icon', null, ICON_SIZE_SMALL, get_lang('CourseHome'));
849
        $courseEditIcon = Display::getMdiIcon(ActionIcon::EDIT, 'ch-tool-icon', null, ICON_SIZE_SMALL, get_lang('Edit'));
850
        $windows = api_is_windows_os();
851
        $courseEditPath = api_get_path(WEB_CODE_PATH).'admin/course_edit.php?id=';
852
        while ($row = $res->fetch()) {
853
            $quota = $row['disk_quota'] / (1024 * 1024);
854
            $dir = $systemPath.$row['directory'].'/';
855
            $path = '<a href="'.$webPath.$row['code'].'/index.php?id_session=0">'.$courseHomeIcon.'</a>';
856
            $size = '-';
857
            $courseEditLink = '<a href="'.$courseEditPath.$row['id'].'">'.$courseEditIcon.'</a>';
858
859
            if (!$windows) {
860
                $err = [];
861
                $du = exec('du -s '.$dir, $err);
862
                list($size, $none) = explode("\t", $du);
863
                unset($none);
864
                $size = intval($size);
865
                if ($size < 1024) {
866
                    $size = 1;
867
                } else {
868
                    $size = round($size / 1024);
869
                }
870
            }
871
            $array[] = [
872
                $path,
873
                $row['code'],
874
                $size,
875
                round($quota),
876
                $courseEditLink,
877
                $row['last_visit'],
878
                $dir,
879
            ];
880
        }
881
882
        return $array;
883
    }
884
885
    /**
886
     * Functions to get the number of courses in the database.
887
     *
888
     * @throws Exception
889
     *
890
     * @return array of data
891
     */
892
    public function get_courses_space_count()
893
    {
894
        $em = Database::getManager();
895
        $connection = $em->getConnection();
896
        $res = $connection->query('SELECT count(id) FROM course');
897
        while ($row = $res->fetch()) {
898
            $count = $row[0];
899
        }
900
901
        return $count;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $count does not seem to be defined for all execution paths leading up to this point.
Loading history...
902
    }
903
904
    /**
905
     * Additional functions needed for fast integration.
906
     *
907
     * @param int    $status         Status constant defining which icon to use to illustrate the info
908
     * @param string $section        The name of the section this setting is included in
909
     * @param string $title          The name of the setting (usually a translated string)
910
     * @param string $url            A URL to point the user to regarding this setting, or '#' otherwise
911
     * @param mixed  $current_value  The current value for this setting
912
     * @param mixed  $expected_value The expected value for this setting
913
     * @param string $formatter      If this setting is expressed in some kind of format, which format to use
914
     * @param string $comment        A translated string explaining what this setting represents
915
     *
916
     * @return array A list of elements to show in an array's row
917
     */
918
    public function build_setting(
919
        $status,
920
        $section,
921
        $title,
922
        $url,
923
        $current_value,
924
        $expected_value,
925
        $formatter,
926
        $comment
927
    ) {
928
        switch ($status) {
929
            case self::STATUS_OK:
930
                $img = StateIcon::COMPLETE;
931
                break;
932
            case self::STATUS_WARNING:
933
                $img = StateIcon::WARNING;
934
                break;
935
            case self::STATUS_ERROR:
936
                $img = StateIcon::ERROR;
937
                break;
938
            case self::STATUS_INFORMATION:
939
            default:
940
                $img = ActionIcon::INFORMATION;
941
                break;
942
        }
943
944
        $image = Display::getMdiIcon($img, 'ch-tool-icon', null, ICON_SIZE_SMALL, $title);
945
        $url = $this->get_link($title, $url);
946
947
        $formatted_current_value = $current_value;
948
        $formatted_expected_value = $expected_value;
949
950
        if ($formatter) {
951
            if (method_exists($this, 'format_'.$formatter)) {
952
                $formatted_current_value = call_user_func([$this, 'format_'.$formatter], $current_value);
953
                $formatted_expected_value = call_user_func([$this, 'format_'.$formatter], $expected_value);
954
            }
955
        }
956
957
        return [$image, $section, $url, $formatted_current_value, $formatted_expected_value, $comment];
958
    }
959
960
    /**
961
     * Create a link with a url and a title.
962
     *
963
     * @param $title
964
     * @param $url
965
     *
966
     * @return string the url
967
     */
968
    public function get_link($title, $url)
969
    {
970
        return '<a href="'.$url.'" target="about:bank">'.$title.'</a>';
971
    }
972
973
    /**
974
     * @param int $value
975
     *
976
     * @return string
977
     */
978
    public function format_yes_no_optional($value)
979
    {
980
        $return = '';
981
        switch ($value) {
982
            case 0:
983
                $return = get_lang('No');
984
                break;
985
            case 1:
986
                $return = get_lang('Yes');
987
                break;
988
            case 2:
989
                $return = get_lang('Optional');
990
                break;
991
        }
992
993
        return $return;
994
    }
995
996
    /**
997
     * @param $value
998
     *
999
     * @return string
1000
     */
1001
    public function format_yes_no($value)
1002
    {
1003
        return $value ? get_lang('Yes') : get_lang('No');
1004
    }
1005
1006
    /**
1007
     * @param int $value
1008
     *
1009
     * @return string
1010
     */
1011
    public function format_on_off($value)
1012
    {
1013
        $value = intval($value);
1014
        if ($value > 1) {
1015
            // Greater than 1 values are shown "as-is", they may be interpreted as "On" later.
1016
            return $value;
1017
        }
1018
        // These are the values 'On' and 'Off' used in the php-ini file. Translation (get_lang()) is not needed here.
1019
        return $value ? 'On' : 'Off';
1020
    }
1021
}
1022