Diagnoser::get_php_data()   F
last analyzed

Complexity

Conditions 23
Paths > 20000

Size

Total Lines 390
Code Lines 319

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 23
eloc 319
c 1
b 0
f 0
nc 3145728
nop 0
dl 0
loc 390
rs 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
use Chamilo\CoreBundle\Enums\ActionIcon;
6
use Chamilo\CoreBundle\Enums\ObjectIcon;
7
use Chamilo\CoreBundle\Enums\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, '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
            'curl' => [
569
                'link' => 'https://php.net/curl',
570
                'expected' => 1,
571
                'comment' => get_lang('This extension must be loaded.'),
572
            ],
573
            'exif' => [
574
                'link' => 'https://www.php.net/exif',
575
                'expected' => 1,
576
                'comment' => get_lang('This extension should be loaded.'),
577
            ],
578
            'fileinfo' => [
579
                'link' => 'https://php.net/fileinfo',
580
                'expected' => 1,
581
                'comment' => get_lang('This extension must be loaded.'),
582
            ],
583
            'gd' => [
584
                'link' => 'https://php.net/gd',
585
                'expected' => 1,
586
                'comment' => get_lang('This extension must be loaded.'),
587
            ],
588
            'ldap' => [
589
                'link' => 'https://php.net/ldap',
590
                'expected' => 1,
591
                'comment' => get_lang('This extension should be loaded.'),
592
            ],
593
            'mbstring' => [
594
                'link' => 'https://www.php.net/mbstring',
595
                'expected' => 1,
596
                'comment' => get_lang('This extension should be loaded.'),
597
            ],
598
            'pcre' => [
599
                'link' => 'https://php.net/pcre',
600
                'expected' => 1,
601
                'comment' => get_lang('This extension must be loaded.'),
602
            ],
603
            'pdo_mysql' => [
604
                'link' => 'https://php.net/manual/en/ref.pdo-mysql.php',
605
                'expected' => 1,
606
                'comment' => get_lang('This extension must be loaded.'),
607
            ],
608
            'session' => [
609
                'link' => 'https://php.net/session',
610
                'expected' => 1,
611
                'comment' => get_lang('This extension must be loaded.'),
612
            ],
613
            'standard' => [
614
                'link' => 'https://php.net/spl',
615
                'expected' => 1,
616
                'comment' => get_lang('This extension must be loaded.'),
617
            ],
618
            'zlib' => [
619
                'link' => 'https://php.net/zlib',
620
                'expected' => 1,
621
                'comment' => get_lang('This extension must be loaded.'),
622
            ],
623
            'apcu' => [
624
                'link' => 'https://php.net/apcu',
625
                'expected' => 2,
626
                'comment' => get_lang('This extension should be loaded.'),
627
            ],
628
            'bcmath' => [
629
                'link' => 'https://php.net/bcmath',
630
                'expected' => 2,
631
                'comment' => get_lang('This extension should be loaded.'),
632
            ],
633
            'OPcache' => [
634
                'link' => 'https://php.net/opcache',
635
                'expected' => 2,
636
                'comment' => get_lang('This extension should be loaded.'),
637
            ],
638
            'openssl' => [ //required only for DKIM e-mail signatures
639
                'link' => 'https://php.net/openssl',
640
                'expected' => 2,
641
                'comment' => get_lang('This extension should be loaded.'),
642
            ],
643
            'xsl' => [
644
                'link' => 'https://php.net/xsl',
645
                'expected' => 2,
646
                'comment' => get_lang('This extension should be loaded.'),
647
            ],
648
        ];
649
650
        foreach ($extensions as $extension => $data) {
651
            $url = $data['link'];
652
            $expected_value = $data['expected'];
653
            $comment = $data['comment'];
654
655
            $loaded = extension_loaded($extension);
656
            $status = $loaded ? self::STATUS_OK : self::STATUS_ERROR;
657
            $array[] = $this->build_setting(
658
                $status,
659
                '[EXTENSION]',
660
                get_lang('Extension loaded').': '.$extension,
661
                $url,
662
                $loaded,
663
                $expected_value,
664
                'yes_no_optional',
665
                $comment
666
            );
667
        }
668
669
        return $array;
670
    }
671
672
    /**
673
     * Functions to get the data for the mysql diagnostics.
674
     *
675
     * @return array of data
676
     */
677
    public function get_database_data()
678
    {
679
        $array = [];
680
        $em = Database::getManager();
681
        $connection = $em->getConnection();
682
        $host = $connection->getHost();
683
        $db = $connection->getDatabase();
684
        $port = $connection->getPort();
685
        $driver = $connection->getDriver()->getName();
686
687
        $array[] = $this->build_setting(
688
            self::STATUS_INFORMATION,
689
            '[Database]',
690
            'driver',
691
            '',
692
            $driver,
693
            null,
694
            null,
695
            get_lang('Driver')
696
        );
697
698
        $array[] = $this->build_setting(
699
            self::STATUS_INFORMATION,
700
            '[Database]',
701
            'host',
702
            '',
703
            $host,
704
            null,
705
            null,
706
            get_lang('MySQL server host')
707
        );
708
709
        $array[] = $this->build_setting(
710
            self::STATUS_INFORMATION,
711
            '[Database]',
712
            'port',
713
            '',
714
            $port,
715
            null,
716
            null,
717
            get_lang('Port')
718
        );
719
720
        $array[] = $this->build_setting(
721
            self::STATUS_INFORMATION,
722
            '[Database]',
723
            'Database name',
724
            '',
725
            $db,
726
            null,
727
            null,
728
            get_lang('Name')
729
        );
730
731
        return $array;
732
    }
733
734
    /**
735
     * Functions to get the data for the webserver diagnostics.
736
     *
737
     * @return array of data
738
     */
739
    public function get_webserver_data()
740
    {
741
        $array = [];
742
743
        $array[] = $this->build_setting(
744
            self::STATUS_INFORMATION,
745
            '[SERVER]',
746
            '$_SERVER["SERVER_NAME"]',
747
            'http://be.php.net/reserved.variables.server',
748
            $_SERVER["SERVER_NAME"],
749
            null,
750
            null,
751
            get_lang('Server name (as used in your request)')
752
        );
753
        $array[] = $this->build_setting(
754
            self::STATUS_INFORMATION,
755
            '[SERVER]',
756
            '$_SERVER["SERVER_ADDR"]',
757
            'http://be.php.net/reserved.variables.server',
758
            $_SERVER["SERVER_ADDR"],
759
            null,
760
            null,
761
            get_lang('Server address')
762
        );
763
        $array[] = $this->build_setting(
764
            self::STATUS_INFORMATION,
765
            '[SERVER]',
766
            '$_SERVER["SERVER_PORT"]',
767
            'http://be.php.net/reserved.variables.server',
768
            $_SERVER["SERVER_PORT"],
769
            null,
770
            null,
771
            get_lang('Server port')
772
        );
773
        $array[] = $this->build_setting(
774
            self::STATUS_INFORMATION,
775
            '[SERVER]',
776
            '$_SERVER["SERVER_SOFTWARE"]',
777
            'http://be.php.net/reserved.variables.server',
778
            $_SERVER["SERVER_SOFTWARE"],
779
            null,
780
            null,
781
            get_lang('Software running as a web server')
782
        );
783
        $array[] = $this->build_setting(
784
            self::STATUS_INFORMATION,
785
            '[SERVER]',
786
            '$_SERVER["REMOTE_ADDR"]',
787
            'http://be.php.net/reserved.variables.server',
788
            $_SERVER["REMOTE_ADDR"],
789
            null,
790
            null,
791
            get_lang('Remote address (your address as received by the server)')
792
        );
793
        $array[] = $this->build_setting(
794
            self::STATUS_INFORMATION,
795
            '[SERVER]',
796
            '$_SERVER["HTTP_USER_AGENT"]',
797
            'http://be.php.net/reserved.variables.server',
798
            $_SERVER["HTTP_USER_AGENT"],
799
            null,
800
            null,
801
            get_lang('Your user agent as received by the server')
802
        );
803
        $array[] = $this->build_setting(
804
            self::STATUS_INFORMATION,
805
            '[SERVER]',
806
            '$_SERVER["SERVER_PROTOCOL"]',
807
            'http://be.php.net/reserved.variables.server',
808
            $_SERVER["SERVER_PROTOCOL"],
809
            null,
810
            null,
811
            get_lang('Protocol used by this server')
812
        );
813
        $array[] = $this->build_setting(
814
            self::STATUS_INFORMATION,
815
            '[SERVER]',
816
            'php_uname()',
817
            'http://be2.php.net/php_uname',
818
            php_uname(),
819
            null,
820
            null,
821
            get_lang('Information on the system the current server is running on')
822
        );
823
        $array[] = $this->build_setting(
824
            self::STATUS_INFORMATION,
825
            '[SERVER]',
826
            '$_SERVER["HTTP_X_FORWARDED_FOR"]',
827
            'http://be.php.net/reserved.variables.server',
828
            (!empty($_SERVER["HTTP_X_FORWARDED_FOR"]) ? $_SERVER["HTTP_X_FORWARDED_FOR"] : ''),
829
            null,
830
            null,
831
            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).')
832
        );
