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 $sTheme = 'basic';
00219 $sTmp = "$sPath/tmp$sVerPrefix/";
00220 if (class_exists('oxConfig')) {
00221 $sTheme = oxConfig::getInstance()->getConfigParam('sTheme');
00222 $sCfgTmp = oxConfig::getInstance()->getConfigParam('sCompileDir');
00223 if (strpos($sCfgTmp, '<sCompileDir_') === false) {
00224 $sTmp = $sCfgTmp;
00225 }
00226 }
00227
00228 $aPathsToCheck = array(
00229 $sPath."out/pictures{$sVerPrefix}/",
00230 $sPath."out/media/",
00231 $sPath."out/$sTheme/src/",
00232 $sPath."log/",
00233 $sTmp
00234 );
00235 $iModStat = 2;
00236 $sPathToCheck = reset( $aPathsToCheck );
00237 while ( $sPathToCheck ) {
00238
00239 if ( !file_exists( $sPathToCheck ) ) {
00240 $iModStat = 0;
00241 break;
00242 }
00243
00244 if ( is_dir( $sPathToCheck ) ) {
00245
00246 $aSubF = glob( $sPathToCheck."*", GLOB_ONLYDIR );
00247 if (is_array($aSubF)) {
00248 foreach ( $aSubF as $sNewFolder ) {
00249 $aPathsToCheck[] = $sNewFolder . "/";
00250 }
00251 }
00252 }
00253
00254
00255
00256 if ( !is_readable( $sPathToCheck ) || !is_writable( $sPathToCheck ) ) {
00257 $iModStat = 0;
00258 break;
00259 }
00260
00261 $sPathToCheck = next( $aPathsToCheck );
00262 }
00263
00264 return $iModStat;
00265 }
00266
00272 public function checkModRewrite()
00273 {
00274 $iModStat = null;
00275 $sHost = $_SERVER['HTTP_HOST'];
00276 $sScript = $_SERVER['SCRIPT_NAME'];
00277 if ( $sScript && $rFp = @fsockopen( $sHost, 80, $iErrNo, $sErrStr, 10 ) ) {
00278 if ( isAdmin() ) {
00279 $sScript = oxConfig::getInstance()->getConfigParam( 'sShopURL' ).'oxseo.php?mod_rewrite_module_is=off';
00280 } else {
00281 $sScript = str_replace( basename( $sScript ), '../oxseo.php?mod_rewrite_module_is=off', $sScript );
00282 }
00283
00284 $sReq = "POST $sScript HTTP/1.1\r\n";
00285 $sReq .= "Host: $sHost\r\n";
00286 $sReq .= "User-Agent: oxid setup\r\n";
00287 $sReq .= "Content-Type: application/x-www-form-urlencoded\r\n";
00288 $sReq .= "Content-Length: 0\r\n";
00289 $sReq .= "Connection: close\r\n\r\n";
00290
00291 $sOut = '';
00292 fwrite( $rFp, $sReq );
00293 while ( !feof( $rFp ) ) {
00294 $sOut .= fgets( $rFp, 100 );
00295 }
00296 fclose( $rFp );
00297
00298 $iModStat = ( strpos( $sOut, 'mod_rewrite_on' ) !== false ) ? 2 : 0;
00299 } else {
00300 if ( function_exists( 'apache_get_modules' ) ) {
00301
00302 $iModStat = in_array( 'mod_rewrite', apache_get_modules() ) ? 1 : 0;
00303 } else {
00304 $iModStat = -1;
00305 }
00306 }
00307 return $iModStat;
00308 }
00309
00315 public function checkAllowUrlFopen()
00316 {
00317 $iModStat = @ini_get('allow_url_fopen');
00318 $iModStat = ( $iModStat && strcasecmp( '1', $iModStat ) ) ? 2 : 1;
00319 if ( $iModStat == 1 ) {
00320 $iErrNo = 0;
00321 $sErrStr = '';
00322 if ( $oRes = @fsockopen( 'www.example.com', 80, $iErrNo, $sErrStr, 10 ) ) {
00323 $iModStat = 2;
00324 fclose( $oRes );
00325 }
00326 }
00327 $iModStat = ( !$iModStat ) ? 1 : $iModStat;
00328 return $iModStat;
00329 }
00330
00337 public function checkPhp4Compat()
00338 {
00339 $sZendStatus = ( strtolower( (string) @ini_get( 'zend.ze1_compatibility_mode' ) ) );
00340 return in_array( $sZendStatus, array( 'on', '1' ) ) ? 0 : 2;
00341 }
00342
00349 public function checkPhpVersion()
00350 {
00351 $iModStat = ( version_compare( PHP_VERSION, '5.1', '>' ) ) ? 1 : 0;
00352 $iModStat = ( $iModStat == 0 ) ? $iModStat : ( version_compare( PHP_VERSION, '5.2', '>=' ) ? 2 : 1 );
00353 return $iModStat;
00354 }
00355
00361 public function checkRequestUri()
00362 {
00363 return ( isset( $_SERVER['REQUEST_URI'] ) || isset( $_SERVER['SCRIPT_URI'] ) ) ? 2 : 0;
00364 }
00365
00371 public function checkLibXml2()
00372 {
00373 return class_exists( 'DOMDocument' ) ? 2 : 0;
00374 }
00375
00381 public function checkPhpXml()
00382 {
00383 return class_exists( 'DOMDocument' ) ? 2 : 0;
00384 }
00385
00391 public function checkJSon()
00392 {
00393 return extension_loaded( 'json' ) ? 2 : 0;
00394 }
00395
00401 public function checkIConv()
00402 {
00403 return extension_loaded( 'iconv' ) ? 2 : 0;
00404 }
00405
00411 public function checkTokenizer()
00412 {
00413 return extension_loaded( 'tokenizer' ) ? 2 : 0;
00414 }
00415
00421 public function checkBcMath()
00422 {
00423 return extension_loaded( 'bcmath' ) ? 2 : 1;
00424 }
00425
00431 public function checkMysqlConnect()
00432 {
00433
00434 $iModStat = ( extension_loaded( 'mysql' ) || extension_loaded( 'mysqli' ) || extension_loaded( 'pdo_mysql' ) ) ? 2 : 0;
00435
00436 if ( $iModStat ) {
00437 $sClientVersion = mysql_get_client_info();
00438 if (version_compare( $sClientVersion, '5', '<' )) {
00439 $iModStat = 1;
00440 if (version_compare( $sClientVersion, '4', '<' )) {
00441 $iModStat = 0;
00442 }
00443 } elseif (version_compare($sClientVersion, '5.0.36', '>=') && version_compare($sClientVersion, '5.0.38', '<')) {
00444
00445 $iModStat = 0;
00446 } elseif (version_compare($sClientVersion, '5.0.40', '>') && version_compare($sClientVersion, '5.0.42', '<')) {
00447
00448 $iModStat = 0;
00449 }
00450 if (strpos($sClientVersion, 'mysqlnd') !== false) {
00451
00452 $iModStat = 2;
00453 }
00454 }
00455 return $iModStat;
00456 }
00457
00465 public function checkMysqlVersion( $sVersion = null )
00466 {
00467 if ( $sVersion === null ) {
00468 $aRez = oxDb::getDb()->getAll( "SHOW VARIABLES LIKE 'version'" );
00469 foreach ( $aRez as $aRecord ) {
00470 $sVersion = $aRecord[1];
00471 break;
00472 }
00473 }
00474
00475 $iModStat = 0;
00476 if ( version_compare( $sVersion, '5', '>=' ) && version_compare( $sVersion, '5.0.37', '<>' ) ) {
00477 $iModStat = 2;
00478 }
00479
00480 return $iModStat;
00481 }
00482
00488 public function checkGdInfo()
00489 {
00490 $iModStat = extension_loaded( 'gd' ) ? 1 : 0;
00491 $iModStat = function_exists( 'imagecreatetruecolor' ) ? 2 : $iModStat;
00492 $iModStat = function_exists( 'imagecreatefromjpeg' ) ? $iModStat : 0;
00493 return $iModStat;
00494 }
00495
00501 public function checkIniSet()
00502 {
00503 return ( @ini_set('session.name', 'sid' ) !== false ) ? 2 : 0;
00504 }
00505
00511 public function checkRegisterGlobals()
00512 {
00513 $sGlobStatus = ( strtolower( (string) @ini_get( 'register_globals' ) ) );
00514 return in_array( $sGlobStatus, array( 'on', '1' ) ) ? 0 : 2;
00515 }
00516
00522 public function checkMemoryLimit()
00523 {
00524 if ( $sMemLimit = @ini_get('memory_limit') ) {
00525
00526 $sDefLimit = '14M';
00527 $sRecLimit = '30M';
00528
00529
00530 $iMemLimit = $this->_getBytes( $sMemLimit );
00531 $iModStat = ( $iMemLimit >= $this->_getBytes( $sDefLimit ) ) ? 1 : 0;
00532 $iModStat = $iModStat ? ( ( $iMemLimit >= $this->_getBytes( $sRecLimit ) ) ? 2 : $iModStat ) : $iModStat;
00533
00534 } else {
00535 $iModStat = -1;
00536 }
00537 return $iModStat;
00538 }
00539
00545 public function checkZendOptimizer()
00546 {
00547 $iMinStat = 0;
00548 $iModStat = (extension_loaded( 'Zend Optimizer' ) || (function_exists('zend_loader_enabled') && zend_loader_enabled())) ? 2 : $iMinStat;
00549 $sHost = $_SERVER['HTTP_HOST'];
00550 $sScript = $_SERVER['SCRIPT_NAME'];
00551 if ( $iModStat > $iMinStat && $sScript && $rFp = @fsockopen( $sHost, 80, $iErrNo, $sErrStr, 10 ) ) {
00552 $sScript = str_replace( basename($sScript), '../admin/index.php', $sScript );
00553
00554 $sReq = "POST $sScript HTTP/1.1\r\n";
00555 $sReq .= "Host: $sHost\r\n";
00556 $sReq .= "User-Agent: oxid setup\r\n";
00557 $sReq .= "Content-Type: application/x-www-form-urlencoded\r\n";
00558 $sReq .= "Content-Length: 0\r\n";
00559 $sReq .= "Connection: close\r\n\r\n";
00560
00561 $sOut = '';
00562 fwrite( $rFp, $sReq );
00563 while ( !feof( $rFp ) ) {
00564 $sOut .= fgets( $rFp, 100 );
00565 }
00566
00567 $iModStat = ( strpos( $sOut, 'Zend Optimizer not installed' ) !== false ) ? $iMinStat : 2;
00568 fclose( $rFp );
00569 }
00570 if ( $iModStat > $iMinStat && $sScript && $rFp = @fsockopen( $sHost, 80, $iErrNo, $sErrStr, 10 ) ) {
00571 $sScript = str_replace( basename($sScript), '../index.php', $sScript );
00572
00573 $sReq = "POST $sScript HTTP/1.1\r\n";
00574 $sReq .= "Host: $sHost\r\n";
00575 $sReq .= "User-Agent: oxid setup\r\n";
00576 $sReq .= "Content-Type: application/x-www-form-urlencoded\r\n";
00577 $sReq .= "Content-Length: 0\r\n";
00578 $sReq .= "Connection: close\r\n\r\n";
00579
00580 $sOut = '';
00581 fwrite( $rFp, $sReq );
00582 while ( !feof( $rFp ) ) {
00583 $sOut .= fgets( $rFp, 100 );
00584 }
00585 $iModStat = ( strpos( $sOut, 'Zend Optimizer not installed' ) !== false ) ? $iMinStat : 2;
00586 fclose( $rFp );
00587 }
00588 return $iModStat;
00589 }
00590
00596 public function checkZendPlatformOrServer()
00597 {
00598 if (function_exists( 'output_cache_get' )) {
00599 return 2;
00600 }
00601 if (function_exists( 'zend_disk_cache_fetch' )) {
00602 return 2;
00603 }
00604 if (function_exists( 'zend_shm_cache_fetch' )) {
00605 return 2;
00606 }
00607 return 1;
00608 }
00609
00615 protected function _getAdditionalCheck()
00616 {
00617 $sSelect = '';
00618 foreach ( $this->_aException as $sTable => $sColumn ) {
00619 $sSelect .= 'and ( t.TABLE_NAME != "'.$sTable.'" and c.COLUMN_NAME != "'.$sColumn.'" ) ';
00620 }
00621 return $sSelect;
00622 }
00623
00629 public function checkCollation()
00630 {
00631 $myConfig = oxConfig::getInstance();
00632
00633 $aCollations = array();
00634 $sCollation = '';
00635
00636 $sSelect = 'select t.TABLE_NAME, c.COLUMN_NAME, c.COLLATION_NAME from INFORMATION_SCHEMA.tables t ' .
00637 'LEFT JOIN INFORMATION_SCHEMA.columns c ON t.TABLE_NAME = c.TABLE_NAME ' .
00638 'where t.TABLE_SCHEMA = "'.$myConfig->getConfigParam( 'dbName' ).'" ' .
00639 'and c.TABLE_SCHEMA = "'.$myConfig->getConfigParam( 'dbName' ).'" ' .
00640 'and c.COLUMN_NAME in ("'.implode('", "', $this->_aColumns).'") ' . $this->_getAdditionalCheck() .
00641 ' ORDER BY (t.TABLE_NAME = "oxarticles") DESC';
00642 $aRez = oxDb::getDb()->getAll($sSelect);
00643 foreach ( $aRez as $aRetTable ) {
00644 if ( !$sCollation ) {
00645 $sCollation = $aRetTable[2];
00646 } else {
00647 if ( $aRetTable[2] && $sCollation != $aRetTable[2]) {
00648 $aCollations[$aRetTable[0]][$aRetTable[1]] = $aRetTable[2];
00649 }
00650 }
00651 }
00652
00653 if ( $this->_blSysReqStatus === null ) {
00654 $this->_blSysReqStatus = true;
00655 }
00656 if ( count($aCollations) > 0 ) {
00657 $this->_blSysReqStatus = false;
00658 }
00659 return $aCollations;
00660 }
00661
00667 public function checkDatabaseCluster()
00668 {
00669 return 2;
00670 }
00671
00677 public function checkUnicodeSupport()
00678 {
00679 return (@preg_match('/\pL/u', 'a') == 1) ? 2 : 1;
00680 }
00681
00687 public function getSysReqStatus()
00688 {
00689 if ( $this->_blSysReqStatus == null ) {
00690 $this->_blSysReqStatus = true;
00691 $this->getSystemInfo();
00692 $this->checkCollation();
00693 }
00694 return $this->_blSysReqStatus;
00695 }
00696
00711 public function getSystemInfo()
00712 {
00713 $aSysInfo = array();
00714 $aRequiredModules = $this->getRequiredModules();
00715 $this->_blSysReqStatus = true;
00716 foreach ( $aRequiredModules as $sModule => $sGroup ) {
00717 if ( isset($aSysInfo[$sGroup]) && !$aSysInfo[$sGroup] ) {
00718 $aSysInfo[$sGroup] = array();
00719 }
00720 $iModuleState = $this->getModuleInfo( $sModule );
00721 $aSysInfo[$sGroup][$sModule] = $iModuleState;
00722 $this->_blSysReqStatus = $this->_blSysReqStatus && ( bool ) abs( $iModuleState );
00723 }
00724 return $aSysInfo;
00725 }
00726
00734 public function getModuleInfo( $sModule = null )
00735 {
00736 if ( $sModule ) {
00737 $iModStat = null;
00738 $sCheckFunction = "check".str_replace(" ", "", ucwords(str_replace("_", " ", $sModule)));
00739 $iModStat = $this->$sCheckFunction();
00740
00741 return $iModStat;
00742 }
00743 }
00744
00752 public function getReqInfoUrl( $sIdent)
00753 {
00754 $sUrl = $this->_sReqInfoUrl;
00755 $aInfoMap = $this->_aInfoMap;
00756
00757
00758 if ( isset( $aInfoMap[$sIdent] ) ) {
00759 $sUrl .= "#".$aInfoMap[$sIdent];
00760 }
00761
00762 return $sUrl;
00763 }
00764
00772 protected function _getBytes( $sBytes )
00773 {
00774 $sBytes = trim( $sBytes );
00775 $sLast = strtolower($sBytes[strlen($sBytes)-1]);
00776 switch( $sLast ) {
00777
00778 case 'g':
00779 $sBytes *= 1024;
00780 case 'm':
00781 $sBytes *= 1024;
00782 case 'k':
00783 $sBytes *= 1024;
00784 break;
00785 }
00786
00787 return $sBytes;
00788 }
00789 }