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_client_connector_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 "bug53632" => "Not_recommended_PHP_versions",
00117
00118 );
00119
00125 public function __construct()
00126 {
00127 }
00128
00134 public function getRequiredModules()
00135 {
00136 if ( $this->_aRequiredModules == null ) {
00137 $aRequiredPHPExtensions = array(
00138 'php_version',
00139 'lib_xml2',
00140 'php_xml',
00141 'j_son',
00142 'i_conv',
00143 'tokenizer',
00144 'mysql_connect',
00145 'gd_info',
00146 'mb_string',
00147 'curl',
00148 'bc_math',
00149 'open_ssl',
00150 'soap',
00151 );
00152
00153 $aRequiredPHPConfigs = array(
00154 'allow_url_fopen',
00155 'php4_compat',
00156 'request_uri',
00157 'ini_set',
00158 'register_globals',
00159 'memory_limit',
00160 'unicode_support'
00161 );
00162
00163 $aRequiredServerConfigs = array(
00164 'mod_rewrite',
00165 'server_permissions',
00166 'bug53632'
00167 );
00168
00169
00170 if ( isAdmin() ) {
00171 $aRequiredServerConfigs[] = 'mysql_version';
00172 }
00173 $this->_aRequiredModules = array_fill_keys( $aRequiredPHPExtensions, 'php_extennsions' ) +
00174 array_fill_keys( $aRequiredPHPConfigs, 'php_config' ) +
00175 array_fill_keys( $aRequiredServerConfigs, 'server_config' );
00176 }
00177 return $this->_aRequiredModules;
00178 }
00179
00188 public function checkBug53632()
00189 {
00190 $iState = 1;
00191 if ( version_compare( PHP_VERSION, "5.3", ">=" ) ) {
00192 if ( version_compare( PHP_VERSION, "5.3.5", ">=" ) && version_compare( PHP_VERSION, "5.3.7", "!=" ) ) {
00193 $iState = 2;
00194 }
00195 } elseif ( version_compare( PHP_VERSION, '5.2', ">=" ) ) {
00196 $iState = version_compare( PHP_VERSION, "5.2.17", ">=" ) ? 2 : $iState;
00197 }
00198 return $iState;
00199 }
00200
00206 public function checkCurl()
00207 {
00208 return extension_loaded( 'curl' ) ? 2 : 1;
00209 }
00210
00216 public function checkMbString()
00217 {
00218 return extension_loaded( 'mbstring' ) ? 2 : 1;
00219 }
00220
00229 public function checkServerPermissions( $sPath = null, $iMinPerm = 777 )
00230 {
00231 $sVerPrefix = '';
00232
00233 clearstatcache();
00234 $sPath = $sPath ? $sPath : getShopBasePath();
00235
00236
00237 $sFullPath = $sPath . "config.inc.php";
00238 if ( !is_readable( $sFullPath ) ||
00239 ( isAdmin() && is_writable( $sFullPath ) ) ||
00240 ( !isAdmin() && !is_writable( $sFullPath ) )
00241 ) {
00242 return 0;
00243 }
00244
00245 $sTmp = "$sPath/tmp$sVerPrefix/";
00246 if (class_exists('oxConfig')) {
00247 $sCfgTmp = oxConfig::getInstance()->getConfigParam('sCompileDir');
00248 if (strpos($sCfgTmp, '<sCompileDir_') === false) {
00249 $sTmp = $sCfgTmp;
00250 }
00251 }
00252
00253 $aPathsToCheck = array(
00254 $sPath."out/pictures{$sVerPrefix}/promo/",
00255 $sPath."out/pictures{$sVerPrefix}/media/",
00256 $sPath."out/pictures{$sVerPrefix}/master/",
00257 $sPath."out/pictures{$sVerPrefix}/generated/",
00258 $sPath."log/",
00259 $sTmp
00260 );
00261 $iModStat = 2;
00262 $sPathToCheck = reset( $aPathsToCheck );
00263 while ( $sPathToCheck ) {
00264
00265 if ( !file_exists( $sPathToCheck ) ) {
00266 $iModStat = 0;
00267 break;
00268 }
00269
00270 if ( is_dir( $sPathToCheck ) ) {
00271
00272 $aSubF = glob( $sPathToCheck."*", GLOB_ONLYDIR );
00273 if (is_array($aSubF)) {
00274 foreach ( $aSubF as $sNewFolder ) {
00275 $aPathsToCheck[] = $sNewFolder . "/";
00276 }
00277 }
00278 }
00279
00280
00281
00282 if ( !is_readable( $sPathToCheck ) || !is_writable( $sPathToCheck ) ) {
00283 $iModStat = 0;
00284 break;
00285 }
00286
00287 $sPathToCheck = next( $aPathsToCheck );
00288 }
00289
00290 return $iModStat;
00291 }
00292
00299 protected function _getShopHostInfoFromConfig()
00300 {
00301 $sShopURL = oxConfig::getInstance()->getConfigParam( 'sShopURL' );
00302 if (preg_match('#^(https?://)?([^/:]+)(:([0-9]+))?(/.*)?$#i', $sShopURL, $m)) {
00303 $sHost = $m[2];
00304 $iPort = (int)$m[4];
00305 $blSsl = (strtolower($m[1])=='https://');
00306 if (!$iPort) {
00307 $iPort = $blSsl?443:80;
00308 }
00309 $sScript = rtrim($m[5], '/').'/';
00310 return array(
00311 'host'=>$sHost,
00312 'port'=>$iPort,
00313 'dir'=>$sScript,
00314 'ssl'=>$blSsl,
00315 );
00316 } else {
00317 return false;
00318 }
00319 }
00320
00327 protected function _getShopHostInfoFromServerVars()
00328 {
00329
00330 $sScript = $_SERVER['SCRIPT_NAME'];
00331 $iPort = (int) $_SERVER['SERVER_PORT'];
00332 $blSsl = (isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on'));
00333 if (!$iPort) {
00334 $iPort = $blSsl?443:80;
00335 }
00336 $sScript = rtrim(dirname(dirname( $sScript )), '/').'/';
00337 return array(
00338 'host'=>$_SERVER['HTTP_HOST'],
00339 'port'=>$iPort,
00340 'dir'=>$sScript,
00341 'ssl'=>$blSsl,
00342 );
00343 }
00344
00350 protected function _getShopHostInfo()
00351 {
00352 if ( isAdmin() ) {
00353 return $this->_getShopHostInfoFromConfig();
00354 } else {
00355 return $this->_getShopHostInfoFromServerVars();
00356 }
00357 }
00358
00364 public function checkModRewrite()
00365 {
00366 $iModStat = null;
00367 if ( ($aHostInfo = $this->_getShopHostInfo()) && $rFp = @fsockopen( ($aHostInfo['ssl']?'ssl://':'').$aHostInfo['host'], $aHostInfo['port'], $iErrNo, $sErrStr, 10 ) ) {
00368 $sReq = "POST {$aHostInfo['dir']}oxseo.php?mod_rewrite_module_is=off HTTP/1.1\r\n";
00369 $sReq .= "Host: {$aHostInfo['host']}\r\n";
00370 $sReq .= "User-Agent: OXID eShop setup\r\n";
00371 $sReq .= "Content-Type: application/x-www-form-urlencoded\r\n";
00372 $sReq .= "Content-Length: 0\r\n";
00373 $sReq .= "Connection: close\r\n\r\n";
00374
00375 $sOut = '';
00376 fwrite( $rFp, $sReq );
00377 while ( !feof( $rFp ) ) {
00378 $sOut .= fgets( $rFp, 100 );
00379 }
00380 fclose( $rFp );
00381
00382 $iModStat = ( strpos( $sOut, 'mod_rewrite_on' ) !== false ) ? 2 : 0;
00383 } else {
00384 if ( function_exists( 'apache_get_modules' ) ) {
00385
00386 $iModStat = in_array( 'mod_rewrite', apache_get_modules() ) ? 1 : 0;
00387 } else {
00388 $iModStat = -1;
00389 }
00390 }
00391 return $iModStat;
00392 }
00393
00399 public function checkAllowUrlFopen()
00400 {
00401 $iModStat = @ini_get('allow_url_fopen');
00402 $iModStat = ( $iModStat && strcasecmp( '1', $iModStat ) ) ? 2 : 1;
00403 if ( $iModStat == 1 ) {
00404 $iErrNo = 0;
00405 $sErrStr = '';
00406 if ( $oRes = @fsockopen( 'www.example.com', 80, $iErrNo, $sErrStr, 10 ) ) {
00407 $iModStat = 2;
00408 fclose( $oRes );
00409 }
00410 }
00411 $iModStat = ( !$iModStat ) ? 1 : $iModStat;
00412 return $iModStat;
00413 }
00414
00421 public function checkPhp4Compat()
00422 {
00423 $sZendStatus = ( strtolower( (string) @ini_get( 'zend.ze1_compatibility_mode' ) ) );
00424 return in_array( $sZendStatus, array( 'on', '1' ) ) ? 0 : 2;
00425 }
00426
00433 public function checkPhpVersion()
00434 {
00435 $iModStat = ( version_compare( PHP_VERSION, '5.1', '>' ) ) ? 1 : 0;
00436 $iModStat = ( $iModStat == 0 ) ? $iModStat : ( version_compare( PHP_VERSION, '5.2', '>=' ) ? 2 : 1 );
00437 return $iModStat;
00438 }
00439
00445 public function checkRequestUri()
00446 {
00447 return ( isset( $_SERVER['REQUEST_URI'] ) || isset( $_SERVER['SCRIPT_URI'] ) ) ? 2 : 0;
00448 }
00449
00455 public function checkLibXml2()
00456 {
00457 return class_exists( 'DOMDocument' ) ? 2 : 0;
00458 }
00459
00465 public function checkPhpXml()
00466 {
00467 return class_exists( 'DOMDocument' ) ? 2 : 0;
00468 }
00469
00475 public function checkJSon()
00476 {
00477 return extension_loaded( 'json' ) ? 2 : 0;
00478 }
00479
00485 public function checkIConv()
00486 {
00487 return extension_loaded( 'iconv' ) ? 2 : 0;
00488 }
00489
00495 public function checkTokenizer()
00496 {
00497 return extension_loaded( 'tokenizer' ) ? 2 : 0;
00498 }
00499
00505 public function checkBcMath()
00506 {
00507 return extension_loaded( 'bcmath' ) ? 2 : 1;
00508 }
00509
00515 public function checkOpenSsl()
00516 {
00517 return extension_loaded( 'openssl' ) ? 2 : 1;
00518 }
00519
00525 public function checkSoap()
00526 {
00527 return extension_loaded( 'soap' ) ? 2 : 1;
00528 }
00529
00535 public function checkMysqlConnect()
00536 {
00537
00538 $iModStat = ( extension_loaded( 'mysql' ) || extension_loaded( 'mysqli' ) || extension_loaded( 'pdo_mysql' ) ) ? 2 : 0;
00539
00540 if ( $iModStat ) {
00541 $sClientVersion = mysql_get_client_info();
00542 if (version_compare( $sClientVersion, '5', '<' )) {
00543 $iModStat = 1;
00544 if (version_compare( $sClientVersion, '4', '<' )) {
00545 $iModStat = 0;
00546 }
00547 } elseif (version_compare($sClientVersion, '5.0.36', '>=') && version_compare($sClientVersion, '5.0.38', '<')) {
00548
00549 $iModStat = 0;
00550 } elseif (version_compare($sClientVersion, '5.0.40', '>') && version_compare($sClientVersion, '5.0.42', '<')) {
00551
00552 $iModStat = 0;
00553 }
00554 if (strpos($sClientVersion, 'mysqlnd') !== false) {
00555
00556 $iModStat = 2;
00557 }
00558 }
00559 return $iModStat;
00560 }
00561
00569 public function checkMysqlVersion( $sVersion = null )
00570 {
00571 if ( $sVersion === null ) {
00572 $aRez = oxDb::getDb()->getAll( "SHOW VARIABLES LIKE 'version'" );
00573 foreach ( $aRez as $aRecord ) {
00574 $sVersion = $aRecord[1];
00575 break;
00576 }
00577 }
00578
00579 $iModStat = 0;
00580 if ( version_compare( $sVersion, '5.0.3', '>=' ) && version_compare( $sVersion, '5.0.37', '<>' ) ) {
00581 $iModStat = 2;
00582 }
00583
00584 return $iModStat;
00585 }
00586
00592 public function checkGdInfo()
00593 {
00594 $iModStat = extension_loaded( 'gd' ) ? 1 : 0;
00595 $iModStat = function_exists( 'imagecreatetruecolor' ) ? 2 : $iModStat;
00596 $iModStat = function_exists( 'imagecreatefromjpeg' ) ? $iModStat : 0;
00597 return $iModStat;
00598 }
00599
00605 public function checkIniSet()
00606 {
00607 return ( @ini_set('session.name', 'sid' ) !== false ) ? 2 : 0;
00608 }
00609
00615 public function checkRegisterGlobals()
00616 {
00617 $sGlobStatus = ( strtolower( (string) @ini_get( 'register_globals' ) ) );
00618 return in_array( $sGlobStatus, array( 'on', '1' ) ) ? 0 : 2;
00619 }
00620
00626 public function checkMemoryLimit()
00627 {
00628 if ( $sMemLimit = @ini_get('memory_limit') ) {
00629
00630 $sDefLimit = '14M';
00631 $sRecLimit = '30M';
00632
00633
00634 $iMemLimit = $this->_getBytes( $sMemLimit );
00635 $iModStat = ( $iMemLimit >= $this->_getBytes( $sDefLimit ) ) ? 1 : 0;
00636 $iModStat = $iModStat ? ( ( $iMemLimit >= $this->_getBytes( $sRecLimit ) ) ? 2 : $iModStat ) : $iModStat;
00637
00638 } else {
00639 $iModStat = -1;
00640 }
00641 return $iModStat;
00642 }
00643
00649 public function checkZendOptimizer()
00650 {
00655 return 2;
00656 }
00657
00663 public function checkZendPlatformOrServer()
00664 {
00665 if (function_exists( 'output_cache_get' )) {
00666 return 2;
00667 }
00668 if (function_exists( 'zend_disk_cache_fetch' )) {
00669 return 2;
00670 }
00671 if (function_exists( 'zend_shm_cache_fetch' )) {
00672 return 2;
00673 }
00674 return 1;
00675 }
00676
00682 protected function _getAdditionalCheck()
00683 {
00684 $sSelect = '';
00685 foreach ( $this->_aException as $sTable => $sColumn ) {
00686 $sSelect .= 'and ( t.TABLE_NAME != "'.$sTable.'" and c.COLUMN_NAME != "'.$sColumn.'" ) ';
00687 }
00688 return $sSelect;
00689 }
00690
00696 public function checkCollation()
00697 {
00698 $myConfig = oxConfig::getInstance();
00699
00700 $aCollations = array();
00701 $sCollation = '';
00702
00703 $sSelect = 'select t.TABLE_NAME, c.COLUMN_NAME, c.COLLATION_NAME from INFORMATION_SCHEMA.tables t ' .
00704 'LEFT JOIN INFORMATION_SCHEMA.columns c ON t.TABLE_NAME = c.TABLE_NAME ' .
00705 'where t.TABLE_SCHEMA = "'.$myConfig->getConfigParam( 'dbName' ).'" ' .
00706 'and c.TABLE_SCHEMA = "'.$myConfig->getConfigParam( 'dbName' ).'" ' .
00707 'and c.COLUMN_NAME in ("'.implode('", "', $this->_aColumns).'") ' . $this->_getAdditionalCheck() .
00708 ' ORDER BY (t.TABLE_NAME = "oxarticles") DESC';
00709 $aRez = oxDb::getDb()->getAll($sSelect);
00710 foreach ( $aRez as $aRetTable ) {
00711 if ( !$sCollation ) {
00712 $sCollation = $aRetTable[2];
00713 } else {
00714 if ( $aRetTable[2] && $sCollation != $aRetTable[2]) {
00715 $aCollations[$aRetTable[0]][$aRetTable[1]] = $aRetTable[2];
00716 }
00717 }
00718 }
00719
00720 if ( $this->_blSysReqStatus === null ) {
00721 $this->_blSysReqStatus = true;
00722 }
00723 if ( count($aCollations) > 0 ) {
00724 $this->_blSysReqStatus = false;
00725 }
00726 return $aCollations;
00727 }
00728
00734 public function checkDatabaseCluster()
00735 {
00736 return 2;
00737 }
00738
00744 public function checkUnicodeSupport()
00745 {
00746 return (@preg_match('/\pL/u', 'a') == 1) ? 2 : 1;
00747 }
00748
00754 public function getSysReqStatus()
00755 {
00756 if ( $this->_blSysReqStatus == null ) {
00757 $this->_blSysReqStatus = true;
00758 $this->getSystemInfo();
00759 $this->checkCollation();
00760 }
00761 return $this->_blSysReqStatus;
00762 }
00763
00778 public function getSystemInfo()
00779 {
00780 $aSysInfo = array();
00781 $aRequiredModules = $this->getRequiredModules();
00782 $this->_blSysReqStatus = true;
00783 foreach ( $aRequiredModules as $sModule => $sGroup ) {
00784 if ( isset($aSysInfo[$sGroup]) && !$aSysInfo[$sGroup] ) {
00785 $aSysInfo[$sGroup] = array();
00786 }
00787 $iModuleState = $this->getModuleInfo( $sModule );
00788 $aSysInfo[$sGroup][$sModule] = $iModuleState;
00789 $this->_blSysReqStatus = $this->_blSysReqStatus && ( bool ) abs( $iModuleState );
00790 }
00791 return $aSysInfo;
00792 }
00793
00801 public function getModuleInfo( $sModule = null )
00802 {
00803 if ( $sModule ) {
00804 $iModStat = null;
00805 $sCheckFunction = "check".str_replace(" ", "", ucwords(str_replace("_", " ", $sModule)));
00806 $iModStat = $this->$sCheckFunction();
00807
00808 return $iModStat;
00809 }
00810 }
00811
00819 public function getReqInfoUrl( $sIdent)
00820 {
00821 $sUrl = $this->_sReqInfoUrl;
00822 $aInfoMap = $this->_aInfoMap;
00823
00824
00825 if ( isset( $aInfoMap[$sIdent] ) ) {
00826 $sUrl .= "#".$aInfoMap[$sIdent];
00827 }
00828
00829 return $sUrl;
00830 }
00831
00839 protected function _getBytes( $sBytes )
00840 {
00841 $sBytes = trim( $sBytes );
00842 $sLast = strtolower($sBytes[strlen($sBytes)-1]);
00843 switch( $sLast ) {
00844
00845 case 'g':
00846 $sBytes *= 1024;
00847 case 'm':
00848 $sBytes *= 1024;
00849 case 'k':
00850 $sBytes *= 1024;
00851 break;
00852 }
00853
00854 return $sBytes;
00855 }
00856
00867 protected function _checkTemplateBlock($sTemplate, $sBlockName)
00868 {
00869 $oConfig = oxConfig::getInstance();
00870
00871 $sTplFile = $oConfig->getTemplatePath($sTemplate, false);
00872 if (!$sTplFile || !file_exists($sTplFile)) {
00873 return false;
00874 }
00875
00876 $sFile = file_get_contents($sTplFile);
00877 $sBlockNameQuoted = preg_quote($sBlockName, '/');
00878 return (bool)preg_match('/\[\{\s*block\s+name\s*=\s*([\'"])'.$sBlockNameQuoted.'\1\s*\}\]/is', $sFile);
00879 }
00880
00890 public function getMissingTemplateBlocks()
00891 {
00892 $aCache = array();
00893 $oConfig = oxConfig::getInstance();
00894
00895 $sShpIdParam = oxDb::getDb()->quote($oConfig->getShopId());
00896 $sSql = "select * from oxtplblocks where oxactive=1 and oxshopid=$sShpIdParam";
00897 $rs = oxDb::getDb(true)->execute($sSql);
00898 $aRet = array();
00899 if ($rs != false && $rs->recordCount() > 0) {
00900 while (!$rs->EOF) {
00901 $blStatus = false;
00902 if (isset($aCache[$rs->fields['OXTEMPLATE']]) && isset($aCache[$rs->fields['OXTEMPLATE']][$rs->fields['OXBLOCKNAME']])) {
00903 $blStatus = $aCache[$rs->fields['OXTEMPLATE']][$rs->fields['OXBLOCKNAME']];
00904 } else {
00905 $blStatus = $this->_checkTemplateBlock($rs->fields['OXTEMPLATE'], $rs->fields['OXBLOCKNAME']);
00906 $aCache[$rs->fields['OXTEMPLATE']][$rs->fields['OXBLOCKNAME']] = $blStatus;
00907 }
00908
00909 if (!$blStatus) {
00910 $aRet[] = array(
00911 'module' => $rs->fields['OXMODULE'],
00912 'block' => $rs->fields['OXBLOCKNAME'],
00913 'template' => $rs->fields['OXTEMPLATE'],
00914 );
00915 }
00916 $rs->moveNext();
00917 }
00918 }
00919
00920 return $aRet;
00921 }
00922 }