Feature 5388: Print Invoices (documents) list gets too long. Fixed by default 180...
[fa-stable.git] / includes / system_tests.inc
1 <?php
2 /**********************************************************************
3     Copyright (C) FrontAccounting, LLC.
4         Released under the terms of the GNU General Public License, GPL, 
5         as published by the Free Software Foundation, either version 3 
6         of the License, or (at your option) any later version.
7     This program is distributed in the hope that it will be useful,
8     but WITHOUT ANY WARRANTY; without even the implied warranty of
9     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
10     See the License here <http://www.gnu.org/licenses/gpl-3.0.html>.
11 ***********************************************************************/
12
13 // Type of requirement for positive test result
14 $test_level = array(
15         0 => _('Info'),
16         1 => _('Optional'),
17         2 => _('Recommended'),
18         3 => _('Required ')
19 );
20
21 // test mysql server version
22 function tst_mysql() 
23 {
24         $test['descr'] = _('MySQL version'). ' >=4.1';
25         $test['type'] = 3;
26         $test['test'] = db_get_version();
27         if (!($test['result'] = ($test['test']>='4.1'))) {
28                 $db_str = explode('-', $test['test']);
29                 $test['result'] = ($db_str[1] == 'MariaDB');
30         }
31         $test['comments'] = _('Upgrade MySQL server to version at least 4.1');
32
33         return $test;
34 }
35 // test php mysql extension
36 function tst_phpmysql() 
37 {
38         $test['descr'] = _('PHP MySQL extension');
39         $test['type'] = 3;
40         $test['result'] = db_extension_exists();
41         $test['test'] = $test['result'] ? _('Yes'): _('No');
42         
43         $test['comments'] = _('Your PHP has to have MySQL extension enabled.');
44         return $test;
45 }
46
47 function tst_php() 
48 {
49         $test['descr'] = _('PHP version').' >=5.0.0';
50         $test['type'] = 3;
51         $test['test'] = phpversion();
52         $test['result'] = $test['test']>='5.0.0';
53         $test['comments'] = _('Upgrade PHP to version at least 5.0.0');
54
55         return $test;
56 }
57
58 function tst_system() 
59 {
60         $test['descr'] = _('Server system');
61         $test['type'] = 0;
62         $test['test'] = PHP_OS;
63         $test['result'] = true;
64
65         return $test;
66 }
67
68 function tst_sessionpath() 
69 {
70         $test['descr'] = _('Session save path');
71         $test['type'] = 0;
72         $test['test'] = session_save_path();
73         $test['result'] = true;
74
75         return $test;
76 }
77
78 function tst_install() 
79 {
80         global $path_to_root;
81
82         $test['descr'] = _('Removed install wizard folder');
83         $test['type'] = 2;
84         $test['result'] = !is_dir($path_to_root.'/install');
85         $test['test'] = _('Not removed');
86         $test['comments'] = _('Remove or rename install wizard folder for security reasons.');
87
88         return $test;
89 }
90
91 function tst_browser() 
92 {
93         $test['descr'] = _('Browser type');
94         $test['type'] = 0;
95         $test['test'] = $_SERVER['HTTP_USER_AGENT'];
96         $test['result'] = true;
97         $test['comments'] = _('Any browser is supported');
98
99         return $test;
100 }
101
102 function tst_server() 
103 {
104         $test['descr'] = _('Http server type');
105         $test['test'] = $_SERVER['SERVER_SOFTWARE'];
106         $test['type'] = 0;
107         $test['result'] = true;
108         $test['comments'] = _('Any server is supported');
109
110         return $test;
111 }
112
113 function tst_gettext() 
114 {
115         $test['descr'] = _('Native gettext');
116         $test['test'] = function_exists('gettext') ? _('Yes'): _('No');
117         $test['type'] = 1;
118         $test['result'] = true;
119         $test['comments'] = _('In case of no gettext support, php emulation is used');
120
121         return $test;
122 }
123
124 function tst_debug() 
125 {
126         global $SysPrefs;
127         $test['descr'] = _('Debugging mode');
128         $test['type'] = 0;
129         $test['test'] = $SysPrefs->go_debug ? _("Yes") : _("No");
130         $test['result'] = $SysPrefs->go_debug != 0;
131         $test['comments'] = _('To switch debugging on set $go_debug>0 in config.php file');
132
133         return $test;
134 }
135
136 function tst_logging() 
137 {
138         global $SysPrefs;
139         
140         $error_logfile = $SysPrefs->error_logfile;
141         $test['descr'] = _('Error logging');
142         $test['type'] = 2;
143         // if error lgging is on, but log file does not exists try write
144         if ($error_logfile && !is_file($error_logfile)) 
145         {
146                 @fclose(@fopen($error_logfile, 'w'));
147         }
148         $test['result'] = @$error_logfile != '' && is_writable($error_logfile);
149         $test['test'] = @$error_logfile == '' ? _("Disabled") : $error_logfile;
150         
151         if (@$error_logfile == '')
152                 $test['comments'] = _('To switch error logging set $error_logging in config.php file');
153         else
154         if (!is_writable($error_logfile))
155                 $test['comments'] = _('Log file is not writeable');
156         
157         return $test;
158 }
159 //
160 //      Installed FA database structure version
161 //
162 function tst_dbversion()
163 {
164         global $db_version;
165         $test['descr'] = _('Current database version');
166         $test['type'] = 3;
167         $test['test'] = get_company_pref('version_id');
168         $test['result'] = $test['test'] == $db_version;
169         $test['comments'] = _('Database structure seems to be not upgraded to current version')
170                 ." ($db_version)";
171
172         return $test;
173 }
174
175
176 function tst_subdirs($install=false)
177 {
178         global $db_connections;
179
180         $comps = $install ? array('0') : array_keys($db_connections);
181
182         $comp_subdirs = array('images', 'pdf_files', 'backup','js_cache');
183
184         $test['descr'] = _('Company subdirectories consistency');
185         $test['type'] = 3;
186         $test['test'] = array(company_path().'/*');
187         foreach($comp_subdirs as $sub) {
188                 $test['test'][] = company_path().'/*/'.$sub;
189         }
190         $test['result'] = true;
191         
192         $comp_path = company_path();
193         foreach ($comps as $n) {
194                 $path = company_path($n);
195                 if (!is_dir($path) || !is_writable($path) ) {
196                         $test['result'] = false;
197                         $test['comments'][] = sprintf(_("'%s' is not writeable"), $path);
198                         continue;
199                 };
200                 foreach($comp_subdirs as $sub) {
201                         $spath = $path.'/'.$sub;
202                         if (!is_dir($spath) || !is_writable($spath) ) {
203                                 $test['result'] = false;
204                                 $test['comments'][] = sprintf(_("'%s' is not writeable"), $spath);
205                         } else {
206                                 $dir = opendir($spath);
207                                 while (false !== ($fname = readdir($dir))) {
208                                         // check only *.js files. Manually installed package can contain other
209                                         // non-writable files which are non-crucial for normal operations
210                                         if (preg_match('/.*(\.js)/', $fname) && !is_writable("$spath/$fname")) {
211                                                 $test['result'] = false;
212                                                 $test['comments'][] = sprintf(_("'%s' is not writeable"), "$spath/$fname");
213                                         }
214                                 }
215                         }
216                 }
217         }
218         return $test;
219 }
220
221 function tst_tmpdir()
222 {
223         global $path_to_root;
224         
225         $test['descr'] = _('Temporary directory');
226         $test['type'] = 3;
227         $test['test'] = VARLIB_PATH;
228         $test['result'] = is_dir($test['test']) && is_writable($test['test']);
229         $test['comments'][] = sprintf(_("'%s' is not writeable"), $test['test']);
230         return $test;
231 }
232
233 function tst_langs($install)
234 {
235         global $installed_languages, $path_to_root, $GetText;
236
237         $test['descr'] = _('Language configuration consistency');
238         $test['type'] = 3;
239         $test['result'] = true;
240         $test['comments'] = array();
241
242         $fname =  $path_to_root.'/lang';
243         $test['test'] = $fname;
244         if (!(is_dir($fname) && is_writable($fname))) {
245                 $test['result'] = false;
246                 $test['comments'][] = _("Languages folder should be writeable.");
247                 return $test;
248         }
249         
250         if (!$install) {
251                 $fname =  $path_to_root.'/lang/installed_languages.inc';
252                 $test['test'] = $fname;
253                 if (!(is_file($fname) && is_writable($fname))) {
254                         $test['result'] = false;
255                         $test['comments'][] = _("Languages configuration file should be writeable.");
256                         return $test;
257                 }
258         }
259
260         $langs = array();
261         
262         foreach ($installed_languages as $lang) {
263
264                 if ($lang['code'] == 'C') continue; // no translation (English)
265                 $langs[] = $lang['code'];
266
267                 $file = $path_to_root.'/lang/'.$lang['code'].'/LC_MESSAGES/'.$lang['code'];
268                 if (@$lang['version'])
269                         $file .= '-'.$lang['version'];
270                 $file .= function_exists('gettext') ? '.mo' : '.po';
271
272                 if (!is_file($file)) {
273                         $test['result'] = false;
274                         $test['comments'][] = sprintf( _('Missing %s translation file.'), $file);
275                 }
276                 if (!$GetText->check_support($lang['code'], $lang['encoding']))
277                 {
278                         $test['result'] = false;
279                         $test['comments'][] = sprintf(_('Missing system locale: %s'), $lang['code'].".".$lang['encoding']);
280                 };
281         }
282
283         $test['test'] = $langs;
284
285         return $test;
286 }
287
288 function tst_config($install)
289 {
290         global $path_to_root;
291
292         $test['descr'] = _('Main config file');
293         $test['test'] = $path_to_root.'/config.php';
294         if ($install) {
295                 $test['type'] = 3;
296                 $writable = check_write($test['test']);
297                 $test['result'] = $writable==1;
298                 $test['comments'][] = $writable == 0 ?
299                         sprintf(_("Can't write '%s' file. Check FA directory write permissions."), $test['test'])
300                         : sprintf(_("'%s' file exists."), $test['test']);
301         } else {
302                 $test['type'] = 2;
303                 $test['result'] = is_file($test['test']) && !is_writable($test['test']);
304                 $test['comments'][] = sprintf(_("'%s' file should be read-only"), $test['test']);
305         }
306         return $test;
307 }
308
309 function tst_dbconfig($install)
310 {
311         global $path_to_root;
312
313         $test['descr'] = _('Database auth file');
314         $test['test'] = $path_to_root.'/config_db.php';
315
316         if ($install) {
317                 $test['type'] = 3;
318                 $writable = check_write($test['test']);
319                 $test['result'] = $writable==1;
320                 $test['comments'][] = $writable == 0 ?
321                         sprintf(_("Can't write '%s' file. Check FA directory write permissions."), $test['test'])
322                         : sprintf(_("'%s' file exists."), $test['test']);
323         } else {
324                 $test['type'] = 2;
325                 $test['result'] = is_file($test['test']) && !is_writable($test['test']);
326                 $test['comments'][] = sprintf(_("'%s' file should be read-only if you do not plan to add or change companies"), $test['test']);
327         }
328         return $test;
329 }
330
331 function tst_extconfig($install)
332 {
333         global $path_to_root, $db_connections;
334
335         $comps = $install ? array('0') : array_keys($db_connections);
336         
337         $test['descr'] = _('Extensions system');
338         $test['type'] = 3;
339         $fname =  $path_to_root.'/installed_extensions.php';
340         $test['test'][] = $fname;
341         $test['result'] = ($install || is_file($fname)) && check_write($fname);
342         $test['test'][] = company_path().'/*/installed_extensions.php';
343         if (!$test['result'])
344                 $test['comments'][] = sprintf(_("'%s' is not writeable"), $fname);
345
346         foreach ($comps as $n) {
347                 $path = company_path($n);
348                 if (!is_dir($path)) continue;
349
350                 $path .= "/installed_extensions.php";
351                 if ((!$install && !is_file($path)) || !check_write($path) ) {
352                         $test['result'] = false;
353                         $test['comments'][] = sprintf(_("'%s' is not writeable"), $path);
354                         continue;
355                 };
356         }
357         foreach(array('modules', 'modules/_cache', 'themes', 'sql') as $dir) {
358                 $fname =  $path_to_root.'/'.$dir;
359                 $test['test'][] = $fname;
360                 $t = is_dir($fname) && is_writable($fname);
361                 if (!$t)
362                         $test['comments'][] = sprintf(_("'%s' is not writeable"), $fname);
363                 $test['result'] &= $t;
364         }
365
366         foreach(array('Release', 'Themes', 'Languages', 'Extensions', 'Charts') as $file) {
367                 $fname = $path_to_root."/modules/_cache/".$file.".gz";
368                 $t = !file_exists($fname) || is_writable($fname);
369                 if (!$t)
370                         $test['comments'][] = sprintf(_("'%s' is not writeable"), $fname);
371                 $test['result'] &= $t;
372         }
373
374         if(!$test['result'])
375                 $test['comments'][] = _("Extensions configuration files and directories should be writeable");
376
377         $fname = $path_to_root."/themes";
378         $themedir = opendir($fname);
379         while (false !== ($fname = readdir($themedir)))
380         {
381                 if ($fname!='.' && $fname!='..' && is_dir($path_to_root.'/themes/'.$fname)
382                         && !in_array($fname, array('canvas', 'default', 'dropdown')))
383                 {
384                         $test['test'][] = $fname;
385                         $test['result'] = is_writable($path_to_root.'/themes/'.$fname);
386                         if (!$test['result']) {
387                                 $test['comments'][] = 
388                                         sprintf(_("Non-standard theme directory '%s' is not writable"), $fname);
389                                 break;
390                         }
391                 }
392         }
393         closedir($themedir);
394
395         $test['test'][] = 'OpenSSL PHP extension';
396         if (!extension_loaded('openssl')) {
397                 $test['result'] = false;
398                 $test['comments'][] = _("OpenSSL PHP extension have to be enabled to use extension repository system.");
399         } elseif (!function_exists('openssl_verify')) {
400                 $test['result'] = false;
401                 $test['comments'][] = _("OpenSSL have to be available on your server to use extension repository system.");
402         }
403         return $test;
404 }
405
406 function display_system_tests($install = false)
407 {
408         global $test_level;
409
410         if ($install)
411                 $system_tests = array('tst_php', 'tst_phpmysql', 'tst_system', 'tst_dbconfig', 
412                         'tst_config',
413                         'tst_subdirs', 'tst_langs', 'tst_tmpdir', 'tst_sessionpath', 'tst_extconfig'
414                 );
415         else
416                 $system_tests = array('tst_mysql', 'tst_php', 'tst_server', 'tst_system', 'tst_browser',
417                         'tst_gettext', 'tst_debug', 'tst_logging',
418                         'tst_dbversion', 'tst_subdirs', 'tst_langs', 'tst_tmpdir', 'tst_sessionpath',
419                         'tst_install', 'tst_dbconfig', 'tst_config', 'tst_extconfig'
420                 );
421
422
423         start_table(TABLESTYLE, "width='80%'");
424         $th = array(_("Test"), _('Test type'), _("Value"), _("Comments"));
425         table_header($th);
426
427         $ret = true;
428         $k = 0; //row colour counter
429         foreach ($system_tests as $test) 
430         {
431                 alt_table_row_color($k);
432                 $result = $test($install);
433                 if (!$result) continue;
434                 
435                 label_cell($result['descr']);
436                 label_cell($test_level[$result['type']]);
437
438                 $res = is_array(@$result['test']) ? implode('<br>', $result['test']) 
439                         : $result['test'];
440                 label_cell($res);
441
442                 $comm = is_array(@$result['comments']) ? implode('<br>', $result['comments']) 
443                         : @$result['comments'];
444                 $color = ($result['result'] ? 'green': 
445                         ($result['type']==3 ? 'red' :
446                          ($result['type']==2 ? 'orange' : 'green')));
447                 label_cell("<span style='color:$color'>".
448                         ($result['result'] ? _('Ok') : '<b>'.$comm.'</b>').'</span>');
449                 end_row();
450                 $ret = $ret && (($result['result']!=0) || ($result['type'] < 3));
451         }
452         end_table();
453
454         return $ret;
455 }