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" => "PHP_Bug_.2353632",
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
00187 public function checkBug53632()
00188 {
00189 $iState = 1;
00190 if ( version_compare( PHP_VERSION, "5.3", ">=" ) ) {
00191 $iState = version_compare( PHP_VERSION, "5.3.5", ">=" ) ? 2 : $iState;
00192 } elseif ( version_compare( PHP_VERSION, '5.2', ">=" ) ) {
00193 $iState = version_compare( PHP_VERSION, "5.2.17", ">=" ) ? 2 : $iState;
00194 }
00195 return $iState;
00196 }
00197
00203 public function checkCurl()
00204 {
00205 return extension_loaded( 'curl' ) ? 2 : 1;
00206 }
00207
00213 public function checkMbString()
00214 {
00215 return extension_loaded( 'mbstring' ) ? 2 : 1;
00216 }
00217
00226 public function checkServerPermissions( $sPath = null, $iMinPerm = 777 )
00227 {
00228 $sVerPrefix = '';
00229
00230 clearstatcache();
00231 $sPath = $sPath ? $sPath : getShopBasePath();
00232
00233
00234 $sFullPath = $sPath . "config.inc.php";
00235 if ( !is_readable( $sFullPath ) ||
00236 ( isAdmin() && is_writable( $sFullPath ) ) ||
00237 ( !isAdmin() && !is_writable( $sFullPath ) )
00238 ) {
00239 return 0;
00240 }
00241
00242 $sTheme = 'basic';
00243 $sTmp = "$sPath/tmp$sVerPrefix/";
00244 if (class_exists('oxConfig')) {
00245 $sTheme = oxConfig::getInstance()->getConfigParam('sTheme');
00246 $sCfgTmp = oxConfig::getInstance()->getConfigParam('sCompileDir');
00247 if (strpos($sCfgTmp, '<sCompileDir_') === false) {
00248 $sTmp = $sCfgTmp;
00249 }
00250 }
00251
00252 $aPathsToCheck = array(
00253 $sPath."out/pictures{$sVerPrefix}/",
00254 $sPath."out/media/",
00255 $sPath."out/$sTheme/src/",
00256 $sPath."log/",
00257 $sTmp
00258 );
00259 $iModStat = 2;
00260 $sPathToCheck = reset( $aPathsToCheck );
00261 while ( $sPathToCheck ) {
00262
00263 if ( !file_exists( $sPathToCheck ) ) {
00264 $iModStat = 0;
00265 break;
00266 }
00267
00268 if ( is_dir( $sPathToCheck ) ) {
00269
00270 $aSubF = glob( $sPathToCheck."*", GLOB_ONLYDIR );
00271 if (is_array($aSubF)) {
00272 foreach ( $aSubF as $sNewFolder ) {
00273 $aPathsToCheck[] = $sNewFolder . "/";
00274 }
00275 }
00276 }
00277
00278
00279
00280 if ( !is_readable( $sPathToCheck ) || !is_writable( $sPathToCheck ) ) {
00281 $iModStat = 0;
00282 break;
00283 }
00284
00285 $sPathToCheck = next( $aPathsToCheck );
00286 }
00287
00288 return $iModStat;
00289 }
00290
00297 protected function _getShopHostInfoFromConfig()
00298 {
00299 $sShopURL = oxConfig::getInstance()->getConfigParam( 'sShopURL' );
00300 if (preg_match('#^(https?://)?([^/:]+)(:([0-9]+))?(/.*)?$#i', $sShopURL, $m)) {
00301 $sHost = $m[2];
00302 $iPort = (int)$m[4];
00303 $blSsl = (strtolower($m[1])=='https://');
00304 if (!$iPort) {
00305 $iPort = $blSsl?443:80;
00306 }
00307 $sScript = rtrim($m[5], '/').'/';
00308 return array(
00309 'host'=>$sHost,
00310 'port'=>$iPort,
00311 'dir'=>$sScript,
00312 'ssl'=>$blSsl,
00313 );
00314 } else {
00315 return false;
00316 }
00317 }
00318
00325 protected function _getShopHostInfoFromServerVars()
00326 {
00327
00328 $sScript = $_SERVER['SCRIPT_NAME'];
00329 $iPort = (int) $_SERVER['SERVER_PORT'];
00330 $blSsl = (isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on'));
00331 if (!$iPort) {
00332 $iPort = $blSsl?443:80;
00333 }
00334 $sScript = rtrim(dirname(dirname( $sScript )), '/').'/';
00335 return array(
00336 'host'=>$_SERVER['HTTP_HOST'],
00337 'port'=>$iPort,
00338 'dir'=>$sScript,
00339 'ssl'=>$blSsl,
00340 );
00341 }
00342
00348 protected function _getShopHostInfo()
00349 {
00350 if ( isAdmin() ) {
00351 return $this->_getShopHostInfoFromConfig();
00352 } else {
00353 return $this->_getShopHostInfoFromServerVars();
00354 }
00355 }
00356
00362 public function checkModRewrite()
00363 {
00364 $iModStat = null;
00365 if ( ($aHostInfo = $this->_getShopHostInfo()) && $rFp = @fsockopen( ($aHostInfo['ssl']?'ssl://':'').$aHostInfo['host'], $aHostInfo['port'], $iErrNo, $sErrStr, 10 ) ) {
00366 $sReq = "POST {$aHostInfo['dir']}oxseo.php?mod_rewrite_module_is=off HTTP/1.1\r\n";
00367 $sReq .= "Host: {$aHostInfo['host']}\r\n";
00368 $sReq .= "User-Agent: OXID eShop setup\r\n";
00369 $sReq .= "Content-Type: application/x-www-form-urlencoded\r\n";
00370 $sReq .= "Content-Length: 0\r\n";
00371 $sReq .= "Connection: close\r\n\r\n";
00372
00373 $sOut = '';
00374 fwrite( $rFp, $sReq );
00375 while ( !feof( $rFp ) ) {
00376 $sOut .= fgets( $rFp, 100 );
00377 }
00378 fclose( $rFp );
00379
00380 $iModStat = ( strpos( $sOut, 'mod_rewrite_on' ) !== false ) ? 2 : 0;
00381 } else {
00382 if ( function_exists( 'apache_get_modules' ) ) {
00383
00384 $iModStat = in_array( 'mod_rewrite', apache_get_modules() ) ? 1 : 0;
00385 } else {
00386 $iModStat = -1;
00387 }
00388 }
00389 return $iModStat;
00390 }
00391
00397 public function checkAllowUrlFopen()
00398 {
00399 $iModStat = @ini_get('allow_url_fopen');
00400 $iModStat = ( $iModStat && strcasecmp( '1', $iModStat ) ) ? 2 : 1;
00401 if ( $iModStat == 1 ) {
00402 $iErrNo = 0;
00403 $sErrStr = '';
00404 if ( $oRes = @fsockopen( 'www.example.com', 80, $iErrNo, $sErrStr, 10 ) ) {
00405 $iModStat = 2;
00406 fclose( $oRes );
00407 }
00408 }
00409 $iModStat = ( !$iModStat ) ? 1 : $iModStat;
00410 return $iModStat;
00411 }
00412
00419 public function checkPhp4Compat()
00420 {
00421 $sZendStatus = ( strtolower( (string) @ini_get( 'zend.ze1_compatibility_mode' ) ) );
00422 return in_array( $sZendStatus, array( 'on', '1' ) ) ? 0 : 2;
00423 }
00424
00431 public function checkPhpVersion()
00432 {
00433 $iModStat = ( version_compare( PHP_VERSION, '5.1', '>' ) ) ? 1 : 0;
00434 $iModStat = ( $iModStat == 0 ) ? $iModStat : ( version_compare( PHP_VERSION, '5.2', '>=' ) ? 2 : 1 );
00435 return $iModStat;
00436 }
00437
00443 public function checkRequestUri()
00444 {
00445 return ( isset( $_SERVER['REQUEST_URI'] ) || isset( $_SERVER['SCRIPT_URI'] ) ) ? 2 : 0;
00446 }
00447
00453 public function checkLibXml2()
00454 {
00455 return class_exists( 'DOMDocument' ) ? 2 : 0;
00456 }
00457
00463 public function checkPhpXml()
00464 {
00465 return class_exists( 'DOMDocument' ) ? 2 : 0;
00466 }
00467
00473 public function checkJSon()
00474 {
00475 return extension_loaded( 'json' ) ? 2 : 0;
00476 }
00477
00483 public function checkIConv()
00484 {
00485 return extension_loaded( 'iconv' ) ? 2 : 0;
00486 }
00487
00493 public function checkTokenizer()
00494 {
00495 return extension_loaded( 'tokenizer' ) ? 2 : 0;
00496 }
00497
00503 public function checkBcMath()
00504 {
00505 return extension_loaded( 'bcmath' ) ? 2 : 1;
00506 }
00507
00513 public function checkOpenSsl()
00514 {
00515 return extension_loaded( 'openssl' ) ? 2 : 1;
00516 }
00517
00523 public function checkSoap()
00524 {
00525 return extension_loaded( 'soap' ) ? 2 : 1;
00526 }
00527
00533 public function checkMysqlConnect()
00534 {
00535
00536 $iModStat = ( extension_loaded( 'mysql' ) || extension_loaded( 'mysqli' ) || extension_loaded( 'pdo_mysql' ) ) ? 2 : 0;
00537
00538 if ( $iModStat ) {
00539 $sClientVersion = mysql_get_client_info();
00540 if (version_compare( $sClientVersion, '5', '<' )) {
00541 $iModStat = 1;
00542 if (version_compare( $sClientVersion, '4', '<' )) {
00543 $iModStat = 0;
00544 }
00545 } elseif (version_compare($sClientVersion, '5.0.36', '>=') && version_compare($sClientVersion, '5.0.38', '<')) {
00546
00547 $iModStat = 0;
00548 } elseif (version_compare($sClientVersion, '5.0.40', '>') && version_compare($sClientVersion, '5.0.42', '<')) {
00549
00550 $iModStat = 0;
00551 }
00552 if (strpos($sClientVersion, 'mysqlnd') !== false) {
00553
00554 $iModStat = 2;
00555 }
00556 }
00557 return $iModStat;
00558 }
00559
00567 public function checkMysqlVersion( $sVersion = null )
00568 {
00569 if ( $sVersion === null ) {
00570 $aRez = oxDb::getDb()->getAll( "SHOW VARIABLES LIKE 'version'" );
00571 foreach ( $aRez as $aRecord ) {
00572 $sVersion = $aRecord[1];
00573 break;
00574 }
00575 }
00576
00577 $iModStat = 0;
00578 if ( version_compare( $sVersion, '5.0.3', '>=' ) && version_compare( $sVersion, '5.0.37', '<>' ) ) {
00579 $iModStat = 2;
00580 }
00581
00582 return $iModStat;
00583 }
00584
00590 public function checkGdInfo()
00591 {
00592 $iModStat = extension_loaded( 'gd' ) ? 1 : 0;
00593 $iModStat = function_exists( 'imagecreatetruecolor' ) ? 2 : $iModStat;
00594 $iModStat = function_exists( 'imagecreatefromjpeg' ) ? $iModStat : 0;
00595 return $iModStat;
00596 }
00597
00603 public function checkIniSet()
00604 {
00605 return ( @ini_set('session.name', 'sid' ) !== false ) ? 2 : 0;
00606 }
00607
00613 public function checkRegisterGlobals()
00614 {
00615 $sGlobStatus = ( strtolower( (string) @ini_get( 'register_globals' ) ) );
00616 return in_array( $sGlobStatus, array( 'on', '1' ) ) ? 0 : 2;
00617 }
00618
00624 public function checkMemoryLimit()
00625 {
00626 if ( $sMemLimit = @ini_get('memory_limit') ) {
00627
00628 $sDefLimit = '14M';
00629 $sRecLimit = '30M';
00630
00631
00632 $iMemLimit = $this->_getBytes( $sMemLimit );
00633 $iModStat = ( $iMemLimit >= $this->_getBytes( $sDefLimit ) ) ? 1 : 0;
00634 $iModStat = $iModStat ? ( ( $iMemLimit >= $this->_getBytes( $sRecLimit ) ) ? 2 : $iModStat ) : $iModStat;
00635
00636 } else {
00637 $iModStat = -1;
00638 }
00639 return $iModStat;
00640 }
00641
00647 public function checkZendOptimizer()
00648 {
00653 return 2;
00654 }
00655
00661 public function checkZendPlatformOrServer()
00662 {
00663 if (function_exists( 'output_cache_get' )) {
00664 return 2;
00665 }
00666 if (function_exists( 'zend_disk_cache_fetch' )) {
00667 return 2;
00668 }
00669 if (function_exists( 'zend_shm_cache_fetch' )) {
00670 return 2;
00671 }
00672 return 1;
00673 }
00674
00680 protected function _getAdditionalCheck()
00681 {
00682 $sSelect = '';
00683 foreach ( $this->_aException as $sTable => $sColumn ) {
00684 $sSelect .= 'and ( t.TABLE_NAME != "'.$sTable.'" and c.COLUMN_NAME != "'.$sColumn.'" ) ';
00685 }
00686 return $sSelect;
00687 }
00688
00694 public function checkCollation()
00695 {
00696 $myConfig = oxConfig::getInstance();
00697
00698 $aCollations = array();
00699 $sCollation = '';
00700
00701 $sSelect = 'select t.TABLE_NAME, c.COLUMN_NAME, c.COLLATION_NAME from INFORMATION_SCHEMA.tables t ' .
00702 'LEFT JOIN INFORMATION_SCHEMA.columns c ON t.TABLE_NAME = c.TABLE_NAME ' .
00703 'where t.TABLE_SCHEMA = "'.$myConfig->getConfigParam( 'dbName' ).'" ' .
00704 'and c.TABLE_SCHEMA = "'.$myConfig->getConfigParam( 'dbName' ).'" ' .
00705 'and c.COLUMN_NAME in ("'.implode('", "', $this->_aColumns).'") ' . $this->_getAdditionalCheck() .
00706 ' ORDER BY (t.TABLE_NAME = "oxarticles") DESC';
00707 $aRez = oxDb::getDb()->getAll($sSelect);
00708 foreach ( $aRez as $aRetTable ) {
00709 if ( !$sCollation ) {
00710 $sCollation = $aRetTable[2];
00711 } else {
00712 if ( $aRetTable[2] && $sCollation != $aRetTable[2]) {
00713 $aCollations[$aRetTable[0]][$aRetTable[1]] = $aRetTable[2];
00714 }
00715 }
00716 }
00717
00718 if ( $this->_blSysReqStatus === null ) {
00719 $this->_blSysReqStatus = true;
00720 }
00721 if ( count($aCollations) > 0 ) {
00722 $this->_blSysReqStatus = false;
00723 }
00724 return $aCollations;
00725 }
00726
00732 public function checkDatabaseCluster()
00733 {
00734 return 2;
00735 }
00736
00742 public function checkUnicodeSupport()
00743 {
00744 return (@preg_match('/\pL/u', 'a') == 1) ? 2 : 1;
00745 }
00746
00752 public function getSysReqStatus()
00753 {
00754 if ( $this->_blSysReqStatus == null ) {
00755 $this->_blSysReqStatus = true;
00756 $this->getSystemInfo();
00757 $this->checkCollation();
00758 }
00759 return $this->_blSysReqStatus;
00760 }
00761
00776 public function getSystemInfo()
00777 {
00778 $aSysInfo = array();
00779 $aRequiredModules = $this->getRequiredModules();
00780 $this->_blSysReqStatus = true;
00781 foreach ( $aRequiredModules as $sModule => $sGroup ) {
00782 if ( isset($aSysInfo[$sGroup]) && !$aSysInfo[$sGroup] ) {
00783 $aSysInfo[$sGroup] = array();
00784 }
00785 $iModuleState = $this->getModuleInfo( $sModule );
00786 $aSysInfo[$sGroup][$sModule] = $iModuleState;
00787 $this->_blSysReqStatus = $this->_blSysReqStatus && ( bool ) abs( $iModuleState );
00788 }
00789 return $aSysInfo;
00790 }
00791
00799 public function getModuleInfo( $sModule = null )
00800 {
00801 if ( $sModule ) {
00802 $iModStat = null;
00803 $sCheckFunction = "check".str_replace(" ", "", ucwords(str_replace("_", " ", $sModule)));
00804 $iModStat = $this->$sCheckFunction();
00805
00806 return $iModStat;
00807 }
00808 }
00809
00817 public function getReqInfoUrl( $sIdent)
00818 {
00819 $sUrl = $this->_sReqInfoUrl;
00820 $aInfoMap = $this->_aInfoMap;
00821
00822
00823 if ( isset( $aInfoMap[$sIdent] ) ) {
00824 $sUrl .= "#".$aInfoMap[$sIdent];
00825 }
00826
00827 return $sUrl;
00828 }
00829
00837 protected function _getBytes( $sBytes )
00838 {
00839 $sBytes = trim( $sBytes );
00840 $sLast = strtolower($sBytes[strlen($sBytes)-1]);
00841 switch( $sLast ) {
00842
00843 case 'g':
00844 $sBytes *= 1024;
00845 case 'm':
00846 $sBytes *= 1024;
00847 case 'k':
00848 $sBytes *= 1024;
00849 break;
00850 }
00851
00852 return $sBytes;
00853 }
00854
00865 protected function _checkTemplateBlock($sTemplate, $sBlockName)
00866 {
00867 $oConfig = oxConfig::getInstance();
00868
00869 $sTplFile = $oConfig->getTemplatePath($sTemplate, false);
00870 if (!$sTplFile || !file_exists($sTplFile)) {
00871 return false;
00872 }
00873
00874 $sFile = file_get_contents($sTplFile);
00875 $sBlockNameQuoted = preg_quote($sBlockName, '/');
00876 return (bool)preg_match('/\[\{\s*block\s+name\s*=\s*([\'"])'.$sBlockNameQuoted.'\1\s*\}\]/is', $sFile);
00877 }
00878
00888 public function getMissingTemplateBlocks()
00889 {
00890 $aCache = array();
00891 $oConfig = oxConfig::getInstance();
00892
00893 $sShpIdParam = oxDb::getDb()->quote($oConfig->getShopId());
00894 $sSql = "select * from oxtplblocks where oxactive=1 and oxshopid=$sShpIdParam";
00895 $rs = oxDb::getDb(true)->execute($sSql);
00896 $aRet = array();
00897 if ($rs != false && $rs->recordCount() > 0) {
00898 while (!$rs->EOF) {
00899 $blStatus = false;
00900 if (isset($aCache[$rs->fields['OXTEMPLATE']]) && isset($aCache[$rs->fields['OXTEMPLATE']][$rs->fields['OXBLOCKNAME']])) {
00901 $blStatus = $aCache[$rs->fields['OXTEMPLATE']][$rs->fields['OXBLOCKNAME']];
00902 } else {
00903 $blStatus = $this->_checkTemplateBlock($rs->fields['OXTEMPLATE'], $rs->fields['OXBLOCKNAME']);
00904 $aCache[$rs->fields['OXTEMPLATE']][$rs->fields['OXBLOCKNAME']] = $blStatus;
00905 }
00906
00907 if (!$blStatus) {
00908 $aRet[] = array(
00909 'module' => $rs->fields['OXMODULE'],
00910 'block' => $rs->fields['OXBLOCKNAME'],
00911 'template' => $rs->fields['OXTEMPLATE'],
00912 );
00913 }
00914 $rs->moveNext();
00915 }
00916 }
00917
00918 return $aRet;
00919 }
00920 }