00001 <?php
00002
00006 class oxSysRequirements
00007 {
00013 protected $_aRequiredModules = null;
00014
00020 protected $_blSysReqStatus = null;
00021
00027 protected $_aException = array( 'OXDELIVERY' => 'OXDELTYPE',
00028 'OXSELECTLIST' => 'OXIDENT');
00029
00035 protected $_aColumns = array( 'OXID',
00036 'OXOBJECTID',
00037 'OXARTICLENID',
00038 'OXACTIONID',
00039 'OXARTID',
00040 'OXUSERID',
00041 'OXADDRESSUSERID',
00042 'OXCOUNTRYID',
00043 'OXSESSID',
00044 'OXITMID',
00045 'OXPARENTID',
00046 'OXAMITEMID',
00047 'OXAMTASKID',
00048 'OXVENDORID',
00049 'OXMANUFACTURERID',
00050 'OXROOTID',
00051 'OXATTRID',
00052 'OXCATID',
00053 'OXDELID',
00054 'OXDELSETID',
00055 'OXITMARTID',
00056 'OXFIELDID',
00057 'OXROLEID',
00058 'OXCNID',
00059 'OXANID',
00060 'OXARTICLENID',
00061 'OXCATNID',
00062 'OXDELIVERYID',
00063 'OXDISCOUNTID',
00064 'OXGROUPSID',
00065 'OXLISTID',
00066 'OXPAYMENTID',
00067 'OXDELTYPE',
00068 'OXROLEID',
00069 'OXSELNID',
00070 'OXBILLCOUNTRYID',
00071 'OXDELCOUNTRYID',
00072 'OXPAYMENTID',
00073 'OXCARDID',
00074 'OXPAYID',
00075 'OXIDENT',
00076 'OXDEFCAT',
00077 'OXBASKETID',
00078 'OXPAYMENTSID',
00079 'OXORDERID',
00080 'OXVOUCHERSERIEID');
00081
00087 protected $_sReqInfoUrl = "http://www.oxidforge.org/wiki/Installation";
00088
00094 protected $_aInfoMap = array( "php_version" => "PHP_version_at_least_5.2.0",
00095 "lib_xml2" => "LIB_XML2",
00096 "php_xml" => "DOM",
00097 "j_son" => "JSON",
00098 "i_conv" => "ICONV",
00099 "tokenizer" => "Tokenizer",
00100 "mysql_connect" => "MySQL_module_for_MySQL_5",
00101 "gd_info" => "GDlib_v2_.5Bv1.5D_incl._JPEG_support",
00102 "mb_string" => "mbstring",
00103 "bc_math" => "BCMath",
00104 "allow_url_fopen" => "allow_url_fopen_or_fsockopen_to_port_80",
00105 "php4_compat" => "Zend_compatibility_mode_must_be_off",
00106 "request_uri" => "REQUEST_URI_set",
00107 "ini_set" => "ini_set_allowed",
00108 "register_globals" => "register_globals_must_be_off",
00109 "memory_limit" => "PHP_Memory_limit_.28min._14MB.2C_30MB_recommended.29",
00110 "unicode_support" => "UTF-8_support",
00111 "mod_rewrite" => "apache_mod_rewrite_module",
00112 "server_permissions" => "Files_.26_Folder_Permission_Setup",
00113 "zend_optimizer" => "Zend_Optimizer"
00114
00115 );
00116
00122 public function __construct()
00123 {
00124 }
00125
00131 public function getRequiredModules()
00132 {
00133 if ( $this->_aRequiredModules == null ) {
00134 $aRequiredPHPExtensions = array(
00135 'php_version',
00136 'lib_xml2',
00137 'php_xml',
00138 'j_son',
00139 'i_conv',
00140 'tokenizer',
00141 'mysql_connect',
00142 'gd_info',
00143 'mb_string',
00144 'curl',
00145 'bc_math',
00146 );
00147
00148 $aRequiredPHPConfigs = array(
00149 'allow_url_fopen',
00150 'php4_compat',
00151 'request_uri',
00152 'ini_set',
00153 'register_globals',
00154 'memory_limit',
00155 'unicode_support'
00156 );
00157
00158 $aRequiredServerConfigs = array(
00159 'mod_rewrite',
00160 'server_permissions'
00161 );
00162
00163
00164 if ( isAdmin() ) {
00165 $aRequiredServerConfigs[] = 'mysql_version';
00166 }
00167 $this->_aRequiredModules = array_fill_keys( $aRequiredPHPExtensions, 'php_extennsions' ) +
00168 array_fill_keys( $aRequiredPHPConfigs, 'php_config' ) +
00169 array_fill_keys( $aRequiredServerConfigs, 'server_config' );
00170 }
00171 return $this->_aRequiredModules;
00172 }
00173
00179 public function checkCurl()
00180 {
00181 return extension_loaded( 'curl' ) ? 2 : 1;
00182 }
00183
00189 public function checkMbString()
00190 {
00191 return extension_loaded( 'mbstring' ) ? 2 : 1;
00192 }
00193
00202 public function checkServerPermissions( $sPath = null, $iMinPerm = 777 )
00203 {
00204 $sVerPrefix = '';
00205
00206 clearstatcache();
00207 $sPath = $sPath ? $sPath : getShopBasePath();
00208
00209
00210 $sFullPath = $sPath . "config.inc.php";
00211 if ( !is_readable( $sFullPath ) ||
00212 ( isAdmin() && is_writable( $sFullPath ) ) ||
00213 ( !isAdmin() && !is_writable( $sFullPath ) )
00214 ) {
00215 return 0;
00216 }
00217
00218 $aPathsToCheck = array(
00219 "out/pictures{$sVerPrefix}/",
00220 "out/media/",
00221 "out/basic/src/",
00222 "log/",
00223 "tmp{$sVerPrefix}/"
00224 );
00225
00226 $iModStat = 2;
00227 $sPathToCheck = reset( $aPathsToCheck );
00228 while ( $sPathToCheck ) {
00229 $sFullPath = $sPath.$sPathToCheck;
00230
00231
00232 if ( !file_exists( $sFullPath ) ) {
00233 $iModStat = 0;
00234 break;
00235 }
00236
00237 if ( is_dir( $sFullPath ) ) {
00238
00239 $aSubF = glob( $sFullPath."*", GLOB_ONLYDIR );
00240 if (is_array($aSubF)) {
00241 foreach ( $aSubF as $sNewFolder ) {
00242 $aPathsToCheck[] = str_replace( $sPath, "", $sNewFolder ) . "/";
00243 }
00244 }
00245 }
00246
00247
00248
00249 if ( !is_readable( $sFullPath ) || !is_writable( $sFullPath ) ) {
00250 $iModStat = 0;
00251 break;
00252 }
00253
00254 $sPathToCheck = next( $aPathsToCheck );
00255 }
00256
00257 return $iModStat;
00258 }
00259
00265 public function checkModRewrite()
00266 {
00267 $iModStat = null;
00268 $sHost = $_SERVER['HTTP_HOST'];
00269 $sScript = $_SERVER['SCRIPT_NAME'];
00270 if ( $sScript && $rFp = @fsockopen( $sHost, 80, $iErrNo, $sErrStr, 10 ) ) {
00271 $sScript = str_replace( basename($sScript), '../oxseo.php?mod_rewrite_module_is=off', $sScript );
00272
00273 $sReq = "POST $sScript HTTP/1.1\r\n";
00274 $sReq .= "Host: $sHost\r\n";
00275 $sReq .= "User-Agent: oxid setup\r\n";
00276 $sReq .= "Content-Type: application/x-www-form-urlencoded\r\n";
00277 $sReq .= "Content-Length: 0\r\n";
00278 $sReq .= "Connection: close\r\n\r\n";
00279
00280 $sOut = '';
00281 fwrite( $rFp, $sReq );
00282 while ( !feof( $rFp ) ) {
00283 $sOut .= fgets( $rFp, 100 );
00284 }
00285 fclose( $rFp );
00286
00287 $iModStat = ( strpos( $sOut, 'mod_rewrite_on' ) !== false ) ? 2 : 0;
00288 } else {
00289 if ( function_exists( 'apache_get_modules' ) ) {
00290
00291 $iModStat = in_array( 'mod_rewrite', apache_get_modules() ) ? 1 : 0;
00292 } else {
00293 $iModStat = -1;
00294 }
00295 }
00296 return $iModStat;
00297 }
00298
00304 public function checkAllowUrlFopen()
00305 {
00306 $iModStat = @ini_get('allow_url_fopen');
00307 $iModStat = ( $iModStat && strcasecmp( '1', $iModStat ) ) ? 2 : 1;
00308 if ( $iModStat == 1 ) {
00309 $iErrNo = 0;
00310 $sErrStr = '';
00311 if ( $oRes = @fsockopen( 'www.example.com', 80, $iErrNo, $sErrStr, 10 ) ) {
00312 $iModStat = 2;
00313 fclose( $oRes );
00314 }
00315 }
00316 $iModStat = ( !$iModStat ) ? 1 : $iModStat;
00317 return $iModStat;
00318 }
00319
00326 public function checkPhp4Compat()
00327 {
00328 $sZendStatus = ( strtolower( (string) @ini_get( 'zend.ze1_compatibility_mode' ) ) );
00329 return in_array( $sZendStatus, array( 'on', '1' ) ) ? 0 : 2;
00330 }
00331
00338 public function checkPhpVersion()
00339 {
00340 $iModStat = ( version_compare( PHP_VERSION, '5.1', '>' ) ) ? 1 : 0;
00341 $iModStat = ( $iModStat == 0 ) ? $iModStat : ( version_compare( PHP_VERSION, '5.2', '>=' ) ? 2 : 1 );
00342 return $iModStat;
00343 }
00344
00350 public function checkRequestUri()
00351 {
00352 return ( isset( $_SERVER['REQUEST_URI'] ) || isset( $_SERVER['SCRIPT_URI'] ) ) ? 2 : 0;
00353 }
00354
00360 public function checkLibXml2()
00361 {
00362 return class_exists( 'DOMDocument' ) ? 2 : 0;
00363 }
00364
00370 public function checkPhpXml()
00371 {
00372 return class_exists( 'DOMDocument' ) ? 2 : 0;
00373 }
00374
00380 public function checkJSon()
00381 {
00382 return extension_loaded( 'json' ) ? 2 : 0;
00383 }
00384
00390 public function checkIConv()
00391 {
00392 return extension_loaded( 'iconv' ) ? 2 : 0;
00393 }
00394
00400 public function checkTokenizer()
00401 {
00402 return extension_loaded( 'tokenizer' ) ? 2 : 0;
00403 }
00404
00410 public function checkBcMath()
00411 {
00412 return extension_loaded( 'bcmath' ) ? 2 : 1;
00413 }
00414
00420 public function checkMysqlConnect()
00421 {
00422
00423 $iModStat = ( extension_loaded( 'mysql' ) || extension_loaded( 'mysqli' ) || extension_loaded( 'pdo_mysql' ) ) ? 2 : 0;
00424
00425 if ( $iModStat ) {
00426 $sClientVersion = mysql_get_client_info();
00427 if (version_compare( $sClientVersion, '5', '<' )) {
00428 $iModStat = 1;
00429 if (version_compare( $sClientVersion, '4', '<' )) {
00430 $iModStat = 0;
00431 }
00432 } elseif (version_compare($sClientVersion, '5.0.36', '>=') && version_compare($sClientVersion, '5.0.38', '<')) {
00433
00434 $iModStat = 0;
00435 }
00436 if (strpos($sClientVersion, 'mysqlnd') !== false) {
00437
00438 $iModStat = 2;
00439 }
00440 }
00441 return $iModStat;
00442 }
00443
00451 public function checkMysqlVersion( $sVersion = null )
00452 {
00453 if ( $sVersion === null ) {
00454 $aRez = oxDb::getDb()->getAll( "SHOW VARIABLES LIKE 'version'" );
00455 foreach ( $aRez as $aRecord ) {
00456 $sVersion = $aRecord[1];
00457 break;
00458 }
00459 }
00460
00461 $iModStat = 0;
00462 if ( version_compare( $sVersion, '5', '>=' ) && version_compare( $sVersion, '5.0.37', '<>' ) ) {
00463 $iModStat = 2;
00464 }
00465
00466 return $iModStat;
00467 }
00468
00474 public function checkGdInfo()
00475 {
00476 $iModStat = extension_loaded( 'gd' ) ? 1 : 0;
00477 $iModStat = function_exists( 'imagecreatetruecolor' ) ? 2 : $iModStat;
00478 $iModStat = function_exists( 'imagecreatefromjpeg' ) ? $iModStat : 0;
00479 return $iModStat;
00480 }
00481
00487 public function checkIniSet()
00488 {
00489 return ( @ini_set('session.name', 'sid' ) !== false ) ? 2 : 0;
00490 }
00491
00497 public function checkRegisterGlobals()
00498 {
00499 $sGlobStatus = ( strtolower( (string) @ini_get( 'register_globals' ) ) );
00500 return in_array( $sGlobStatus, array( 'on', '1' ) ) ? 0 : 2;
00501 }
00502
00508 public function checkMemoryLimit()
00509 {
00510 if ( $sMemLimit = @ini_get('memory_limit') ) {
00511
00512 $sDefLimit = '14M';
00513 $sRecLimit = '30M';
00514
00515
00516 $iMemLimit = $this->_getBytes( $sMemLimit );
00517 $iModStat = ( $iMemLimit >= $this->_getBytes( $sDefLimit ) ) ? 1 : 0;
00518 $iModStat = $iModStat ? ( ( $iMemLimit >= $this->_getBytes( $sRecLimit ) ) ? 2 : $iModStat ) : $iModStat;
00519
00520 } else {
00521 $iModStat = -1;
00522 }
00523 return $iModStat;
00524 }
00525
00531 public function checkZendOptimizer()
00532 {
00533 $iMinStat = 0;
00534 $iModStat = (extension_loaded( 'Zend Optimizer' ) || (function_exists('zend_loader_enabled') && zend_loader_enabled())) ? 2 : $iMinStat;
00535 $sHost = $_SERVER['HTTP_HOST'];
00536 $sScript = $_SERVER['SCRIPT_NAME'];
00537 if ( $iModStat > $iMinStat && $sScript && $rFp = @fsockopen( $sHost, 80, $iErrNo, $sErrStr, 10 ) ) {
00538 $sScript = str_replace( basename($sScript), '../admin/index.php', $sScript );
00539
00540 $sReq = "POST $sScript HTTP/1.1\r\n";
00541 $sReq .= "Host: $sHost\r\n";
00542 $sReq .= "User-Agent: oxid setup\r\n";
00543 $sReq .= "Content-Type: application/x-www-form-urlencoded\r\n";
00544 $sReq .= "Content-Length: 0\r\n";
00545 $sReq .= "Connection: close\r\n\r\n";
00546
00547 $sOut = '';
00548 fwrite( $rFp, $sReq );
00549 while ( !feof( $rFp ) ) {
00550 $sOut .= fgets( $rFp, 100 );
00551 }
00552
00553 $iModStat = ( strpos( $sOut, 'Zend Optimizer not installed' ) !== false ) ? $iMinStat : 2;
00554 fclose( $rFp );
00555 }
00556 if ( $iModStat > $iMinStat && $sScript && $rFp = @fsockopen( $sHost, 80, $iErrNo, $sErrStr, 10 ) ) {
00557 $sScript = str_replace( basename($sScript), '../index.php', $sScript );
00558
00559 $sReq = "POST $sScript HTTP/1.1\r\n";
00560 $sReq .= "Host: $sHost\r\n";
00561 $sReq .= "User-Agent: oxid setup\r\n";
00562 $sReq .= "Content-Type: application/x-www-form-urlencoded\r\n";
00563 $sReq .= "Content-Length: 0\r\n";
00564 $sReq .= "Connection: close\r\n\r\n";
00565
00566 $sOut = '';
00567 fwrite( $rFp, $sReq );
00568 while ( !feof( $rFp ) ) {
00569 $sOut .= fgets( $rFp, 100 );
00570 }
00571 $iModStat = ( strpos( $sOut, 'Zend Optimizer not installed' ) !== false ) ? $iMinStat : 2;
00572 fclose( $rFp );
00573 }
00574 return $iModStat;
00575 }
00576
00582 public function checkZendPlatformOrServer()
00583 {
00584 if (function_exists( 'output_cache_get' )) {
00585 return 2;
00586 }
00587 if (function_exists( 'zend_disk_cache_fetch' )) {
00588 return 2;
00589 }
00590 if (function_exists( 'zend_shm_cache_fetch' )) {
00591 return 2;
00592 }
00593 return 1;
00594 }
00595
00601 protected function _getAdditionalCheck()
00602 {
00603 $sSelect = '';
00604 foreach ( $this->_aException as $sTable => $sColumn ) {
00605 $sSelect .= 'and ( t.TABLE_NAME != "'.$sTable.'" and c.COLUMN_NAME != "'.$sColumn.'" ) ';
00606 }
00607 return $sSelect;
00608 }
00609
00615 public function checkCollation()
00616 {
00617 $myConfig = oxConfig::getInstance();
00618
00619 $aCollations = array();
00620 $sCollation = '';
00621
00622 $sSelect = 'select t.TABLE_NAME, c.COLUMN_NAME, c.COLLATION_NAME from INFORMATION_SCHEMA.tables t ' .
00623 'LEFT JOIN INFORMATION_SCHEMA.columns c ON t.TABLE_NAME = c.TABLE_NAME ' .
00624 'where t.TABLE_SCHEMA = "'.$myConfig->getConfigParam( 'dbName' ).'" ' .
00625 'and c.TABLE_SCHEMA = "'.$myConfig->getConfigParam( 'dbName' ).'" ' .
00626 'and c.COLUMN_NAME in ("'.implode('", "', $this->_aColumns).'") ' . $this->_getAdditionalCheck() .
00627 ' ORDER BY (t.TABLE_NAME = "oxarticles") DESC';
00628 $aRez = oxDb::getDb()->getAll($sSelect);
00629 foreach ( $aRez as $aRetTable ) {
00630 if ( !$sCollation ) {
00631 $sCollation = $aRetTable[2];
00632 } else {
00633 if ( $aRetTable[2] && $sCollation != $aRetTable[2]) {
00634 $aCollations[$aRetTable[0]][$aRetTable[1]] = $aRetTable[2];
00635 }
00636 }
00637 }
00638
00639 if ( $this->_blSysReqStatus === null ) {
00640 $this->_blSysReqStatus = true;
00641 }
00642 if ( count($aCollations) > 0 ) {
00643 $this->_blSysReqStatus = false;
00644 }
00645 return $aCollations;
00646 }
00647
00653 public function checkDatabaseCluster()
00654 {
00655 return 2;
00656 }
00657
00663 public function checkUnicodeSupport()
00664 {
00665 return (@preg_match('/\pL/u', 'a') == 1) ? 2 : 1;
00666 }
00667
00673 public function getSysReqStatus()
00674 {
00675 if ( $this->_blSysReqStatus == null ) {
00676 $this->_blSysReqStatus = true;
00677 $this->getSystemInfo();
00678 $this->checkCollation();
00679 }
00680 return $this->_blSysReqStatus;
00681 }
00682
00697 public function getSystemInfo()
00698 {
00699 $aSysInfo = array();
00700 $aRequiredModules = $this->getRequiredModules();
00701 $this->_blSysReqStatus = true;
00702 foreach ( $aRequiredModules as $sModule => $sGroup ) {
00703 if ( isset($aSysInfo[$sGroup]) && !$aSysInfo[$sGroup] ) {
00704 $aSysInfo[$sGroup] = array();
00705 }
00706 $iModuleState = $this->getModuleInfo( $sModule );
00707 $aSysInfo[$sGroup][$sModule] = $iModuleState;
00708 $this->_blSysReqStatus = $this->_blSysReqStatus && ( bool ) abs( $iModuleState );
00709 }
00710 return $aSysInfo;
00711 }
00712
00720 public function getModuleInfo( $sModule = null )
00721 {
00722 if ( $sModule ) {
00723 $iModStat = null;
00724 $sCheckFunction = "check".str_replace(" ", "", ucwords(str_replace("_", " ", $sModule)));
00725 $iModStat = $this->$sCheckFunction();
00726
00727 return $iModStat;
00728 }
00729 }
00730
00738 public function getReqInfoUrl( $sIdent)
00739 {
00740 $sUrl = $this->_sReqInfoUrl;
00741 $aInfoMap = $this->_aInfoMap;
00742
00743
00744 if ( isset( $aInfoMap[$sIdent] ) ) {
00745 $sUrl .= "#".$aInfoMap[$sIdent];
00746 }
00747
00748 return $sUrl;
00749 }
00750
00758 protected function _getBytes( $sBytes )
00759 {
00760 $sBytes = trim( $sBytes );
00761 $sLast = strtolower($sBytes[strlen($sBytes)-1]);
00762 switch( $sLast ) {
00763
00764 case 'g':
00765 $sBytes *= 1024;
00766 case 'm':
00767 $sBytes *= 1024;
00768 case 'k':
00769 $sBytes *= 1024;
00770 break;
00771 }
00772
00773 return $sBytes;
00774 }
00775 }