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 if ( isAdmin() ) {
00272 $sScript = oxConfig::getInstance()->getConfigParam( 'sShopURL' ).'oxseo.php?mod_rewrite_module_is=off';
00273 } else {
00274 $sScript = str_replace( basename( $sScript ), '../oxseo.php?mod_rewrite_module_is=off', $sScript );
00275 }
00276
00277 $sReq = "POST $sScript HTTP/1.1\r\n";
00278 $sReq .= "Host: $sHost\r\n";
00279 $sReq .= "User-Agent: oxid setup\r\n";
00280 $sReq .= "Content-Type: application/x-www-form-urlencoded\r\n";
00281 $sReq .= "Content-Length: 0\r\n";
00282 $sReq .= "Connection: close\r\n\r\n";
00283
00284 $sOut = '';
00285 fwrite( $rFp, $sReq );
00286 while ( !feof( $rFp ) ) {
00287 $sOut .= fgets( $rFp, 100 );
00288 }
00289 fclose( $rFp );
00290
00291 $iModStat = ( strpos( $sOut, 'mod_rewrite_on' ) !== false ) ? 2 : 0;
00292 } else {
00293 if ( function_exists( 'apache_get_modules' ) ) {
00294
00295 $iModStat = in_array( 'mod_rewrite', apache_get_modules() ) ? 1 : 0;
00296 } else {
00297 $iModStat = -1;
00298 }
00299 }
00300 return $iModStat;
00301 }
00302
00308 public function checkAllowUrlFopen()
00309 {
00310 $iModStat = @ini_get('allow_url_fopen');
00311 $iModStat = ( $iModStat && strcasecmp( '1', $iModStat ) ) ? 2 : 1;
00312 if ( $iModStat == 1 ) {
00313 $iErrNo = 0;
00314 $sErrStr = '';
00315 if ( $oRes = @fsockopen( 'www.example.com', 80, $iErrNo, $sErrStr, 10 ) ) {
00316 $iModStat = 2;
00317 fclose( $oRes );
00318 }
00319 }
00320 $iModStat = ( !$iModStat ) ? 1 : $iModStat;
00321 return $iModStat;
00322 }
00323
00330 public function checkPhp4Compat()
00331 {
00332 $sZendStatus = ( strtolower( (string) @ini_get( 'zend.ze1_compatibility_mode' ) ) );
00333 return in_array( $sZendStatus, array( 'on', '1' ) ) ? 0 : 2;
00334 }
00335
00342 public function checkPhpVersion()
00343 {
00344 $iModStat = ( version_compare( PHP_VERSION, '5.1', '>' ) ) ? 1 : 0;
00345 $iModStat = ( $iModStat == 0 ) ? $iModStat : ( version_compare( PHP_VERSION, '5.2', '>=' ) ? 2 : 1 );
00346 return $iModStat;
00347 }
00348
00354 public function checkRequestUri()
00355 {
00356 return ( isset( $_SERVER['REQUEST_URI'] ) || isset( $_SERVER['SCRIPT_URI'] ) ) ? 2 : 0;
00357 }
00358
00364 public function checkLibXml2()
00365 {
00366 return class_exists( 'DOMDocument' ) ? 2 : 0;
00367 }
00368
00374 public function checkPhpXml()
00375 {
00376 return class_exists( 'DOMDocument' ) ? 2 : 0;
00377 }
00378
00384 public function checkJSon()
00385 {
00386 return extension_loaded( 'json' ) ? 2 : 0;
00387 }
00388
00394 public function checkIConv()
00395 {
00396 return extension_loaded( 'iconv' ) ? 2 : 0;
00397 }
00398
00404 public function checkTokenizer()
00405 {
00406 return extension_loaded( 'tokenizer' ) ? 2 : 0;
00407 }
00408
00414 public function checkBcMath()
00415 {
00416 return extension_loaded( 'bcmath' ) ? 2 : 1;
00417 }
00418
00424 public function checkMysqlConnect()
00425 {
00426
00427 $iModStat = ( extension_loaded( 'mysql' ) || extension_loaded( 'mysqli' ) || extension_loaded( 'pdo_mysql' ) ) ? 2 : 0;
00428
00429 if ( $iModStat ) {
00430 $sClientVersion = mysql_get_client_info();
00431 if (version_compare( $sClientVersion, '5', '<' )) {
00432 $iModStat = 1;
00433 if (version_compare( $sClientVersion, '4', '<' )) {
00434 $iModStat = 0;
00435 }
00436 } elseif (version_compare($sClientVersion, '5.0.36', '>=') && version_compare($sClientVersion, '5.0.38', '<')) {
00437
00438 $iModStat = 0;
00439 } elseif (version_compare($sClientVersion, '5.0.40', '>') && version_compare($sClientVersion, '5.0.42', '<')) {
00440
00441 $iModStat = 0;
00442 }
00443 if (strpos($sClientVersion, 'mysqlnd') !== false) {
00444
00445 $iModStat = 2;
00446 }
00447 }
00448 return $iModStat;
00449 }
00450
00458 public function checkMysqlVersion( $sVersion = null )
00459 {
00460 if ( $sVersion === null ) {
00461 $aRez = oxDb::getDb()->getAll( "SHOW VARIABLES LIKE 'version'" );
00462 foreach ( $aRez as $aRecord ) {
00463 $sVersion = $aRecord[1];
00464 break;
00465 }
00466 }
00467
00468 $iModStat = 0;
00469 if ( version_compare( $sVersion, '5', '>=' ) && version_compare( $sVersion, '5.0.37', '<>' ) ) {
00470 $iModStat = 2;
00471 }
00472
00473 return $iModStat;
00474 }
00475
00481 public function checkGdInfo()
00482 {
00483 $iModStat = extension_loaded( 'gd' ) ? 1 : 0;
00484 $iModStat = function_exists( 'imagecreatetruecolor' ) ? 2 : $iModStat;
00485 $iModStat = function_exists( 'imagecreatefromjpeg' ) ? $iModStat : 0;
00486 return $iModStat;
00487 }
00488
00494 public function checkIniSet()
00495 {
00496 return ( @ini_set('session.name', 'sid' ) !== false ) ? 2 : 0;
00497 }
00498
00504 public function checkRegisterGlobals()
00505 {
00506 $sGlobStatus = ( strtolower( (string) @ini_get( 'register_globals' ) ) );
00507 return in_array( $sGlobStatus, array( 'on', '1' ) ) ? 0 : 2;
00508 }
00509
00515 public function checkMemoryLimit()
00516 {
00517 if ( $sMemLimit = @ini_get('memory_limit') ) {
00518
00519 $sDefLimit = '14M';
00520 $sRecLimit = '30M';
00521
00522
00523 $iMemLimit = $this->_getBytes( $sMemLimit );
00524 $iModStat = ( $iMemLimit >= $this->_getBytes( $sDefLimit ) ) ? 1 : 0;
00525 $iModStat = $iModStat ? ( ( $iMemLimit >= $this->_getBytes( $sRecLimit ) ) ? 2 : $iModStat ) : $iModStat;
00526
00527 } else {
00528 $iModStat = -1;
00529 }
00530 return $iModStat;
00531 }
00532
00538 public function checkZendOptimizer()
00539 {
00540 $iMinStat = 0;
00541 $iModStat = (extension_loaded( 'Zend Optimizer' ) || (function_exists('zend_loader_enabled') && zend_loader_enabled())) ? 2 : $iMinStat;
00542 $sHost = $_SERVER['HTTP_HOST'];
00543 $sScript = $_SERVER['SCRIPT_NAME'];
00544 if ( $iModStat > $iMinStat && $sScript && $rFp = @fsockopen( $sHost, 80, $iErrNo, $sErrStr, 10 ) ) {
00545 $sScript = str_replace( basename($sScript), '../admin/index.php', $sScript );
00546
00547 $sReq = "POST $sScript HTTP/1.1\r\n";
00548 $sReq .= "Host: $sHost\r\n";
00549 $sReq .= "User-Agent: oxid setup\r\n";
00550 $sReq .= "Content-Type: application/x-www-form-urlencoded\r\n";
00551 $sReq .= "Content-Length: 0\r\n";
00552 $sReq .= "Connection: close\r\n\r\n";
00553
00554 $sOut = '';
00555 fwrite( $rFp, $sReq );
00556 while ( !feof( $rFp ) ) {
00557 $sOut .= fgets( $rFp, 100 );
00558 }
00559
00560 $iModStat = ( strpos( $sOut, 'Zend Optimizer not installed' ) !== false ) ? $iMinStat : 2;
00561 fclose( $rFp );
00562 }
00563 if ( $iModStat > $iMinStat && $sScript && $rFp = @fsockopen( $sHost, 80, $iErrNo, $sErrStr, 10 ) ) {
00564 $sScript = str_replace( basename($sScript), '../index.php', $sScript );
00565
00566 $sReq = "POST $sScript HTTP/1.1\r\n";
00567 $sReq .= "Host: $sHost\r\n";
00568 $sReq .= "User-Agent: oxid setup\r\n";
00569 $sReq .= "Content-Type: application/x-www-form-urlencoded\r\n";
00570 $sReq .= "Content-Length: 0\r\n";
00571 $sReq .= "Connection: close\r\n\r\n";
00572
00573 $sOut = '';
00574 fwrite( $rFp, $sReq );
00575 while ( !feof( $rFp ) ) {
00576 $sOut .= fgets( $rFp, 100 );
00577 }
00578 $iModStat = ( strpos( $sOut, 'Zend Optimizer not installed' ) !== false ) ? $iMinStat : 2;
00579 fclose( $rFp );
00580 }
00581 return $iModStat;
00582 }
00583
00589 public function checkZendPlatformOrServer()
00590 {
00591 if (function_exists( 'output_cache_get' )) {
00592 return 2;
00593 }
00594 if (function_exists( 'zend_disk_cache_fetch' )) {
00595 return 2;
00596 }
00597 if (function_exists( 'zend_shm_cache_fetch' )) {
00598 return 2;
00599 }
00600 return 1;
00601 }
00602
00608 protected function _getAdditionalCheck()
00609 {
00610 $sSelect = '';
00611 foreach ( $this->_aException as $sTable => $sColumn ) {
00612 $sSelect .= 'and ( t.TABLE_NAME != "'.$sTable.'" and c.COLUMN_NAME != "'.$sColumn.'" ) ';
00613 }
00614 return $sSelect;
00615 }
00616
00622 public function checkCollation()
00623 {
00624 $myConfig = oxConfig::getInstance();
00625
00626 $aCollations = array();
00627 $sCollation = '';
00628
00629 $sSelect = 'select t.TABLE_NAME, c.COLUMN_NAME, c.COLLATION_NAME from INFORMATION_SCHEMA.tables t ' .
00630 'LEFT JOIN INFORMATION_SCHEMA.columns c ON t.TABLE_NAME = c.TABLE_NAME ' .
00631 'where t.TABLE_SCHEMA = "'.$myConfig->getConfigParam( 'dbName' ).'" ' .
00632 'and c.TABLE_SCHEMA = "'.$myConfig->getConfigParam( 'dbName' ).'" ' .
00633 'and c.COLUMN_NAME in ("'.implode('", "', $this->_aColumns).'") ' . $this->_getAdditionalCheck() .
00634 ' ORDER BY (t.TABLE_NAME = "oxarticles") DESC';
00635 $aRez = oxDb::getDb()->getAll($sSelect);
00636 foreach ( $aRez as $aRetTable ) {
00637 if ( !$sCollation ) {
00638 $sCollation = $aRetTable[2];
00639 } else {
00640 if ( $aRetTable[2] && $sCollation != $aRetTable[2]) {
00641 $aCollations[$aRetTable[0]][$aRetTable[1]] = $aRetTable[2];
00642 }
00643 }
00644 }
00645
00646 if ( $this->_blSysReqStatus === null ) {
00647 $this->_blSysReqStatus = true;
00648 }
00649 if ( count($aCollations) > 0 ) {
00650 $this->_blSysReqStatus = false;
00651 }
00652 return $aCollations;
00653 }
00654
00660 public function checkDatabaseCluster()
00661 {
00662 return 2;
00663 }
00664
00670 public function checkUnicodeSupport()
00671 {
00672 return (@preg_match('/\pL/u', 'a') == 1) ? 2 : 1;
00673 }
00674
00680 public function getSysReqStatus()
00681 {
00682 if ( $this->_blSysReqStatus == null ) {
00683 $this->_blSysReqStatus = true;
00684 $this->getSystemInfo();
00685 $this->checkCollation();
00686 }
00687 return $this->_blSysReqStatus;
00688 }
00689
00704 public function getSystemInfo()
00705 {
00706 $aSysInfo = array();
00707 $aRequiredModules = $this->getRequiredModules();
00708 $this->_blSysReqStatus = true;
00709 foreach ( $aRequiredModules as $sModule => $sGroup ) {
00710 if ( isset($aSysInfo[$sGroup]) && !$aSysInfo[$sGroup] ) {
00711 $aSysInfo[$sGroup] = array();
00712 }
00713 $iModuleState = $this->getModuleInfo( $sModule );
00714 $aSysInfo[$sGroup][$sModule] = $iModuleState;
00715 $this->_blSysReqStatus = $this->_blSysReqStatus && ( bool ) abs( $iModuleState );
00716 }
00717 return $aSysInfo;
00718 }
00719
00727 public function getModuleInfo( $sModule = null )
00728 {
00729 if ( $sModule ) {
00730 $iModStat = null;
00731 $sCheckFunction = "check".str_replace(" ", "", ucwords(str_replace("_", " ", $sModule)));
00732 $iModStat = $this->$sCheckFunction();
00733
00734 return $iModStat;
00735 }
00736 }
00737
00745 public function getReqInfoUrl( $sIdent)
00746 {
00747 $sUrl = $this->_sReqInfoUrl;
00748 $aInfoMap = $this->_aInfoMap;
00749
00750
00751 if ( isset( $aInfoMap[$sIdent] ) ) {
00752 $sUrl .= "#".$aInfoMap[$sIdent];
00753 }
00754
00755 return $sUrl;
00756 }
00757
00765 protected function _getBytes( $sBytes )
00766 {
00767 $sBytes = trim( $sBytes );
00768 $sLast = strtolower($sBytes[strlen($sBytes)-1]);
00769 switch( $sLast ) {
00770
00771 case 'g':
00772 $sBytes *= 1024;
00773 case 'm':
00774 $sBytes *= 1024;
00775 case 'k':
00776 $sBytes *= 1024;
00777 break;
00778 }
00779
00780 return $sBytes;
00781 }
00782 }