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 );
00146
00147 $aRequiredPHPExtensions[] = 'bc_math';
00148
00149 $aRequiredPHPConfigs = array(
00150 'allow_url_fopen',
00151 'php4_compat',
00152 'request_uri',
00153 'ini_set',
00154 'register_globals',
00155 'memory_limit',
00156 'unicode_support'
00157 );
00158
00159 $aRequiredServerConfigs = array(
00160 'mod_rewrite',
00161 'server_permissions'
00162 );
00163
00164
00165 if ( isAdmin() ) {
00166 $aRequiredServerConfigs[] = 'mysql_version';
00167 }
00168 $this->_aRequiredModules = array_fill_keys( $aRequiredPHPExtensions, 'php_extennsions' ) +
00169 array_fill_keys( $aRequiredPHPConfigs, 'php_config' ) +
00170 array_fill_keys( $aRequiredServerConfigs, 'server_config' );
00171 }
00172 return $this->_aRequiredModules;
00173 }
00174
00180 public function checkCurl()
00181 {
00182 return extension_loaded( 'curl' ) ? 2 : 1;
00183 }
00184
00190 public function checkMbString()
00191 {
00192 return extension_loaded( 'mbstring' ) ? 2 : 1;
00193 }
00194
00203 public function checkServerPermissions( $sPath = null, $iMinPerm = 777 )
00204 {
00205 $sVerPrefix = '';
00206
00207 clearstatcache();
00208 $sPath = $sPath ? $sPath : getShopBasePath();
00209
00210
00211 $sFullPath = $sPath . "config.inc.php";
00212 if ( !is_readable( $sFullPath ) ||
00213 ( isAdmin() && is_writable( $sFullPath ) ) ||
00214 ( !isAdmin() && !is_writable( $sFullPath ) )
00215 ) {
00216 return 0;
00217 }
00218
00219 $aPathsToCheck = array(
00220 "out/pictures{$sVerPrefix}/",
00221 "out/media/",
00222 "out/basic/src/",
00223 "log/",
00224 "tmp{$sVerPrefix}/"
00225 );
00226
00227 $iModStat = 2;
00228 $sPathToCheck = reset( $aPathsToCheck );
00229 while ( $sPathToCheck ) {
00230 $sFullPath = $sPath.$sPathToCheck;
00231
00232
00233 if ( !file_exists( $sFullPath ) ) {
00234 $iModStat = 0;
00235 break;
00236 }
00237
00238 if ( is_dir( $sFullPath ) ) {
00239
00240 $aSubF = glob( $sFullPath."*", GLOB_ONLYDIR );
00241 if (is_array($aSubF)) {
00242 foreach ( $aSubF as $sNewFolder ) {
00243 $aPathsToCheck[] = str_replace( $sPath, "", $sNewFolder ) . "/";
00244 }
00245 }
00246 }
00247
00248
00249
00250 if ( !is_readable( $sFullPath ) || !is_writable( $sFullPath ) ) {
00251 $iModStat = 0;
00252 break;
00253 }
00254
00255 $sPathToCheck = next( $aPathsToCheck );
00256 }
00257
00258 return $iModStat;
00259 }
00260
00266 public function checkModRewrite()
00267 {
00268 $iModStat = null;
00269 $sHost = $_SERVER['HTTP_HOST'];
00270 $sScript = $_SERVER['SCRIPT_NAME'];
00271 if ( $sScript && $rFp = @fsockopen( $sHost, 80, $iErrNo, $sErrStr, 10 ) ) {
00272 $sScript = str_replace( basename($sScript), '../oxseo.php?mod_rewrite_module_is=off', $sScript );
00273
00274 $sReq = "POST $sScript HTTP/1.1\r\n";
00275 $sReq .= "Host: $sHost\r\n";
00276 $sReq .= "User-Agent: oxid setup\r\n";
00277 $sReq .= "Content-Type: application/x-www-form-urlencoded\r\n";
00278 $sReq .= "Content-Length: 0\r\n";
00279 $sReq .= "Connection: close\r\n\r\n";
00280
00281 $sOut = '';
00282 fwrite( $rFp, $sReq );
00283 while ( !feof( $rFp ) ) {
00284 $sOut .= fgets( $rFp, 100 );
00285 }
00286 fclose( $rFp );
00287
00288 $iModStat = ( strpos( $sOut, 'mod_rewrite_on' ) !== false ) ? 2 : 0;
00289 } else {
00290 if ( function_exists( 'apache_get_modules' ) ) {
00291
00292 $iModStat = in_array( 'mod_rewrite', apache_get_modules() ) ? 1 : 0;
00293 } else {
00294 $iModStat = -1;
00295 }
00296 }
00297 return $iModStat;
00298 }
00299
00305 public function checkAllowUrlFopen()
00306 {
00307 $iModStat = @ini_get('allow_url_fopen');
00308 $iModStat = ( $iModStat && strcasecmp( '1', $iModStat ) ) ? 2 : 1;
00309 if ( $iModStat == 1 ) {
00310 $iErrNo = 0;
00311 $sErrStr = '';
00312 if ( $oRes = @fsockopen( 'www.example.com', 80, $iErrNo, $sErrStr, 10 ) ) {
00313 $iModStat = 2;
00314 fclose( $oRes );
00315 }
00316 }
00317 $iModStat = ( !$iModStat ) ? 1 : $iModStat;
00318 return $iModStat;
00319 }
00320
00327 public function checkPhp4Compat()
00328 {
00329 $sZendStatus = ( strtolower( (string) @ini_get( 'zend.ze1_compatibility_mode' ) ) );
00330 return in_array( $sZendStatus, array( 'on', '1' ) ) ? 0 : 2;
00331 }
00332
00339 public function checkPhpVersion()
00340 {
00341 $iModStat = ( version_compare( PHP_VERSION, '5.1', '>' ) ) ? 1 : 0;
00342 $iModStat = ( $iModStat == 0 ) ? $iModStat : ( version_compare( PHP_VERSION, '5.2', '>=' ) ? 2 : 1 );
00343 return $iModStat;
00344 }
00345
00351 public function checkRequestUri()
00352 {
00353 return ( isset( $_SERVER['REQUEST_URI'] ) || isset( $_SERVER['SCRIPT_URI'] ) ) ? 2 : 0;
00354 }
00355
00361 public function checkLibXml2()
00362 {
00363 return class_exists( 'DOMDocument' ) ? 2 : 0;
00364 }
00365
00371 public function checkPhpXml()
00372 {
00373 return class_exists( 'DOMDocument' ) ? 2 : 0;
00374 }
00375
00381 public function checkJSon()
00382 {
00383 return extension_loaded( 'json' ) ? 2 : 0;
00384 }
00385
00391 public function checkIConv()
00392 {
00393 return extension_loaded( 'iconv' ) ? 2 : 0;
00394 }
00395
00401 public function checkTokenizer()
00402 {
00403 return extension_loaded( 'tokenizer' ) ? 2 : 0;
00404 }
00405
00411 public function checkBcMath()
00412 {
00413 return extension_loaded( 'bcmath' ) ? 2 : 1;
00414 }
00415
00421 public function checkMysqlConnect()
00422 {
00423
00424 $iModStat = ( extension_loaded( 'mysql' ) || extension_loaded( 'mysqli' ) || extension_loaded( 'pdo_mysql' ) ) ? 2 : 0;
00425
00426 if ( $iModStat ) {
00427 $sClientVersion = mysql_get_client_info();
00428 if (version_compare( $sClientVersion, '5', '<' )) {
00429 $iModStat = 1;
00430 if (version_compare( $sClientVersion, '4', '<' )) {
00431 $iModStat = 0;
00432 }
00433 } elseif (version_compare($sClientVersion, '5.0.36', '>=') && version_compare($sClientVersion, '5.0.38', '<')) {
00434
00435 $iModStat = 0;
00436 }
00437 if (strpos($sClientVersion, 'mysqlnd') !== false) {
00438
00439 $iModStat = 2;
00440 }
00441 }
00442 return $iModStat;
00443 }
00444
00452 public function checkMysqlVersion( $sVersion = null )
00453 {
00454 if ( $sVersion === null ) {
00455 $aRez = oxDb::getDb()->getAll( "SHOW VARIABLES LIKE 'version'" );
00456 foreach ( $aRez as $aRecord ) {
00457 $sVersion = $aRecord[1];
00458 break;
00459 }
00460 }
00461
00462 $iModStat = 0;
00463 if ( version_compare( $sVersion, '5', '>=' ) && version_compare( $sVersion, '5.0.37', '<>' ) ) {
00464 $iModStat = 2;
00465 }
00466
00467 return $iModStat;
00468 }
00469
00475 public function checkGdInfo()
00476 {
00477 $iModStat = extension_loaded( 'gd' ) ? 1 : 0;
00478 $iModStat = function_exists( 'imagecreatetruecolor' ) ? 2 : $iModStat;
00479 $iModStat = function_exists( 'imagecreatefromjpeg' ) ? $iModStat : 0;
00480 return $iModStat;
00481 }
00482
00488 public function checkIniSet()
00489 {
00490 return ( @ini_set('session.name', 'sid' ) !== false ) ? 2 : 0;
00491 }
00492
00498 public function checkRegisterGlobals()
00499 {
00500 $sGlobStatus = ( strtolower( (string) @ini_get( 'register_globals' ) ) );
00501 return in_array( $sGlobStatus, array( 'on', '1' ) ) ? 0 : 2;
00502 }
00503
00509 public function checkMemoryLimit()
00510 {
00511 if ( $sMemLimit = @ini_get('memory_limit') ) {
00512
00513 $sDefLimit = '14M';
00514 $sRecLimit = '30M';
00515
00516
00517 $iMemLimit = $this->_getBytes( $sMemLimit );
00518 $iModStat = ( $iMemLimit >= $this->_getBytes( $sDefLimit ) ) ? 1 : 0;
00519 $iModStat = $iModStat ? ( ( $iMemLimit >= $this->_getBytes( $sRecLimit ) ) ? 2 : $iModStat ) : $iModStat;
00520
00521 } else {
00522 $iModStat = -1;
00523 }
00524 return $iModStat;
00525 }
00526
00532 public function checkZendOptimizer()
00533 {
00534 $iMinStat = 0;
00535 $iModStat = (extension_loaded( 'Zend Optimizer' ) || (function_exists('zend_loader_enabled') && zend_loader_enabled())) ? 2 : $iMinStat;
00536 $sHost = $_SERVER['HTTP_HOST'];
00537 $sScript = $_SERVER['SCRIPT_NAME'];
00538 if ( $iModStat > $iMinStat && $sScript && $rFp = @fsockopen( $sHost, 80, $iErrNo, $sErrStr, 10 ) ) {
00539 $sScript = str_replace( basename($sScript), '../admin/index.php', $sScript );
00540
00541 $sReq = "POST $sScript HTTP/1.1\r\n";
00542 $sReq .= "Host: $sHost\r\n";
00543 $sReq .= "User-Agent: oxid setup\r\n";
00544 $sReq .= "Content-Type: application/x-www-form-urlencoded\r\n";
00545 $sReq .= "Content-Length: 0\r\n";
00546 $sReq .= "Connection: close\r\n\r\n";
00547
00548 $sOut = '';
00549 fwrite( $rFp, $sReq );
00550 while ( !feof( $rFp ) ) {
00551 $sOut .= fgets( $rFp, 100 );
00552 }
00553
00554 $iModStat = ( strpos( $sOut, 'Zend Optimizer not installed' ) !== false ) ? $iMinStat : 2;
00555 fclose( $rFp );
00556 }
00557 if ( $iModStat > $iMinStat && $sScript && $rFp = @fsockopen( $sHost, 80, $iErrNo, $sErrStr, 10 ) ) {
00558 $sScript = str_replace( basename($sScript), '../index.php', $sScript );
00559
00560 $sReq = "POST $sScript HTTP/1.1\r\n";
00561 $sReq .= "Host: $sHost\r\n";
00562 $sReq .= "User-Agent: oxid setup\r\n";
00563 $sReq .= "Content-Type: application/x-www-form-urlencoded\r\n";
00564 $sReq .= "Content-Length: 0\r\n";
00565 $sReq .= "Connection: close\r\n\r\n";
00566
00567 $sOut = '';
00568 fwrite( $rFp, $sReq );
00569 while ( !feof( $rFp ) ) {
00570 $sOut .= fgets( $rFp, 100 );
00571 }
00572 $iModStat = ( strpos( $sOut, 'Zend Optimizer not installed' ) !== false ) ? $iMinStat : 2;
00573 fclose( $rFp );
00574 }
00575 return $iModStat;
00576 }
00577
00583 public function checkZendPlatformOrServer()
00584 {
00585 if (function_exists( 'output_cache_get' )) {
00586 return 2;
00587 }
00588 if (function_exists( 'zend_disk_cache_fetch' )) {
00589 return 2;
00590 }
00591 if (function_exists( 'zend_shm_cache_fetch' )) {
00592 return 2;
00593 }
00594 return 1;
00595 }
00596
00602 protected function _getAdditionalCheck()
00603 {
00604 $sSelect = '';
00605 foreach ( $this->_aException as $sTable => $sColumn ) {
00606 $sSelect .= 'and ( t.TABLE_NAME != "'.$sTable.'" and c.COLUMN_NAME != "'.$sColumn.'" ) ';
00607 }
00608 return $sSelect;
00609 }
00610
00616 public function checkCollation()
00617 {
00618 $myConfig = oxConfig::getInstance();
00619
00620 $aCollations = array();
00621 $sCollation = '';
00622
00623 $sSelect = 'select t.TABLE_NAME, c.COLUMN_NAME, c.COLLATION_NAME from INFORMATION_SCHEMA.tables t ' .
00624 'LEFT JOIN INFORMATION_SCHEMA.columns c ON t.TABLE_NAME = c.TABLE_NAME ' .
00625 'where t.TABLE_SCHEMA = "'.$myConfig->getConfigParam( 'dbName' ).'" ' .
00626 'and c.TABLE_SCHEMA = "'.$myConfig->getConfigParam( 'dbName' ).'" ' .
00627 'and c.COLUMN_NAME in ("'.implode('", "', $this->_aColumns).'") ' . $this->_getAdditionalCheck() .
00628 ' ORDER BY (t.TABLE_NAME = "oxarticles") DESC';
00629 $aRez = oxDb::getDb()->getAll($sSelect);
00630 foreach ( $aRez as $aRetTable ) {
00631 if ( !$sCollation ) {
00632 $sCollation = $aRetTable[2];
00633 } else {
00634 if ( $aRetTable[2] && $sCollation != $aRetTable[2]) {
00635 $aCollations[$aRetTable[0]][$aRetTable[1]] = $aRetTable[2];
00636 }
00637 }
00638 }
00639
00640 if ( $this->_blSysReqStatus === null ) {
00641 $this->_blSysReqStatus = true;
00642 }
00643 if ( count($aCollations) > 0 ) {
00644 $this->_blSysReqStatus = false;
00645 }
00646 return $aCollations;
00647 }
00648
00654 public function checkDatabaseCluster()
00655 {
00656 return 2;
00657 }
00658
00664 public function checkUnicodeSupport()
00665 {
00666 return (@preg_match('/\pL/u', 'a') == 1) ? 2 : 1;
00667 }
00668
00674 public function getSysReqStatus()
00675 {
00676 if ( $this->_blSysReqStatus == null ) {
00677 $this->_blSysReqStatus = true;
00678 $this->getSystemInfo();
00679 $this->checkCollation();
00680 }
00681 return $this->_blSysReqStatus;
00682 }
00683
00698 public function getSystemInfo()
00699 {
00700 $aSysInfo = array();
00701 $aRequiredModules = $this->getRequiredModules();
00702 $this->_blSysReqStatus = true;
00703 foreach ( $aRequiredModules as $sModule => $sGroup ) {
00704 if ( isset($aSysInfo[$sGroup]) && !$aSysInfo[$sGroup] ) {
00705 $aSysInfo[$sGroup] = array();
00706 }
00707 $iModuleState = $this->getModuleInfo( $sModule );
00708 $aSysInfo[$sGroup][$sModule] = $iModuleState;
00709 $this->_blSysReqStatus = $this->_blSysReqStatus && ( bool ) abs( $iModuleState );
00710 }
00711 return $aSysInfo;
00712 }
00713
00721 public function getModuleInfo( $sModule = null )
00722 {
00723 if ( $sModule ) {
00724 $iModStat = null;
00725 $sCheckFunction = "check".str_replace(" ", "", ucwords(str_replace("_", " ", $sModule)));
00726 $iModStat = $this->$sCheckFunction();
00727
00728 return $iModStat;
00729 }
00730 }
00731
00739 public function getReqInfoUrl( $sIdent)
00740 {
00741 $sUrl = $this->_sReqInfoUrl;
00742 $aInfoMap = $this->_aInfoMap;
00743
00744
00745 if ( isset( $aInfoMap[$sIdent] ) ) {
00746 $sUrl .= "#".$aInfoMap[$sIdent];
00747 }
00748
00749 return $sUrl;
00750 }
00751
00759 protected function _getBytes( $sBytes )
00760 {
00761 $sBytes = trim( $sBytes );
00762 $sLast = strtolower($sBytes[strlen($sBytes)-1]);
00763 switch( $sLast ) {
00764
00765 case 'g':
00766 $sBytes *= 1024;
00767 case 'm':
00768 $sBytes *= 1024;
00769 case 'k':
00770 $sBytes *= 1024;
00771 break;
00772 }
00773
00774 return $sBytes;
00775 }
00776 }