833
834
        return $array;
835
    }
836
837
    /**
838
     * Functions to get the data for the courses space usage.
839
     *
840
     * @throws Exception
841
     *
842
     * @return array of data
843
     */
844
    public function get_courses_space_data()
845
    {
846
        $array = [];
847
848
        $em = Database::getManager();
849
        $connection = $em->getConnection();
850
        $res = $connection->query('SELECT id, code, directory, disk_quota, last_visit FROM course ORDER BY last_visit DESC, code LIMIT 500');
851
        $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...
852
        $webPath = api_get_path(WEB_COURSE_PATH);
853
        $courseHomeIcon = Display::getMdiIcon(ObjectIcon::HOME, 'ch-tool-icon', null, ICON_SIZE_SMALL, get_lang('Course homepage'));
854
        $courseEditIcon = Display::getMdiIcon(ActionIcon::EDIT, 'ch-tool-icon', null, ICON_SIZE_SMALL, get_lang('Edit'));
855
        $windows = api_is_windows_os();
856
        $courseEditPath = api_get_path(WEB_CODE_PATH).'admin/course_edit.php?id=';
857
        while ($row = $res->fetch()) {
858
            $quota = $row['disk_quota'] / (1024 * 1024);
859
            $dir = $systemPath.$row['directory'].'/';
860
            $path = '<a href="'.$webPath.$row['code'].'/index.php?id_session=0">'.$courseHomeIcon.'</a>';
861
            $size = '-';
862
            $courseEditLink = '<a href="'.$courseEditPath.$row['id'].'">'.$courseEditIcon.'</a>';
863
864
            if (!$windows) {
865
                $err = [];
866
                $du = exec('du -s '.$dir, $err);
867
                list($size, $none) = explode("\t", $du);
868
                unset($none);
869
                $size = intval($size);
870
                if ($size < 1024) {
871
                    $size = 1;
872
                } else {
873
                    $size = round($size / 1024);
874
                }
875
            }
876
            $array[] = [
877
                $path,
878
                $row['code'],
879
                $size,
880
                round($quota),
881
                $courseEditLink,
882
                $row['last_visit'],
883
                $dir,
884
            ];
885
        }
886
887
        return $array;
888
    }
889
890
    /**
891
     * Functions to get the number of courses in the database.
892
     *
893
     * @throws Exception
894
     *
895
     * @return array of data
896
     */
897
    public function get_courses_space_count()
