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
00273 protected function _getShopHostInfoFromConfig()
00274 {
00275 $sShopURL = oxConfig::getInstance()->getConfigParam( 'sShopURL' );
00276 if (preg_match('#^(https?://)?([^/:]+)(:([0-9]+))?(/.*)?$#i', $sShopURL, $m)) {
00277 $sHost = $m[2];
00278 $iPort = (int)$m[4];
00279 $blSsl = (strtolower($m[1])=='https://');
00280 if (!$iPort) {
00281 $iPort = $blSsl?443:80;
00282 }
00283 $sScript = rtrim($m[5], '/').'/';
00284 return array(
00285 'host'=>$sHost,
00286 'port'=>$iPort,
00287 'dir'=>$sScript,
00288 'ssl'=>$blSsl,
00289 );
00290 } else {
00291 return false;
00292 }
00293 }
00294
00301 protected function _getShopHostInfoFromServerVars()
00302 {
00303
00304 $sScript = $_SERVER['SCRIPT_NAME'];
00305 $iPort = (int) $_SERVER['SERVER_PORT'];
00306 $blSsl = (isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on'));
00307 if (!$iPort) {
00308 $iPort = $blSsl?443:80;
00309 }
00310 $sScript = rtrim(dirname(dirname( $sScript )), '/').'/';
00311 return array(
00312 'host'=>$_SERVER['HTTP_HOST'],
00313 'port'=>$iPort,
00314 'dir'=>$sScript,
00315 'ssl'=>$blSsl,
00316 );
00317 }
00318
00324 protected function _getShopHostInfo()
00325 {
00326 if ( isAdmin() ) {
00327 return $this->_getShopHostInfoFromConfig();
00328 } else {
00329 return $this->_getShopHostInfoFromServerVars();
00330 }
00331 }
00332
00338 public function checkModRewrite()
00339 {
00340 $iModStat = null;
00341 if ( ($aHostInfo = $this->_getShopHostInfo()) && $rFp = @fsockopen( ($aHostInfo['ssl']?'ssl://':'').$aHostInfo['host'], $aHostInfo['port'], $iErrNo, $sErrStr, 10 ) ) {
00342 $sReq = "POST {$aHostInfo['dir']}oxseo.php?mod_rewrite_module_is=off HTTP/1.1\r\n";
00343 $sReq .= "Host: {$aHostInfo['host']}\r\n";
00344 $sReq .= "User-Agent: OXID eShop setup\r\n";
00345 $sReq .= "Content-Type: application/x-www-form-urlencoded\r\n";
00346 $sReq .= "Content-Length: 0\r\n";
00347 $sReq .= "Connection: close\r\n\r\n";
00348
00349 $sOut = '';
00350 fwrite( $rFp, $sReq );
00351 while ( !feof( $rFp ) ) {
00352 $sOut .= fgets( $rFp, 100 );
00353 }
00354 fclose( $rFp );
00355
00356 $iModStat = ( strpos( $sOut, 'mod_rewrite_on' ) !== false ) ? 2 : 0;
00357 } else {
00358 if ( function_exists( 'apache_get_modules' ) ) {
00359
00360 $iModStat = in_array( 'mod_rewrite', apache_get_modules() ) ? 1 : 0;
00361 } else {
00362 $iModStat = -1;
00363 }
00364 }
00365 return $iModStat;
00366 }
00367
00373 public function checkAllowUrlFopen()
00374 {
00375 $iModStat = @ini_get('allow_url_fopen');
00376 $iModStat = ( $iModStat && strcasecmp( '1', $iModStat ) ) ? 2 : 1;
00377 if ( $iModStat == 1 ) {
00378 $iErrNo = 0;
00379 $sErrStr = '';
00380 if ( $oRes = @fsockopen( 'www.example.com', 80, $iErrNo, $sErrStr, 10 ) ) {
00381 $iModStat = 2;
00382 fclose( $oRes );
00383 }
00384 }
00385 $iModStat = ( !$iModStat ) ? 1 : $iModStat;
00386 return $iModStat;
00387 }
00388
00395 public function checkPhp4Compat()
00396 {
00397 $sZendStatus = ( strtolower( (string) @ini_get( 'zend.ze1_compatibility_mode' ) ) );
00398 return in_array( $sZendStatus, array( 'on', '1' ) ) ? 0 : 2;
00399 }
00400
00407 public function checkPhpVersion()
00408 {
00409 $iModStat = ( version_compare( PHP_VERSION, '5.1', '>' ) ) ? 1 : 0;
00410 $iModStat = ( $iModStat == 0 ) ? $iModStat : ( version_compare( PHP_VERSION, '5.2', '>=' ) ? 2 : 1 );
00411 return $iModStat;
00412 }
00413
00419 public function checkRequestUri()
00420 {
00421 return ( isset( $_SERVER['REQUEST_URI'] ) || isset( $_SERVER['SCRIPT_URI'] ) ) ? 2 : 0;
00422 }
00423
00429 public function checkLibXml2()
00430 {
00431 return class_exists( 'DOMDocument' ) ? 2 : 0;
00432 }
00433
00439 public function checkPhpXml()
00440 {
00441 return class_exists( 'DOMDocument' ) ? 2 : 0;
00442 }
00443
00449 public function checkJSon()
00450 {
00451 return extension_loaded( 'json' ) ? 2 : 0;
00452 }
00453
00459 public function checkIConv()
00460 {
00461 return extension_loaded( 'iconv' ) ? 2 : 0;
00462 }
00463
00469 public function checkTokenizer()
00470 {
00471 return extension_loaded( 'tokenizer' ) ? 2 : 0;
00472 }
00473
00479 public function checkBcMath()
00480 {
00481 return extension_loaded( 'bcmath' ) ? 2 : 1;
00482 }
00483
00489 public function checkMysqlConnect()
00490 {
00491
00492 $iModStat = ( extension_loaded( 'mysql' ) || extension_loaded( 'mysqli' ) || extension_loaded( 'pdo_mysql' ) ) ? 2 : 0;
00493
00494 if ( $iModStat ) {
00495 $sClientVersion = mysql_get_client_info();
00496 if (version_compare( $sClientVersion, '5', '<' )) {
00497 $iModStat = 1;
00498 if (version_compare( $sClientVersion, '4', '<' )) {
00499 $iModStat = 0;
00500 }
00501 } elseif (version_compare($sClientVersion, '5.0.36', '>=') && version_compare($sClientVersion, '5.0.38', '<')) {
00502
00503 $iModStat = 0;
00504 } elseif (version_compare($sClientVersion, '5.0.40', '>') && version_compare($sClientVersion, '5.0.42', '<')) {
00505
00506 $iModStat = 0;
00507 }
00508 if (strpos($sClientVersion, 'mysqlnd') !== false) {
00509
00510 $iModStat = 2;
00511 }
00512 }
00513 return $iModStat;
00514 }
00515
00523 public function checkMysqlVersion( $sVersion = null )
00524 {
00525 if ( $sVersion === null ) {
00526 $aRez = oxDb::getDb()->getAll( "SHOW VARIABLES LIKE 'version'" );
00527 foreach ( $aRez as $aRecord ) {
00528 $sVersion = $aRecord[1];
00529 break;
00530 }
00531 }
00532
00533 $iModStat = 0;
00534 if ( version_compare( $sVersion, '5', '>=' ) && version_compare( $sVersion, '5.0.37', '<>' ) ) {
00535 $iModStat = 2;
00536 }
00537
00538 return $iModStat;
00539 }
00540
00546 public function checkGdInfo()
00547 {
00548 $iModStat = extension_loaded( 'gd' ) ? 1 : 0;
00549 $iModStat = function_exists( 'imagecreatetruecolor' ) ? 2 : $iModStat;
00550 $iModStat = function_exists( 'imagecreatefromjpeg' ) ? $iModStat : 0;
00551 return $iModStat;
00552 }
00553
00559 public function checkIniSet()
00560 {
00561 return ( @ini_set('session.name', 'sid' ) !== false ) ? 2 : 0;
00562 }
00563
00569 public function checkRegisterGlobals()
00570 {
00571 $sGlobStatus = ( strtolower( (string) @ini_get( 'register_globals' ) ) );
00572 return in_array( $sGlobStatus, array( 'on', '1' ) ) ? 0 : 2;
00573 }
00574
00580 public function checkMemoryLimit()
00581 {
00582 if ( $sMemLimit = @ini_get('memory_limit') ) {
00583
00584 $sDefLimit = '14M';
00585 $sRecLimit = '30M';
00586
00587
00588 $iMemLimit = $this->_getBytes( $sMemLimit );
00589 $iModStat = ( $iMemLimit >= $this->_getBytes( $sDefLimit ) ) ? 1 : 0;
00590 $iModStat = $iModStat ? ( ( $iMemLimit >= $this->_getBytes( $sRecLimit ) ) ? 2 : $iModStat ) : $iModStat;
00591
00592 } else {
00593 $iModStat = -1;
00594 }
00595 return $iModStat;
00596 }
00597
00603 public function checkZendOptimizer()
00604 {
00609 return 2;
00610 }
00611
00617 public function checkZendPlatformOrServer()
00618 {
00619 if (function_exists( 'output_cache_get' )) {
00620 return 2;
00621 }
00622 if (function_exists( 'zend_disk_cache_fetch' )) {
00623 return 2;
00624 }
00625 if (function_exists( 'zend_shm_cache_fetch' )) {
00626 return 2;
00627 }
00628 return 1;
00629 }
00630
00636 protected function _getAdditionalCheck()
00637 {
00638 $sSelect = '';
00639 foreach ( $this->_aException as $sTable => $sColumn ) {
00640 $sSelect .= 'and ( t.TABLE_NAME != "'.$sTable.'" and c.COLUMN_NAME != "'.$sColumn.'" ) ';
00641 }
00642 return $sSelect;
00643 }
00644
00650 public function checkCollation()
00651 {
00652 $myConfig = oxConfig::getInstance();
00653
00654 $aCollations = array();
00655 $sCollation = '';
00656
00657 $sSelect = 'select t.TABLE_NAME, c.COLUMN_NAME, c.COLLATION_NAME from INFORMATION_SCHEMA.tables t ' .
00658 'LEFT JOIN INFORMATION_SCHEMA.columns c ON t.TABLE_NAME = c.TABLE_NAME ' .
00659 'where t.TABLE_SCHEMA = "'.$myConfig->getConfigParam( 'dbName' ).'" ' .
00660 'and c.TABLE_SCHEMA = "'.$myConfig->getConfigParam( 'dbName' ).'" ' .
00661 'and c.COLUMN_NAME in ("'.implode('", "', $this->_aColumns).'") ' . $this->_getAdditionalCheck() .
00662 ' ORDER BY (t.TABLE_NAME = "oxarticles") DESC';
00663 $aRez = oxDb::getDb()->getAll($sSelect);
00664 foreach ( $aRez as $aRetTable ) {
00665 if ( !$sCollation ) {
00666 $sCollation = $aRetTable[2];
00667 } else {
00668 if ( $aRetTable[2] && $sCollation != $aRetTable[2]) {
00669 $aCollations[$aRetTable[0]][$aRetTable[1]] = $aRetTable[2];
00670 }
00671 }
00672 }
00673
00674 if ( $this->_blSysReqStatus === null ) {
00675 $this->_blSysReqStatus = true;
00676 }
00677 if ( count($aCollations) > 0 ) {
00678 $this->_blSysReqStatus = false;
00679 }
00680 return $aCollations;
00681 }
00682
00688 public function checkDatabaseCluster()
00689 {
00690 return 2;
00691 }
00692
00698 public function checkUnicodeSupport()
00699 {
00700 return (@preg_match('/\pL/u', 'a') == 1) ? 2 : 1;
00701 }
00702
00708 public function getSysReqStatus()
00709 {
00710 if ( $this->_blSysReqStatus == null ) {
00711 $this->_blSysReqStatus = true;
00712 $this->getSystemInfo();
00713 $this->checkCollation();
00714 }
00715 return $this->_blSysReqStatus;
00716 }
00717
00732 public function getSystemInfo()
00733 {
00734 $aSysInfo = array();
00735 $aRequiredModules = $this->getRequiredModules();
00736 $this->_blSysReqStatus = true;
00737 foreach ( $aRequiredModules as $sModule => $sGroup ) {
00738 if ( isset($aSysInfo[$sGroup]) && !$aSysInfo[$sGroup] ) {
00739 $aSysInfo[$sGroup] = array();
00740 }
00741 $iModuleState = $this->getModuleInfo( $sModule );
00742 $aSysInfo[$sGroup][$sModule] = $iModuleState;
00743 $this->_blSysReqStatus = $this->_blSysReqStatus && ( bool ) abs( $iModuleState );
00744 }
00745 return $aSysInfo;
00746 }
00747
00755 public function getModuleInfo( $sModule = null )
00756 {
00757 if ( $sModule ) {
00758 $iModStat = null;
00759 $sCheckFunction = "check".str_replace(" ", "", ucwords(str_replace("_", " ", $sModule)));
00760 $iModStat = $this->$sCheckFunction();
00761
00762 return $iModStat;
00763 }
00764 }
00765
00773 public function getReqInfoUrl( $sIdent)
00774 {
00775 $sUrl = $this->_sReqInfoUrl;
00776 $aInfoMap = $this->_aInfoMap;
00777
00778
00779 if ( isset( $aInfoMap[$sIdent] ) ) {
00780 $sUrl .= "#".$aInfoMap[$sIdent];
00781 }
00782
00783 return $sUrl;
00784 }
00785
00793 protected function _getBytes( $sBytes )
00794 {
00795 $sBytes = trim( $sBytes );
00796 $sLast = strtolower($sBytes[strlen($sBytes)-1]);
00797 switch( $sLast ) {
00798
00799 case 'g':
00800 $sBytes *= 1024;
00801 case 'm':
00802 $sBytes *= 1024;
00803 case 'k':
00804 $sBytes *= 1024;
00805 break;
00806 }
00807
00808 return $sBytes;
00809 }
00810 }