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 "open_ssl" => "OpenSSL",
00098 "soap" => "SOAP",
00099 "j_son" => "JSON",
00100 "i_conv" => "ICONV",
00101 "tokenizer" => "Tokenizer",
00102 "mysql_connect" => "MySQL_module_for_MySQL_5",
00103 "gd_info" => "GDlib_v2_.5Bv1.5D_incl._JPEG_support",
00104 "mb_string" => "mbstring",
00105 "bc_math" => "BCMath",
00106 "allow_url_fopen" => "allow_url_fopen_or_fsockopen_to_port_80",
00107 "php4_compat" => "Zend_compatibility_mode_must_be_off",
00108 "request_uri" => "REQUEST_URI_set",
00109 "ini_set" => "ini_set_allowed",
00110 "register_globals" => "register_globals_must_be_off",
00111 "memory_limit" => "PHP_Memory_limit_.28min._14MB.2C_30MB_recommended.29",
00112 "unicode_support" => "UTF-8_support",
00113 "mod_rewrite" => "apache_mod_rewrite_module",
00114 "server_permissions" => "Files_.26_Folder_Permission_Setup",
00115 "zend_optimizer" => "Zend_Optimizer"
00116
00117 );
00118
00124 public function __construct()
00125 {
00126 }
00127
00133 public function getRequiredModules()
00134 {
00135 if ( $this->_aRequiredModules == null ) {
00136 $aRequiredPHPExtensions = array(
00137 'php_version',
00138 'lib_xml2',
00139 'php_xml',
00140 'j_son',
00141 'i_conv',
00142 'tokenizer',
00143 'mysql_connect',
00144 'gd_info',
00145 'mb_string',
00146 'curl',
00147 'bc_math',
00148 'open_ssl',
00149 'soap',
00150 );
00151
00152 $aRequiredPHPConfigs = array(
00153 'allow_url_fopen',
00154 'php4_compat',
00155 'request_uri',
00156 'ini_set',
00157 'register_globals',
00158 'memory_limit',
00159 'unicode_support'
00160 );
00161
00162 $aRequiredServerConfigs = array(
00163 'mod_rewrite',
00164 'server_permissions'
00165 );
00166
00167
00168 if ( isAdmin() ) {
00169 $aRequiredServerConfigs[] = 'mysql_version';
00170 }
00171 $this->_aRequiredModules = array_fill_keys( $aRequiredPHPExtensions, 'php_extennsions' ) +
00172 array_fill_keys( $aRequiredPHPConfigs, 'php_config' ) +
00173 array_fill_keys( $aRequiredServerConfigs, 'server_config' );
00174 }
00175 return $this->_aRequiredModules;
00176 }
00177
00183 public function checkCurl()
00184 {
00185 return extension_loaded( 'curl' ) ? 2 : 1;
00186 }
00187
00193 public function checkMbString()
00194 {
00195 return extension_loaded( 'mbstring' ) ? 2 : 1;
00196 }
00197
00206 public function checkServerPermissions( $sPath = null, $iMinPerm = 777 )
00207 {
00208 $sVerPrefix = '';
00209
00210 clearstatcache();
00211 $sPath = $sPath ? $sPath : getShopBasePath();
00212
00213
00214 $sFullPath = $sPath . "config.inc.php";
00215 if ( !is_readable( $sFullPath ) ||
00216 ( isAdmin() && is_writable( $sFullPath ) ) ||
00217 ( !isAdmin() && !is_writable( $sFullPath ) )
00218 ) {
00219 return 0;
00220 }
00221
00222 $sTheme = 'basic';
00223 $sTmp = "$sPath/tmp$sVerPrefix/";
00224 if (class_exists('oxConfig')) {
00225 $sTheme = oxConfig::getInstance()->getConfigParam('sTheme');
00226 $sCfgTmp = oxConfig::getInstance()->getConfigParam('sCompileDir');
00227 if (strpos($sCfgTmp, '<sCompileDir_') === false) {
00228 $sTmp = $sCfgTmp;
00229 }
00230 }
00231
00232 $aPathsToCheck = array(
00233 $sPath."out/pictures{$sVerPrefix}/",
00234 $sPath."out/media/",
00235 $sPath."out/$sTheme/src/",
00236 $sPath."log/",
00237 $sTmp
00238 );
00239 $iModStat = 2;
00240 $sPathToCheck = reset( $aPathsToCheck );
00241 while ( $sPathToCheck ) {
00242
00243 if ( !file_exists( $sPathToCheck ) ) {
00244 $iModStat = 0;
00245 break;
00246 }
00247
00248 if ( is_dir( $sPathToCheck ) ) {
00249
00250 $aSubF = glob( $sPathToCheck."*", GLOB_ONLYDIR );
00251 if (is_array($aSubF)) {
00252 foreach ( $aSubF as $sNewFolder ) {
00253 $aPathsToCheck[] = $sNewFolder . "/";
00254 }
00255 }
00256 }
00257
00258
00259
00260 if ( !is_readable( $sPathToCheck ) || !is_writable( $sPathToCheck ) ) {
00261 $iModStat = 0;
00262 break;
00263 }
00264
00265 $sPathToCheck = next( $aPathsToCheck );
00266 }
00267
00268 return $iModStat;
00269 }
00270
00277 protected function _getShopHostInfoFromConfig()
00278 {
00279 $sShopURL = oxConfig::getInstance()->getConfigParam( 'sShopURL' );
00280 if (preg_match('#^(https?://)?([^/:]+)(:([0-9]+))?(/.*)?$#i', $sShopURL, $m)) {
00281 $sHost = $m[2];
00282 $iPort = (int)$m[4];
00283 $blSsl = (strtolower($m[1])=='https://');
00284 if (!$iPort) {
00285 $iPort = $blSsl?443:80;
00286 }
00287 $sScript = rtrim($m[5], '/').'/';
00288 return array(
00289 'host'=>$sHost,
00290 'port'=>$iPort,
00291 'dir'=>$sScript,
00292 'ssl'=>$blSsl,
00293 );
00294 } else {
00295 return false;
00296 }
00297 }
00298
00305 protected function _getShopHostInfoFromServerVars()
00306 {
00307
00308 $sScript = $_SERVER['SCRIPT_NAME'];
00309 $iPort = (int) $_SERVER['SERVER_PORT'];
00310 $blSsl = (isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on'));
00311 if (!$iPort) {
00312 $iPort = $blSsl?443:80;
00313 }
00314 $sScript = rtrim(dirname(dirname( $sScript )), '/').'/';
00315 return array(
00316 'host'=>$_SERVER['HTTP_HOST'],
00317 'port'=>$iPort,
00318 'dir'=>$sScript,
00319 'ssl'=>$blSsl,
00320 );
00321 }
00322
00328 protected function _getShopHostInfo()
00329 {
00330 if ( isAdmin() ) {
00331 return $this->_getShopHostInfoFromConfig();
00332 } else {
00333 return $this->_getShopHostInfoFromServerVars();
00334 }
00335 }
00336
00342 public function checkModRewrite()
00343 {
00344 $iModStat = null;
00345 if ( ($aHostInfo = $this->_getShopHostInfo()) && $rFp = @fsockopen( ($aHostInfo['ssl']?'ssl://':'').$aHostInfo['host'], $aHostInfo['port'], $iErrNo, $sErrStr, 10 ) ) {
00346 $sReq = "POST {$aHostInfo['dir']}oxseo.php?mod_rewrite_module_is=off HTTP/1.1\r\n";
00347 $sReq .= "Host: {$aHostInfo['host']}\r\n";
00348 $sReq .= "User-Agent: OXID eShop setup\r\n";
00349 $sReq .= "Content-Type: application/x-www-form-urlencoded\r\n";
00350 $sReq .= "Content-Length: 0\r\n";
00351 $sReq .= "Connection: close\r\n\r\n";
00352
00353 $sOut = '';
00354 fwrite( $rFp, $sReq );
00355 while ( !feof( $rFp ) ) {
00356 $sOut .= fgets( $rFp, 100 );
00357 }
00358 fclose( $rFp );
00359
00360 $iModStat = ( strpos( $sOut, 'mod_rewrite_on' ) !== false ) ? 2 : 0;
00361 } else {
00362 if ( function_exists( 'apache_get_modules' ) ) {
00363
00364 $iModStat = in_array( 'mod_rewrite', apache_get_modules() ) ? 1 : 0;
00365 } else {
00366 $iModStat = -1;
00367 }
00368 }
00369 return $iModStat;
00370 }
00371
00377 public function checkAllowUrlFopen()
00378 {
00379 $iModStat = @ini_get('allow_url_fopen');
00380 $iModStat = ( $iModStat && strcasecmp( '1', $iModStat ) ) ? 2 : 1;
00381 if ( $iModStat == 1 ) {
00382 $iErrNo = 0;
00383 $sErrStr = '';
00384 if ( $oRes = @fsockopen( 'www.example.com', 80, $iErrNo, $sErrStr, 10 ) ) {
00385 $iModStat = 2;
00386 fclose( $oRes );
00387 }
00388 }
00389 $iModStat = ( !$iModStat ) ? 1 : $iModStat;
00390 return $iModStat;
00391 }
00392
00399 public function checkPhp4Compat()
00400 {
00401 $sZendStatus = ( strtolower( (string) @ini_get( 'zend.ze1_compatibility_mode' ) ) );
00402 return in_array( $sZendStatus, array( 'on', '1' ) ) ? 0 : 2;
00403 }
00404
00411 public function checkPhpVersion()
00412 {
00413 $iModStat = ( version_compare( PHP_VERSION, '5.1', '>' ) ) ? 1 : 0;
00414 $iModStat = ( $iModStat == 0 ) ? $iModStat : ( version_compare( PHP_VERSION, '5.2', '>=' ) ? 2 : 1 );
00415 return $iModStat;
00416 }
00417
00423 public function checkRequestUri()
00424 {
00425 return ( isset( $_SERVER['REQUEST_URI'] ) || isset( $_SERVER['SCRIPT_URI'] ) ) ? 2 : 0;
00426 }
00427
00433 public function checkLibXml2()
00434 {
00435 return class_exists( 'DOMDocument' ) ? 2 : 0;
00436 }
00437
00443 public function checkPhpXml()
00444 {
00445 return class_exists( 'DOMDocument' ) ? 2 : 0;
00446 }
00447
00453 public function checkJSon()
00454 {
00455 return extension_loaded( 'json' ) ? 2 : 0;
00456 }
00457
00463 public function checkIConv()
00464 {
00465 return extension_loaded( 'iconv' ) ? 2 : 0;
00466 }
00467
00473 public function checkTokenizer()
00474 {
00475 return extension_loaded( 'tokenizer' ) ? 2 : 0;
00476 }
00477
00483 public function checkBcMath()
00484 {
00485 return extension_loaded( 'bcmath' ) ? 2 : 1;
00486 }
00487
00493 public function checkOpenSsl()
00494 {
00495 return extension_loaded( 'openssl' ) ? 2 : 1;
00496 }
00497
00503 public function checkSoap()
00504 {
00505 return extension_loaded( 'soap' ) ? 2 : 1;
00506 }
00507
00513 public function checkMysqlConnect()
00514 {
00515
00516 $iModStat = ( extension_loaded( 'mysql' ) || extension_loaded( 'mysqli' ) || extension_loaded( 'pdo_mysql' ) ) ? 2 : 0;
00517
00518 if ( $iModStat ) {
00519 $sClientVersion = mysql_get_client_info();
00520 if (version_compare( $sClientVersion, '5', '<' )) {
00521 $iModStat = 1;
00522 if (version_compare( $sClientVersion, '4', '<' )) {
00523 $iModStat = 0;
00524 }
00525 } elseif (version_compare($sClientVersion, '5.0.36', '>=') && version_compare($sClientVersion, '5.0.38', '<')) {
00526
00527 $iModStat = 0;
00528 } elseif (version_compare($sClientVersion, '5.0.40', '>') && version_compare($sClientVersion, '5.0.42', '<')) {
00529
00530 $iModStat = 0;
00531 }
00532 if (strpos($sClientVersion, 'mysqlnd') !== false) {
00533
00534 $iModStat = 2;
00535 }
00536 }
00537 return $iModStat;
00538 }
00539
00547 public function checkMysqlVersion( $sVersion = null )
00548 {
00549 if ( $sVersion === null ) {
00550 $aRez = oxDb::getDb()->getAll( "SHOW VARIABLES LIKE 'version'" );
00551 foreach ( $aRez as $aRecord ) {
00552 $sVersion = $aRecord[1];
00553 break;
00554 }
00555 }
00556
00557 $iModStat = 0;
00558 if ( version_compare( $sVersion, '5', '>=' ) && version_compare( $sVersion, '5.0.37', '<>' ) ) {
00559 $iModStat = 2;
00560 }
00561
00562 return $iModStat;
00563 }
00564
00570 public function checkGdInfo()
00571 {
00572 $iModStat = extension_loaded( 'gd' ) ? 1 : 0;
00573 $iModStat = function_exists( 'imagecreatetruecolor' ) ? 2 : $iModStat;
00574 $iModStat = function_exists( 'imagecreatefromjpeg' ) ? $iModStat : 0;
00575 return $iModStat;
00576 }
00577
00583 public function checkIniSet()
00584 {
00585 return ( @ini_set('session.name', 'sid' ) !== false ) ? 2 : 0;
00586 }
00587
00593 public function checkRegisterGlobals()
00594 {
00595 $sGlobStatus = ( strtolower( (string) @ini_get( 'register_globals' ) ) );
00596 return in_array( $sGlobStatus, array( 'on', '1' ) ) ? 0 : 2;
00597 }
00598
00604 public function checkMemoryLimit()
00605 {
00606 if ( $sMemLimit = @ini_get('memory_limit') ) {
00607
00608 $sDefLimit = '14M';
00609 $sRecLimit = '30M';
00610
00611
00612 $iMemLimit = $this->_getBytes( $sMemLimit );
00613 $iModStat = ( $iMemLimit >= $this->_getBytes( $sDefLimit ) ) ? 1 : 0;
00614 $iModStat = $iModStat ? ( ( $iMemLimit >= $this->_getBytes( $sRecLimit ) ) ? 2 : $iModStat ) : $iModStat;
00615
00616 } else {
00617 $iModStat = -1;
00618 }
00619 return $iModStat;
00620 }
00621
00627 public function checkZendOptimizer()
00628 {
00633 return 2;
00634 }
00635
00641 public function checkZendPlatformOrServer()
00642 {
00643 if (function_exists( 'output_cache_get' )) {
00644 return 2;
00645 }
00646 if (function_exists( 'zend_disk_cache_fetch' )) {
00647 return 2;
00648 }
00649 if (function_exists( 'zend_shm_cache_fetch' )) {
00650 return 2;
00651 }
00652 return 1;
00653 }
00654
00660 protected function _getAdditionalCheck()
00661 {
00662 $sSelect = '';
00663 foreach ( $this->_aException as $sTable => $sColumn ) {
00664 $sSelect .= 'and ( t.TABLE_NAME != "'.$sTable.'" and c.COLUMN_NAME != "'.$sColumn.'" ) ';
00665 }
00666 return $sSelect;
00667 }
00668
00674 public function checkCollation()
00675 {
00676 $myConfig = oxConfig::getInstance();
00677
00678 $aCollations = array();
00679 $sCollation = '';
00680
00681 $sSelect = 'select t.TABLE_NAME, c.COLUMN_NAME, c.COLLATION_NAME from INFORMATION_SCHEMA.tables t ' .
00682 'LEFT JOIN INFORMATION_SCHEMA.columns c ON t.TABLE_NAME = c.TABLE_NAME ' .
00683 'where t.TABLE_SCHEMA = "'.$myConfig->getConfigParam( 'dbName' ).'" ' .
00684 'and c.TABLE_SCHEMA = "'.$myConfig->getConfigParam( 'dbName' ).'" ' .
00685 'and c.COLUMN_NAME in ("'.implode('", "', $this->_aColumns).'") ' . $this->_getAdditionalCheck() .
00686 ' ORDER BY (t.TABLE_NAME = "oxarticles") DESC';
00687 $aRez = oxDb::getDb()->getAll($sSelect);
00688 foreach ( $aRez as $aRetTable ) {
00689 if ( !$sCollation ) {
00690 $sCollation = $aRetTable[2];
00691 } else {
00692 if ( $aRetTable[2] && $sCollation != $aRetTable[2]) {
00693 $aCollations[$aRetTable[0]][$aRetTable[1]] = $aRetTable[2];
00694 }
00695 }
00696 }
00697
00698 if ( $this->_blSysReqStatus === null ) {
00699 $this->_blSysReqStatus = true;
00700 }
00701 if ( count($aCollations) > 0 ) {
00702 $this->_blSysReqStatus = false;
00703 }
00704 return $aCollations;
00705 }
00706
00712 public function checkDatabaseCluster()
00713 {
00714 return 2;
00715 }
00716
00722 public function checkUnicodeSupport()
00723 {
00724 return (@preg_match('/\pL/u', 'a') == 1) ? 2 : 1;
00725 }
00726
00732 public function getSysReqStatus()
00733 {
00734 if ( $this->_blSysReqStatus == null ) {
00735 $this->_blSysReqStatus = true;
00736 $this->getSystemInfo();
00737 $this->checkCollation();
00738 }
00739 return $this->_blSysReqStatus;
00740 }
00741
00756 public function getSystemInfo()
00757 {
00758 $aSysInfo = array();
00759 $aRequiredModules = $this->getRequiredModules();
00760 $this->_blSysReqStatus = true;
00761 foreach ( $aRequiredModules as $sModule => $sGroup ) {
00762 if ( isset($aSysInfo[$sGroup]) && !$aSysInfo[$sGroup] ) {
00763 $aSysInfo[$sGroup] = array();
00764 }
00765 $iModuleState = $this->getModuleInfo( $sModule );
00766 $aSysInfo[$sGroup][$sModule] = $iModuleState;
00767 $this->_blSysReqStatus = $this->_blSysReqStatus && ( bool ) abs( $iModuleState );
00768 }
00769 return $aSysInfo;
00770 }
00771
00779 public function getModuleInfo( $sModule = null )
00780 {
00781 if ( $sModule ) {
00782 $iModStat = null;
00783 $sCheckFunction = "check".str_replace(" ", "", ucwords(str_replace("_", " ", $sModule)));
00784 $iModStat = $this->$sCheckFunction();
00785
00786 return $iModStat;
00787 }
00788 }
00789
00797 public function getReqInfoUrl( $sIdent)
00798 {
00799 $sUrl = $this->_sReqInfoUrl;
00800 $aInfoMap = $this->_aInfoMap;
00801
00802
00803 if ( isset( $aInfoMap[$sIdent] ) ) {
00804 $sUrl .= "#".$aInfoMap[$sIdent];
00805 }
00806
00807 return $sUrl;
00808 }
00809
00817 protected function _getBytes( $sBytes )
00818 {
00819 $sBytes = trim( $sBytes );
00820 $sLast = strtolower($sBytes[strlen($sBytes)-1]);
00821 switch( $sLast ) {
00822
00823 case 'g':
00824 $sBytes *= 1024;
00825 case 'm':
00826 $sBytes *= 1024;
00827 case 'k':
00828 $sBytes *= 1024;
00829 break;
00830 }
00831
00832 return $sBytes;
00833 }
00834 }