898
    {
899
        $em = Database::getManager();
900
        $connection = $em->getConnection();
901
        $res = $connection->query('SELECT count(id) FROM course');
902
        while ($row = $res->fetch()) {
903
            $count = $row[0];
904
        }
905
906
        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...
907
    }
908
909
    /**
910
     * Additional functions needed for fast integration.
911
     *
912
     * @param int    $status         Status constant defining which icon to use to illustrate the info
913
     * @param string $section        The name of the section this setting is included in
914
     * @param string $title          The name of the setting (usually a translated string)
915
     * @param string $url            A URL to point the user to regarding this setting, or '#' otherwise
916
     * @param mixed  $current_value  The current value for this setting
917
     * @param mixed  $expected_value The expected value for this setting
918
     * @param string $formatter      If this setting is expressed in some kind of format, which format to use
919
     * @param string $comment        A translated string explaining what this setting represents
920
     *
921
     * @return array A list of elements to show in an array's row
922
     */
923
    public function build_setting(
924
        $status,
925
        $section,
926
        $title,
927
        $url,
928
        $current_value,
929
        $expected_value,
930
        $formatter,
931
        $comment
932
    ) {
933
        switch ($status) {
934
            case self::STATUS_OK:
935
                $img = StateIcon::COMPLETE;
936
                break;
937
            case self::STATUS_WARNING:
938
                $img = StateIcon::WARNING;
939
                break;
940
            case self::STATUS_ERROR:
941
                $img = StateIcon::ERROR;
942
                break;
943
            case self::STATUS_INFORMATION:
944
            default:
945
                $img = ActionIcon::INFORMATION;
946
                break;
947
        }
948
949
        $image = Display::getMdiIcon($img, 'ch-tool-icon', null, ICON_SIZE_SMALL, $title);
950
        $url = $this->get_link($title, $url);
951
952
        $formatted_current_value = $current_value;
953
        $formatted_expected_value = $expected_value;
954
955
        if ($formatter) {
956
            if (method_exists($this, 'format_'.$formatter)) {
957
                $formatted_current_value = call_user_func([$this, 'format_'.$formatter], $current_value);
958
                $formatted_expected_value = call_user_func([$this, 'format_'.$formatter], $expected_value);
959
            }
960
        }
961
962
        return [$image, $section, $url, $formatted_current_value, $formatted_expected_value, $comment];
963
    }
964
965
    /**
966
     * Create a link with a url and a title.
967
     *
968
     * @param $title
969
     * @param $url
970
     *
971
     * @return string the url
972
     */
973
    public function get_link($title, $url)
974
    {
975
        return '<a href="'.$url.'" target="about:bank">'.$title.'</a>';
976
    }
977
978
    /**
979
     * @param int $value
980
     *
981
     * @return string
982
     */
983
    public function format_yes_no_optional($value)
984
    {
985
        $return = '';
986
        switch ($value) {
987
            case 0:
988
                $return = get_lang('No');
989
                break;
990
            case 1:
991
                $return = get_lang('Yes');
992
                break;
993
            case 2:
994
                $return = get_lang('Optional');
995
                break;
996
        }
997
998
        return $return;
999
    }
1000
1001
    /**
1002
     * @param $value
1003
     *
1004
     * @return string
1005
     */
1006
    public function format_yes_no($value)
1007
    {
1008
        return $value ? get_lang('Yes') : get_lang('No');
1009
    }
1010
1011
    /**
1012
     * @param int $value
1013
     *
1014
     * @return string
1015
     */
1016
    public function format_on_off($value)
1017
    {
1018
        $value = intval($value);
1019
        if ($value > 1) {
1020
            // Greater than 1 values are shown "as-is", they may be interpreted as "On" later.
1021
            return $value;
1022
        }
1023
        // These are the values 'On' and 'Off' used in the php-ini file. Translation (get_lang()) is not needed here.
1024
        return $value ? 'On' : 'Off';
1025
    }
1026
}
1027