1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35:
36:
37: 38: 39: 40: 41: 42: 43: 44:
45:
46:
47:
48:
49: $document = '<html><header><title>X2Engine System Requirements Check</title>{headerContent}</head><body><div style="width: 680px; border:1px solid #DDD; margin: 25px auto 25px auto; padding: 20px;font-family:sans-serif;">{bodyContent}</div></body></html>';
50: $totalFailure = array(
51: "<h1>This server definitely, most certainly cannot run X2Engine.</h1><p>Not even the system requirements checker script itself could run properly on this server. It encountered the following {scenario}:</p>\n<pre style=\"overflow-x:auto;margin:5px;padding:5px;border:1px red dashed;\">\n",
52: "\n</pre>"
53: );
54: $mode = php_sapi_name() == 'cli' ? 'cli' : 'web';
55: $responding = false;
56: if(!isset($thisFile))
57: $thisFile = __FILE__;
58: if(!isset($standalone))
59: $standalone = realpath($thisFile) === realpath(__FILE__);
60: $returnArray = (isset($returnArray)?$returnArray:false) || $mode == 'cli';
61: if(!$standalone){
62:
63: $document = '{bodyContent}';
64: }
65: $tryCurl = 0;
66:
67:
68:
69:
70:
71:
72:
73:
74:
75: 76: 77: 78: 79:
80: function RIP(){
81: global $standalone;
82: if($standalone){
83: die();
84: }
85: }
86:
87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98:
99: function handleReqError($no, $st, $fi = Null, $ln = Null){
100: global $document, $totalFailure, $responding, $standalone;
101: $fatal = $no === E_ERROR;
102: if($no === E_ERROR){
103: $responding = true;
104: echo strtr($document, array(
105: '{headerContent}' => '',
106: '{bodyContent}' => str_replace('{scenario}', 'error', $totalFailure[0]."Error [$no]: $st $fi L$ln".$totalFailure[1])
107: ));
108: RIP();
109: }
110: }
111:
112: 113: 114: 115: 116: 117: 118: 119: 120:
121: function handleReqException($e){
122: global $document, $totalFailure, $responding, $standalone;
123: $responding = true;
124: $message = 'Exception: "'.$e->getMessage().'" in '.$e->getFile().' L'.$e->getLine()."\n";
125:
126: foreach($e->getTrace() as $stackLevel){
127: $message .= $stackLevel['file'].' L'.$stackLevel['line'].' ';
128: if($stackLevel['class'] != ''){
129: $message .= $stackLevel['class'];
130: $message .= '->';
131: }
132: $message .= $stackLevel['function'];
133: $message .= "();\n";
134: }
135: $message = str_replace('{scenario}', 'uncaught exception', $totalFailure[0].$message.$totalFailure[1]);
136: echo strtr($document, array(
137: '{headerContent}' => '',
138: '{bodyContent}' => $message
139: ));
140:
141: RIP();
142: }
143:
144: 145: 146: 147: 148: 149: 150: 151:
152: function reqShutdown(){
153: global $document, $totalFailure, $responding, $standalone;
154: $error = error_get_last();
155: if($error != null && !$responding){
156: $errno = $error["type"];
157: $errfile = $error["file"];
158: $errline = $error["line"];
159: $errstr = $error["message"];
160: $errtype = ($errno == E_PARSE ? 'parse' : 'fatal').' error';
161: $message = "PHP $errtype [$errno]: $errstr in $errfile L$errline";
162: $message = str_replace('{scenario}', $errtype, $totalFailure[0].$message.$totalFailure[1]);
163: echo strtr($document, array(
164: '{headerContent}' => '',
165: '{bodyContent}' => $message
166: ));
167: }
168: }
169:
170: 171: 172: 173: 174: 175: 176: 177: 178:
179: function exceptionForError($no, $st, $fi = Null, $ln = Null){
180: throw new Exception("Error [$no]: $st $fi L$ln");
181: }
182:
183:
184:
185:
186:
187: 188: 189: 190: 191: 192:
193: function checkDNS($hostname) {
194: if(function_exists('dns_check_record')) {
195: return (integer) @dns_check_record($hostname);
196: } else {
197: return 0;
198: }
199: }
200:
201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213:
214: function checkServerVar($thisFile = null){
215: $vars = array('HTTP_HOST', 'SERVER_NAME', 'SERVER_PORT', 'SCRIPT_NAME', 'SCRIPT_FILENAME', 'PHP_SELF', 'HTTP_ACCEPT', 'HTTP_USER_AGENT');
216: $missing = array();
217: foreach($vars as $var){
218: if(!isset($_SERVER[$var]))
219: $missing[] = $var;
220: }
221: if(!empty($missing))
222: return installer_tr('$_SERVER does not have {vars}.', array('{vars}' => implode(', ', $missing)));
223: if(empty($thisFile))
224: $thisFile = __FILE__;
225:
226: if(realpath($_SERVER["SCRIPT_FILENAME"]) !== realpath($thisFile))
227: return installer_t('$_SERVER["SCRIPT_FILENAME"] must be the same as the entry script file path.');
228:
229: if(!isset($_SERVER["REQUEST_URI"]) && isset($_SERVER["QUERY_STRING"]))
230: return installer_t('Either $_SERVER["REQUEST_URI"] or $_SERVER["QUERY_STRING"] must exist.');
231:
232: if(!isset($_SERVER["PATH_INFO"]) && strpos($_SERVER["PHP_SELF"], $_SERVER["SCRIPT_NAME"]) !== 0)
233: return installer_t('Unable to determine URL path info. Please make sure $_SERVER["PATH_INFO"] (or $_SERVER["PHP_SELF"] and $_SERVER["SCRIPT_NAME"]) contains proper value.');
234:
235: return '';
236: }
237:
238: 239: 240: 241: 242: 243:
244: function isAllowedDir($path) {
245: $basedir = trim(ini_get('open_basedir'));
246: if($allowCwd = empty($basedir))
247: return 1;
248: $basedirs = explode(PATH_SEPARATOR,$basedir);
249: foreach($basedirs as $dir){
250: if(empty($dir))
251: continue;
252: if(strpos($path,$dir) !== false){
253: $allowCwd = 1;
254: break;
255: }
256: }
257: return $allowCwd;
258: }
259:
260: 261: 262: 263: 264: 265: 266:
267: function tryGetRemote($url) {
268: global $tryCurl;
269: if($tryCurl || !(bool) ($response = @file_get_contents($url))){
270:
271: $ch = @curl_init($url);
272: if(!(bool) $ch)
273: return 0;
274: curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
275: curl_setopt($ch, CURLOPT_POST, 0);
276: $response = @curl_exec($ch);
277: curl_close($ch);
278: }
279: return (int) (bool) $response;
280: }
281:
282:
283: if(!$returnArray){
284: set_error_handler('handleReqError');
285: set_exception_handler('handleReqException');
286: register_shutdown_function('reqShutdown');
287: }
288:
289:
290:
291:
292:
293: if(!isset($scenario))
294: $scenario = 'install';
295:
296:
297: ob_start();
298: phpinfo();
299: $pi = ob_get_contents();
300: preg_match('%(<style[^>]*>.*</style>)%ms',$pi,$phpInfoStyle);
301: preg_match('%<body>(.*)</body>%ms',$pi,$phpInfoContent);
302: ob_end_clean();
303: if(count($phpInfoStyle))
304: $phpInfoStyle = $phpInfoStyle[1];
305: else
306: $phpInfoStyle = '';
307: if(count($phpInfoContent))
308: $phpInfoContent = $phpInfoContent[1];
309: else
310: $phpInfoStyle = '';
311:
312: $phpInfoStyle .= '<style>
313: .hidden {display: none;}
314: </style>';
315:
316:
317: if(!function_exists('installer_t')){
318: function installer_t($msg){
319: return $msg;
320: }
321:
322: }
323: if(!function_exists('installer_tr')) {
324: function installer_tr($msg,$params = array()){
325: return strtr($msg,$params);
326: }
327: }
328:
329: $canInstall = True;
330: $curl = true;
331: $tryAccess = true;
332: $reqMessages = array_fill_keys(array(1, 2, 3), array());
333: $requirements = array_fill_keys(array('functions','classes','extensions','environment'),array());
334: $rbm = installer_t("required but missing");
335:
336:
337: if(!(@function_exists('function_exists') && @function_exists('extension_loaded')))
338: throw new Exception(installer_t('The functions function_exist and/or extension_loaded are unavailable!').' '.installer_t('The requirements check script itself cannot run.'));
339:
340:
341:
342:
343:
344:
345:
346: $requirements['environment']['filesystem_ownership'] = 1;
347: $uid = array_fill_keys(array('{id_own}', '{id_run}'), null);
348: $uid['{id_own}'] = fileowner(realpath(dirname(__FILE__)));
349: if($requirements['extensions']['posix'] = function_exists('posix_geteuid')){
350: $uid['{id_run}'] = posix_geteuid();
351: if($uid['{id_own}'] !== $uid['{id_run}']){
352: $reqMessages[3][] = strtr(installer_t("PHP is running with user ID={id_run}, but this directory is owned by the system user with ID={id_own}."), $uid);
353: $requirements['environment']['filesystem_ownership'] = 0;
354: }
355: } else {
356: $reqMessages[1][] = installer_t('The requirements check script could not determine if local files have correct ownership because the "posix" extension is not available.');
357: }
358:
359: $requirements['environment']['filesystem_permissions'] = 1;
360:
361: if(!is_writable(dirname(__FILE__))){
362: $reqMessages[3][] = installer_t("This directory is not writable by PHP processes run by the webserver.");
363: $requirements['environment']['filesystem_permissions'] = 0;
364: }
365: if(!is_writable(__FILE__)) {
366: $reqMessages[3][] = installer_t("Permissions and/or ownership of uploaded files do not permit PHP processes run by the webserver to write files.");
367: $requirements['environment']['filesystem_permissions'] = 0;
368: }
369:
370:
371:
372:
373:
374:
375: $requirements['environment']['open_basedir'] = 1;
376: if(!empty($basedir)){
377: if(!isAllowedDir(dirname(__FILE__))) {
378: $reqMessages[3][] = installer_t('The base directory configuration directive is set, and it does not include the current working directory.');
379: $requirements['environment']['open_basedir'] = 0;
380: }
381: }
382:
383:
384: $requirements['environment']['php_version'] = 1;
385: if(!version_compare(PHP_VERSION, "5.3.0", ">=")){
386: $reqMessages[3][] = installer_t("Your server's PHP version").': '.PHP_VERSION.'; '.installer_t("version 5.3 or later is required");
387: $requirements['environment']['php_version'] = 0;
388: }
389:
390: $requirements['environment']['php_server_superglobal'] = 0;
391: if($mode == 'web'){
392: if(($message = checkServerVar($thisFile)) !== ''){
393: $reqMessages[3][] = installer_t($message);
394: }else{
395: $requirements['environment']['php_server_superglobal'] = 1;
396: }
397: }
398:
399:
400: $requirements['extensions']['pcre'] = 0;
401: $requirements['environment']['pcre_version'] = 0;
402: if(!($requirements['classes']['Reflection']=class_exists('Reflection', false))){
403: $reqMessages[3][] = '<a href="http://php.net/manual/class.reflectionclass.php">PHP reflection class</a>: '.$rbm;
404: }else if($requirements['extensions']['pcre']=extension_loaded("pcre")){
405:
406: $pcreReflector = new ReflectionExtension("pcre");
407: ob_start();
408: $pcreReflector->info();
409: $pcreInfo = ob_get_clean();
410: $matches = array();
411: preg_match("/([\d\.]+) \d{4,}-\d{1,2}-\d{1,2}/", $pcreInfo, $matches);
412: $thisVer = $matches[1];
413: $reqVer = '7.4';
414: if(!($requirements['environment']['pcre_version'] = version_compare($thisVer, $reqVer) >= 0)){
415: $reqMessages[3][] = strtr(installer_t("The version of the PCRE library included in this build of PHP is {thisVer}, but {reqVer} or later is required."), array('{thisVer}' => $thisVer, '{reqVer}' => $reqVer));
416: }
417: }else{
418: $reqMessages[3][] = '<a href="http://www.php.net/manual/book.pcre.php">PCRE extension</a>: '.$rbm;
419: }
420:
421: if(!($requirements['extensions']['SPL']=extension_loaded("SPL"))){
422:
423: $reqMessages[3][] = '<a href="http://www.php.net/manual/book.spl.php">SPL</a>: '.$rbm;
424: }
425:
426: if(!($requirements['extensions']['pdo_mysql']=extension_loaded('pdo_mysql'))){
427: $reqMessages[3][] = '<a href="http://www.php.net/manual/ref.pdo-mysql.php">PDO MySQL extension</a>: '.$rbm;
428: }
429:
430: if(!($requirements['extensions']['ctype']=extension_loaded('ctype'))){
431: $reqMessages[3][] = '<a href="http://www.php.net/manual/book.ctype.php">CType extension</a>: '.$rbm;
432: }
433:
434: if(!($requirements['extensions']['mbstring']=extension_loaded('mbstring'))){
435: $reqMessages[3][] = '<a href="http://www.php.net/manual/book.mbstring.php">Multibyte string extension</a>: '.$rbm;
436: }
437:
438: if(!($requirements['extensions']['json']=extension_loaded('json'))){
439: $reqMessages[3][] = '<a href="http://www.php.net/manual/function.json-decode.php">json extension</a>: '.$rbm;
440: }
441:
442: if(!($requirements['extensions']['hash']=extension_loaded('hash'))){
443: $reqMessages[3][] = '<a href="http://www.php.net/manual/book.hash.php">HASH Message Digest Framework</a>: '.$rbm;
444: } else {
445: $algosRequired = array('sha512');
446: $algosAvail = hash_algos();
447: $algosNotAvail = array_diff($algosRequired,$algosAvail);
448: if(!empty($algosNotAvail))
449: $reqMessages[3][] = installer_t('Some hashing algorithms required for software updates are missing on this server:').' '.implode(', ',$algosNotAvail);
450: }
451:
452:
453: $ssp = ini_get('session.save_path');
454: if(!is_writable($ssp)){
455: $reqMessages[3][] = strtr(installer_t('The path defined in session.save_path ({ssp}) is not writable.'), array('{ssp}' => $ssp));
456: }
457:
458:
459: $requiredFunctions = array(
460: 'php_sapi_name',
461: 'mb_regex_encoding',
462: 'getcwd',
463: 'chmod',
464: 'hash_algos',
465: 'mt_rand',
466: 'md5'
467: );
468: $missingFunctions = array();
469: foreach($requiredFunctions as $function)
470: if(!($requirements['functions'][$function]=function_exists($function)))
471: $missingFunctions[] = $function;
472: if(count($missingFunctions))
473: $reqMessages[3][] = installer_t('The following required PHP function(s) is/are missing or disabled: ').implode(', ',$missingFunctions);
474:
475: if(!in_array('chmod', $missingFunctions)) {
476: set_error_handler('exceptionForError');
477: try{
478:
479: $fp = fileperms(__FILE__);
480: chmod(__FILE__,octdec(100700));
481: chmod(__FILE__,$fp);
482: $requirements['environment']['chmod'] = 1;
483: }catch (Exception $e){
484: $reqMessages[3][] = installer_t('PHP scripts are not permitted to run the function "chmod".');
485: $requirements['environment']['chmod'] = 0;
486: }
487: restore_error_handler();
488: }
489:
490:
491:
492:
493:
494: $curl = ($requirements['extensions']['curl']=extension_loaded("curl")) && function_exists('curl_init') && function_exists('curl_exec');
495: if(!$curl){
496: $curlMissingIssues = array(
497: installer_t('Time zone widget will not work'),
498: installer_t('Google integration will not work'),
499: installer_t('Built-in error reporter will not work'),
500: installer_t('API web hooks (and thus, Zapier integration) will not work'),
501: installer_t('Twitter integration will not work')
502: );
503: $reqMessages[2][] = '<a href="http://php.net/manual/book.curl.php">cURL</a>: '.$rbm.'. '.installer_t('This will result in the following issues:').'<ul><li>'.implode('</li><li>', $curlMissingIssues).'</li></ul>'.installer_t('Furthermore, please note: without this extension, the requirements check script could not check the outbound internet connection of this server.');
504: }
505:
506: if(!(bool) ($requirements['environment']['allow_url_fopen']=@ini_get('allow_url_fopen'))){
507: if(!$curl){
508: $tryAccess = false;
509: $reqMessages[2][] = installer_t('The PHP configuration option "allow_url_fopen" is disabled in addition to the CURL extension missing. This means there is no possible way to make outbound HTTP/HTTPS requests.')
510: .' '.installer_t('Software updates will have to be performed using the "offline" method, and Google integration will not work.');
511: } else
512: $reqMessages[1][] = installer_t('The PHP configuration option "allow_url_fopen" is disabled. CURL will be used for making all HTTP requests during updates.');
513: }
514:
515:
516: $maxMem = ini_get('memory_limit');
517: if(!empty($maxMem) && preg_match('/(\d+)([BKMG])/i',$maxMem,$match)) {
518: $multiplier = array(
519: 'b' => 1,
520: 'k' => 1024,
521: 'm' => 1048576,
522: 'g' => 1073741824
523: );
524: $maxBytes = ((integer)$match[1])*$multiplier[strtolower($match[2])];
525: } else {
526: $maxBytes = (integer) $maxMem;
527: }
528: if((bool)((int)$maxBytes+1) && $maxBytes <= 33554432) {
529: $reqMessages[2][] = installer_t('The memory limit is set to 32 megabytes or lower in the PHP configuration. Please consider raising this limit. X2Engine may otherwise encounter fatal runtime errors.');
530: }
531:
532:
533:
534:
535:
536:
537: $updateMethodMsg = installer_t('Software updates will have to be performed using the "offline" method.');
538: $googleIntegrationMsg = installer_t('Google integration will not work.');
539: $tmpProblemMsg = installer_t('This may be a temporary problem.');
540: $cutOffMsg = installer_t('This server is effectively cut off from the internet.');
541: $firewallMsg = installer_t('This is likely because the server is behind a firewall that is preventing outbound HTTP/HTTPS requests.');
542:
543:
544: $tryCurl = !$requirements['environment']['allow_url_fopen'];
545: $requirements['environment']['updates_connection'] = 0;
546: $requirements['environment']['outbound_connection'] = 0;
547:
548:
549: if($tryAccess){
550:
551:
552:
553: if($requirements['environment']['outbound_connection'] = checkDNS('google.com')){
554:
555: if($requirements['environment']['outbound_connection'] = tryGetRemote('http://www.google.com')){
556:
557: if($requirements['environment']['updates_connection'] = checkDNS('x2planet.com')){
558: if(!($requirements['environment']['updates_connection'] = tryGetRemote('https://x2planet.com/installs/registry/reqCheck'))){
559:
560: $reqMessages[2][] = installer_t('Could not reach the updates server from this web server.')
561: .' '.$firewallMsg
562: .' '.$updateMethodMsg
563: .' '.$tmpProblemMsg;
564: }
565: }else{
566:
567: $reqMessages[2][] = installer_t('The DNS record associated with the updates server is not available on this web server.')
568: .' '.$updateMethodMsg
569: .' '.$tmpProblemMsg;
570: }
571: } else {
572:
573: $reqMessages[2][] = $cutOffMsg
574: .' '.$firewallMsg
575: .' '.installer_t('It is also posible that no outbound network route exists.')
576: .' '.$updateMethodMsg
577: .' '.$googleIntegrationMsg;
578: }
579: }else{
580:
581: $reqMessages[2][] = $cutOffMsg
582: .' '.installer_t('This is due to local DNS resolution failing.')
583: .' '.$updateMethodMsg
584: .' '.$googleIntegrationMsg;
585: }
586: }
587:
588: if(!function_exists('dns_check_record') && !$requirements['environment']['outbound_connection']) {
589: $reqMessages[1][] = installer_t('Note: the function "dns_check_record" is not available on this server, so network diagnostic messages may not be accurate.');
590: }
591:
592:
593:
594:
595: if(!(bool) ($requirements['environment']['fsockopen'] = function_exists('fsockopen'))) {
596: $reqMessages[2][] = installer_t('The function "fsockopen" is unavailable or has been disabled on this server. X2Engine will not be able to send email via SMTP.');
597: }
598:
599:
600: if(!(bool) ($canBackup = $requirements['functions']['proc_open'] = function_exists('proc_open'))) {
601: $reqMessages[2][] = installer_t('The function proc_open is unavailable on this system. X2Engine will not be able to control the local cron table, or perform database backups, or automatically restore a database to its backup in the event of a failed update.');
602: }
603: $requirements['environment']['shell'] = $canBackup;
604: if($canBackup){
605: try{
606:
607: $descriptor = array(
608: 0 => array('pipe', 'r'),
609: 1 => array('pipe', 'w'),
610: 2 => array('pipe', 'w'),
611: );
612: $testProc = proc_open('mysqldump --help', $descriptor, $pipes);
613: $ret = proc_close($testProc);
614: unset($pipes);
615:
616: if($ret === 0) {
617: $prog = 'mysqldump';
618: } else if($ret !== 0){
619: $testProc = proc_open('mysqldump.exe --help', $descriptor, $pipes);
620: $ret = proc_close($testProc);
621: if($ret !== 0)
622: throw new Exception(installer_t('Unable to perform database backup; the "mysqldump" utility is not available on this system.'));
623: else
624: $prog = 'mysqldump.exe';
625: }
626: }catch(Exception $e){
627: $canBackup = false;
628: }
629: $canBackup = isset($prog);
630: }
631: if(!$canBackup && $requirements['functions']['proc_open']){
632: $requirements['environment']['shell'] = 0;
633: $reqMessages[1][] = installer_t('The "mysqldump" and "mysql" command line utilities are unavailable on this system. X2Engine will not be able to automatically make a backup of its database during software updates, or automatically restore its database in the event of a failed update.');
634: }
635:
636: $giNotwork = installer_t('Google integration will not work.');
637: if(!function_exists('sys_get_temp_dir')){
638: $message = installer_t('The function "sys_get_temp_dir" is unavailable.');
639: if(isAllowedDir('/tmp')){
640: if(!is_writable('/tmp')){
641: $reqMessages[1][] = $msg.' '.installer_t('The directory "/tmp" is not writable.').' '.$giNotwork;
642: }
643: } else {
644: $reqMessages[1][] = $msg.' '.installer_t('Use of the directory "/tmp" is not permitted on this system.').' '.$giNotwork;
645: }
646: } else {
647: $tmp = sys_get_temp_dir();
648: if(!empty($tmp) && isAllowedDir($tmp)){
649: if(!is_writable($tmp)){
650: $reqMessages[1][] = installer_t('The system temporary directory, according to "sys_get_temp_dir", is not writable.').' '.$giNotwork;
651: }
652: }else{
653: $reqMessages[1][] = installer_t('Usage of the system temporary directory, according to "sys_get_temp_dir", is either unknown or not permitted.').' '.$giNotwork;
654:
655: }
656: }
657:
658:
659:
660:
661:
662: if(!($requirements['extensions']['openssl']=extension_loaded('openssl') && $requirements['extensions']['mcrypt']=extension_loaded('mcrypt'))) {
663: $reqMessages[1][] = installer_t('The "openssl" and "mcrypt" libraries are not available. If any application credentials (i.e. email account passwords) are entered into X2Engine, they will be stored in the database in plain text (without any encryption whatsoever). Thus, if the database is ever compromised, those passwords will be readable by unauthorized parties.');
664: }
665:
666:
667: if(!($requirements['extensions']['zip']=extension_loaded('zip'))){
668: $reqMessages[1][] = '<a href="http://php.net/manual/book.zip.php">Zip</a>: '.$rbm.'. '.installer_t('This will result in the inability to import and export custom modules.');
669: }
670:
671: if(!($requirements['extensions']['fileinfo']=extension_loaded('fileinfo'))){
672: $reqMessages[1][] = '<a href="http://php.net/manual/book.fileinfo.php">Fileinfo</a>: '.$rbm.'. '.installer_t('Image previews and MIME info for uploaded files in the media module will not be available.');
673: }
674:
675: if(!($requirements['extensions']['gd']=extension_loaded('gd'))){
676: $reqMessages[1][] = '<a href="http://php.net/manual/book.image.php">GD</a>: '.$rbm.'. '.installer_t('Security captchas will not work, and the media module will not be able to detect or display the dimensions of uploaded images.');
677: }
678:
679:
680: if(!($requirements['extensions']['ssh2']=extension_loaded('ssh2'))){
681: $reqMessages[1][] = '<a href="http://www.php.net/manual/book.ssh2.php">ssh2 extension</a>: '.$rbm.'. '.installer_t('The FileUtil class needs the SSH2 extension to use SSH as a file operation method.');
682: }
683: if(!($requirements['extensions']['iconv']=extension_loaded('iconv'))){
684: $reqMessages[1][] = '<a href="http://www.php.net/manual/book.iconv.php">iconv extension</a>: '.$rbm.'. '.installer_t('A number of components require the iconv module for encoding and will not function properly.');
685: }
686:
687:
688: $hasMessages = false;
689: foreach($reqMessages as $severity=>$messages) {
690: if((bool)count($messages))
691: $hasMessages = true;
692: }
693: $canInstall = !(bool) count($reqMessages[3]);
694:
695:
696:
697:
698:
699:
700:
701:
702: $output = '';
703:
704: if(!$canInstall){
705: $output .= '<div style="width: 100%; text-align:center;"><h1>'.installer_t("Cannot $scenario X2Engine")."</h1></div>\n";
706: $output .= "<strong>".installer_t('Unfortunately, your server does not meet the minimum system requirements;')."</strong><br />";
707: }else if($hasMessages){
708: $output .= '<div style="width: 100%; text-align:center;"><h1>'.installer_t('Note the following:').'</h1></div>';
709: }else if($standalone){
710: $output .= '<div style="width: 100%; text-align:center;"><h1>'.installer_t('This webserver can run X2Engine!').'</h1></div>';
711: }
712:
713: $severityClasses = array(
714: 1 => 'minor',
715: 2 => 'major',
716: 3 => 'critical'
717: );
718: $severityStyles = array(
719: 1 => 'color:black',
720: 2 => 'color:#CF5A00',
721: 3 => 'color: #DD0000'
722: );
723:
724: if($hasMessages){
725: $output .= "\n<ul>";
726: foreach($reqMessages as $severity => $messages){
727: foreach($messages as $message){
728: $output .= "<li style=\"{$severityStyles[$severity]}\">$message</li>";
729: }
730: }
731: $output .= "</ul>\n";
732: $output .= "<div style=\"text-align:center;\">Severity legend: ";
733: foreach($severityClasses as $severity => $class) {
734: $output .= "<span style=\"{$severityStyles[$severity]}\">$class</span> ";
735: }
736: $output .= "<br />\n";
737: if($canInstall)
738: $output .= '<br />'.installer_t("All other essential requirements were met.").' ';
739: $output .= '</div><br />';
740: }
741:
742: if($standalone){
743: $imgData = 'iVBORw0KGgoAAAANSUhEUgAAAGkAAAAfCAYAAADk+ePmAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAADMlJREFUeNrs'.
744: 'W3lwVGUS/82RZBISyMkRwhESIISjEBJAgWRQbhiuci3AqsUVarfcWlZR1xL+2HJry9oqdNUtj0UFQdSwoELCLcoKBUgOi3AkkkyCYi4SSELOSTIzyWz3N/Ne3nszCVnd2qHKNNU1'.
745: '731nf91fd/++7wUdiI4cOTKIfp4hfoJ4NPrJ39RAnEn8hsViuaLzGOhMZGTk1Pj4eAwZMqRfRX6mtrY2VFRUoKSkhI1lNrIHsYFmzJwpGnS5XP1a8jMFmUxISEyEwWgML7p+PVPP'.
746: 'IS4hIQGurq5fFNtaW/Hujh2q9zdef/2+knHUyJEwmUyj2ZNGh0dE/OI8qLy8HMOHD5fXze+JtHvvNz0EBweDjSSs5g86c+Ys6uvrSFlxuHbtKjZt2oTKykrk5OQI4Tg2r1mzBm++'.
747: '+SY2b96MnNxcXLvqbnfw4EFMnjIFIdSO29fX18NsNnMcF/14zClTJuPEiRPyu9mcLr/zPOnUXlq71WoV5dkXs2VZtm/fjhdeeEGU79y5U8jgDzL6Mw/VkYEoHyJ1Rqp4tpKCT548'.
748: 'iY0bNwojHTp0COWUQF0eGa+SgZhabTZqXw8O0xkZGVi/fj0p9ppoW8HKT08XXsH9Fy9eLPpwO1ubTZQz79q1C7GxsfLalf0kWWLJ02rr6pBLm2MRjeMPPbloTr3kSf7gSlJqakqK'.
749: 'eK4nZbi6XEgkxZuCgtw7nATkZ/4tsZZg0qRJiKTQzMZKm5uGivIK0e8QeVVdbR2VzRXvCWPGiP6lpOizZ84I71m3dq2YT6rjdhHh4bIsPIeyLnbYMGFERlnKfv9v9rsnSUimoqKS'.
750: 'EyRxEOrq6oU8VZVVwls4X5rIqzgErVy1Cv+kXc27K4WMW0W7nxW5YuVKGZmyB0rr4ecFCxeqoC3X5eXlqdop63helkUgLDLM7t27sXLlKr/piGc1UKh4iVEE76Sfy699/A0iBgYj'.
751: 'elDwPdtyDikoKBC/Tc1NWEjKDAsLE4Jdzs93ly1YCKPRAIfTKZBOBBmMhZaeuX3N7du4fPkympqahPECjEaM9KzHZArGxW8u4vbtGsTEDBbti4uKEBYaJp5HKtbNctwoLZVl4TKj'.
752: 'MQDFxUVYunTp/0Q/P4VrqqvBh1nXHAoTP5feOZCHzDNFCA0JxG9WPABL2rhe2xcWFqKqqgoLFiy4bw+Uez/8EJYVK4S3+osYKLnDXZdvVy7+sZaSrQMGgx4GvU5wUnyMV7t/5/2A'.
753: 'Q18XYUjUAPx4qxE7My+h8nYTfrtmeo+T2yj5J09I7nFuf9O3FBKXL7dg6NBhfpWRHcoNwV2+IXheYRXe+TRPeEdocCAGBAfg2ccfxNTx3VdH331fi7f25yJ1Yizyi25BT4a0Ozph'.
754: 'a3fgVm0z3iYP+/rbm2i22eU+YTTevJTReOrRsaq5z58/j9ra2h4FnjNnDqKjo1FEIYtZIg5PISEh8ruyXuqjJZ6rrKwM5cQSjU9KQpKHH5o9W4yRnZMt6qRypszMTLkPh8xp06ap'.
755: 'xpbqeV6eX9vHF62ifNtTVurVk9YtmoiC0hpcKq6Wy/YevYLxo+YhKNCI8ppG/CMjB7HRYbCS14WGBJEhA5GSTMk8fTzWbvscza1u4xgN+u5Q0uHE8QulOJdfhoyXV2NoVKhbcefO'.
756: 'UQ4o7nEhycnJBNmjcP36dRzOypLLdfSPw5JEynqpj0T5+ZewL2MfARTvzcBGqZg+HUnjkwRQUI5joPPauHHjxXOWQuG8OZJeeVWAG4mk+gkTJggjsX6z7mGkNavXwNnZ6RM46CVP'.
757: '6olffOIh4UVymCIPyThRQL92fHjkKoVCHToFVKTfzi4MjQ7FH9fNwp4jl2HQ6RAeGiR4+OAwpE8bJb8zc/jMOFkgEn5P3qz1fdFOg7ROnfqCPPCOLLOq3tOH+fz5c3iLDsaSgVjB'.
758: 'rEiJpffOrk6f88jja8J2VlamSmfac05f1uaCy6f+BYBxe1LPg4SYjNiyfgZez8jtTmbkXaUV9RTa9ALNcf6JIyPcbW7HK08vBDkZrlprMHBAkNznb5vnY+KYaFwuvoU/7zgrlzeR'.
759: 'p7GxHM5OsSCJtm3bhrHj1OCDz1HOTqeqHSuWFXXk8GH8esMGWTFK4vXV0dnnX/v2de9c8gyG54GBge7t6nZJtDMU9+jD1zgq3XjmPnXqFB6ZP18gTi/lk8zafnv37vVs7G7qpPX3'.
760: 'ZAd9t7V75hkTh2Hp7ARVRwflHfac+kYbhpH3dNid+OvvH0ZQAOckBx5fPBEbLFPxq/nJMFP+mZQQg7b2drFnOCdJHBJkFMb2Ugi92+12FTucDrdMinZzPciUc0yJ1epV7/Ks76sv'.
761: 'vxSIjWk6hbTlFouY10nwng0vmJ6NAQHda/dx+lfKyeMEe8LcB7s+8KBmV699hEEorGnXJm0+L5YPs31AL6vN41B44w6FOad7yxG1dxDyo4U2kgdtsDyAkUMGotXmVoQlLVEoQafT'.
762: 'iTYdJEgrIcXDZ60UPgPkcceNjBI7iGVQSsH5qeDaNZUMywhtaXf4iBEj5Gc6TuCZLVvUSnG5xNhl5eXda1m9Gh0d9j5dyag9Sf3OIIdBw4ULF8R5qrTEijEJiV6bTduPQUSnIv9E'.
763: 'RkXhwQcf6jHEe24c7h0zTUEGLJgZj6yzJZ796TYU2QBrF0/G7Kkj0NzSClnV9KN06eraVnxyolCERFOQ0X0jEBSAFeYk8jy7WwaFUtgzvDYKhaj2jg6V8qIIQc2aNQvZ2dki8V+5'.
764: 'ckVV7/Ksj71MotjY4QRe2sXzsaNHcfzYMdU8zz//J8QnjPHh3d56WrZ8uTAS0/79+/Hi1m1eeUzbL0sBeiSAMZvQZO/AgXfxPbiipglf5dxU5RkmJ4W8xBGRaGltFR7hq29e4S3s'.
765: '+DwfdxraqL1LcKDRgKfXzyIvc1HodIp2fdnZop0mni1ZukwOO58eOKCG3C54jc1Kk2SDj2kNBoPPOrmPgviC2DxvnnhmSJ+bmyPKvGTu49q0DBf65kltFOLeO3gFkYNCRA7S0msf'.
766: 'X8SLG2YSLNd71X1+2oqz+RWqstHDBmELnbdCQ4zCuMpdI9HWrVspdGjzoMOtYI2VIiIjYDbPw4kTx0UIamxoUNVzH1YcX/0wXbp0CUm0e5lmzJyByZMnCc+VPELqo81KvvTEyl2y'.
767: 'ZClyyJM55/Eve7c0F9dr++3Zs0dcdSmJ04FvO7ju7UktdAjd/lGuyC0l5XUCgg8KNaljc4MNxy5879X3/cyrOErlfJCV2JI2Hi//YT5MBKpaODyqdk23UjhU2ii/Kdlud7jbasIZ'.
768: 'l6WZzfIO/pJAgraevz3JNySnT8seFhERidjhcQgbONCrjxcI8OFJLnFHaMLiJUvkMxrfmvfmSRw5tGtjdOfTBuiDJ310vBBl1U0YHDnAHQqMeoLNHXg4NR6nc7+X2x2/cIMQXDQS'.
769: 'hrsvSfO+q8YX2T+oxkqIi6Rc4MCOz3IISXXH38fmj/PyJA4d/N1IG1qYvYAByc836IsWL6GD6icCFmvr09LSxWcL6dD6/nvvYhEplr/OeoEET5++5KQuafz0dJyh8e+SBynn7/Lh'.
770: 'SUUEMji3KonlCFYciL2BQw8x88BXxfi26DZiY8JQeaeZDqAmNLZ04KXfmckYg1BaXgtr2V25/Ssf5eCNZx+mfKPD259dVl0Fidtta7VgLfGFbHNLi8pKyjONRPzJgD1GpU+F/Cmp'.
771: 'qcIQVVWVXvX8yWPtuvU0bob7rEfI8ZoGPWr7aL9O+NKT+xzk8lztrMbuD3b1WC/R31991Wuc5557HrFxcf/djcMpAgn7ThWJBG8tq0fUoGDKR2146tEUJMaF425DIx57ZCyFLYM8'.
772: 'YIvNgbc+zceNigbcrGoUl7N9Yf4c4T6V955g+aLXVzul3Ct93IFJdSmpKXjyyY0+7/K0h9Te5vF1o8A8cdJE8bX4p9w46D1r87pxYATNnyoSPXdSSvrLrmykJI/ApaIqCnWhaKYQ'.
773: 'NyE+BptWPYA7tXUyXLz+Qz2+KaiB3elCOx1oOZytmDsWe49dpdBo6NNN7/vblqGWwkRNTTX0vbSLjomBTm8QIcXpsMtw2qGBrhXlZQRiAnusNxJ642ukGzduwGG3y4bhz+VjE8cK'.
774: 'eN7e3qGaR5pbOX5IyACEE2jhHCORso+yXimTL/IlJ1Ml9WMj3R05Oj6cP5apdi0peEBwiIinep1e/uVbA0ZZqjMUJc7AgAAvtNKbUGoY36nOI/0kE9/Ss2Uy6+tqn4gZrP7L1S6y'.
775: 'foOjqU8D2Qh62jxXLmro3t6v5Z9BfI9ot3c0sJFeamluXqXX68PDwyMoNhr6tXOfGOh2jQBZz+g8d16j+IxFbOY/wOgn/xJf9HY6nTfZQBaLJUunrPT88f7UfjX5nRr4f1NIL/8R'.
776: 'YABtitvxQEn6dgAAAABJRU5ErkJggg==';
777: $output .= '<div style="display:block;float:none;margin-left:275px; width: 150px; display:inline-block"><img style="display:block;float:none;" src="data:image/png;base64,'.$imgData.'"><br />';
778: $output .= '<a style="display:block;float:none; padding:0; color: #6A6AA8;font-family:monospace;font-weight:bold; text-decoration:none;" href="javascript:void(0);" onclick="showHidePhpInfo(this);">[ + phpinfo()]</a></div><br /><br />';
779: $output .= "<div id=\"phpInfoContent\" class=\"hidden\"><div style=\"font-family:monospace;text-align:center\">PHP_SAPI == \"".
780: PHP_SAPI."\"</div><br />$phpInfoContent</div>";
781: $output .= '
782: <script type="text/javascript">
783: function showHidePhpInfo(elt) {
784: var content = document.getElementById("phpInfoContent");
785: if (content.getAttribute("class") == "hidden") {
786: elt.innerHTML = "[ - phpinfo()]";
787: content.setAttribute("class","");
788: } else {
789: elt.innerHTML = "[ + phpinfo()]";
790: content.setAttribute("class","hidden");
791: }
792: }
793: </script>';
794: }
795:
796:
797:
798:
799: if(!$returnArray){
800: echo strtr($document, array(
801: '{headerContent}' => $phpInfoStyle,
802: '{bodyContent}' => $output
803: ));
804: $responding = true;
805: restore_error_handler();
806: restore_exception_handler();
807: }else{
808: return compact('requirements','reqMessages','canInstall','hasMessages');
809: }
810: ?>
811: