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