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
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 $sTheme = 'basic';
00246 $sTmp = "$sPath/tmp$sVerPrefix/";
00247 if (class_exists('oxConfig')) {
00248 $sTheme = oxConfig::getInstance()->getConfigParam('sTheme');
00249 $sCfgTmp = oxConfig::getInstance()->getConfigParam('sCompileDir');
00250 if (strpos($sCfgTmp, '<sCompileDir_') === false) {
00251 $sTmp = $sCfgTmp;
00252 }
00253 }
00254
00255 $aPathsToCheck = array(
00256 $sPath."out/pictures{$sVerPrefix}/",
00257 $sPath."out/media/",
00258 $sPath."out/$sTheme/src/",
00259 $sPath."log/",
00260 $sTmp
00261 );
00262 $iModStat = 2;
00263 $sPathToCheck = reset( $aPathsToCheck );
00264 while ( $sPathToCheck ) {
00265
00266 if ( !file_exists( $sPathToCheck ) ) {
00267 $iModStat = 0;
00268 break;
00269 }
00270
00271 if ( is_dir( $sPathToCheck ) ) {
00272
00273 $aSubF = glob( $sPathToCheck."*", GLOB_ONLYDIR );
00274 if (is_array($aSubF)) {
00275 foreach ( $aSubF as $sNewFolder ) {
00276 $aPathsToCheck[] = $sNewFolder . "/";
00277 }
00278 }
00279 }
00280
00281
00282
00283 if ( !is_readable( $sPathToCheck ) || !is_writable( $sPathToCheck ) ) {
00284 $iModStat = 0;
00285 break;
00286 }
00287
00288 $sPathToCheck = next( $aPathsToCheck );
00289 }
00290
00291 return $iModStat;
00292 }
00293
00300 protected function _getShopHostInfoFromConfig()
00301 {
00302 $sShopURL = oxConfig::getInstance()->getConfigParam( 'sShopURL' );
00303 if (preg_match('#^(https?://)?([^/:]+)(:([0-9]+))?(/.*)?$#i', $sShopURL, $m)) {
00304 $sHost = $m[2];
00305 $iPort = (int)$m[4];
00306 $blSsl = (strtolower($m[1])=='https://');
00307 if (!$iPort) {
00308 $iPort = $blSsl?443:80;
00309 }
00310 $sScript = rtrim($m[5], '/').'/';
00311 return array(
00312 'host'=>$sHost,
00313 'port'=>$iPort,
00314 'dir'=>$sScript,
00315 'ssl'=>$blSsl,
00316 );
00317 } else {
00318 return false;
00319 }
00320 }
00321
00328 protected function _getShopHostInfoFromServerVars()
00329 {
00330
00331 $sScript = $_SERVER['SCRIPT_NAME'];
00332 $iPort = (int) $_SERVER['SERVER_PORT'];
00333 $blSsl = (isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on'));
00334 if (!$iPort) {
00335 $iPort = $blSsl?443:80;
00336 }
00337 $sScript = rtrim(dirname(dirname( $sScript )), '/').'/';
00338 return array(
00339 'host'=>$_SERVER['HTTP_HOST'],
00340 'port'=>$iPort,
00341 'dir'=>$sScript,
00342 'ssl'=>$blSsl,
00343 );
00344 }
00345
00351 protected function _getShopHostInfo()
00352 {
00353 if ( isAdmin() ) {
00354 return $this->_getShopHostInfoFromConfig();
00355 } else {
00356 return $this->_getShopHostInfoFromServerVars();
00357 }
00358 }
00359
00365 public function checkModRewrite()
00366 {
00367 $iModStat = null;
00368 if ( ($aHostInfo = $this->_getShopHostInfo()) && $rFp = @fsockopen( ($aHostInfo['ssl']?'ssl://':'').$aHostInfo['host'], $aHostInfo['port'], $iErrNo, $sErrStr, 10 ) ) {
00369 $sReq = "POST {$aHostInfo['dir']}oxseo.php?mod_rewrite_module_is=off HTTP/1.1\r\n";
00370 $sReq .= "Host: {$aHostInfo['host']}\r\n";
00371 $sReq .= "User-Agent: OXID eShop setup\r\n";
00372 $sReq .= "Content-Type: application/x-www-form-urlencoded\r\n";
00373 $sReq .= "Content-Length: 0\r\n";
00374 $sReq .= "Connection: close\r\n\r\n";
00375
00376 $sOut = '';
00377 fwrite( $rFp, $sReq );
00378 while ( !feof( $rFp ) ) {
00379 $sOut .= fgets( $rFp, 100 );
00380 }
00381 fclose( $rFp );
00382
00383 $iModStat = ( strpos( $sOut, 'mod_rewrite_on' ) !== false ) ? 2 : 0;
00384 } else {
00385 if ( function_exists( 'apache_get_modules' ) ) {
00386
00387 $iModStat = in_array( 'mod_rewrite', apache_get_modules() ) ? 1 : 0;
00388 } else {
00389 $iModStat = -1;
00390 }
00391 }
00392 return $iModStat;
00393 }
00394
00400 public function checkAllowUrlFopen()
00401 {
00402 $iModStat = @ini_get('allow_url_fopen');
00403 $iModStat = ( $iModStat && strcasecmp( '1', $iModStat ) ) ? 2 : 1;
00404 if ( $iModStat == 1 ) {
00405 $iErrNo = 0;
00406 $sErrStr = '';
00407 if ( $oRes = @fsockopen( 'www.example.com', 80, $iErrNo, $sErrStr, 10 ) ) {
00408 $iModStat = 2;
00409 fclose( $oRes );
00410 }
00411 }
00412 $iModStat = ( !$iModStat ) ? 1 : $iModStat;
00413 return $iModStat;
00414 }
00415
00422 public function checkPhp4Compat()
00423 {
00424 $sZendStatus = ( strtolower( (string) @ini_get( 'zend.ze1_compatibility_mode' ) ) );
00425 return in_array( $sZendStatus, array( 'on', '1' ) ) ? 0 : 2;
00426 }
00427
00434 public function checkPhpVersion()
00435 {
00436 $iModStat = ( version_compare( PHP_VERSION, '5.1', '>' ) ) ? 1 : 0;
00437 $iModStat = ( $iModStat == 0 ) ? $iModStat : ( version_compare( PHP_VERSION, '5.2', '>=' ) ? 2 : 1 );
00438 return $iModStat;
00439 }
00440
00446 public function checkRequestUri()
00447 {
00448 return ( isset( $_SERVER['REQUEST_URI'] ) || isset( $_SERVER['SCRIPT_URI'] ) ) ? 2 : 0;
00449 }
00450
00456 public function checkLibXml2()
00457 {
00458 return class_exists( 'DOMDocument' ) ? 2 : 0;
00459 }
00460
00466 public function checkPhpXml()
00467 {
00468 return class_exists( 'DOMDocument' ) ? 2 : 0;
00469 }
00470
00476 public function checkJSon()
00477 {
00478 return extension_loaded( 'json' ) ? 2 : 0;
00479 }
00480
00486 public function checkIConv()
00487 {
00488 return extension_loaded( 'iconv' ) ? 2 : 0;
00489 }
00490
00496 public function checkTokenizer()
00497 {
00498 return extension_loaded( 'tokenizer' ) ? 2 : 0;
00499 }
00500
00506 public function checkBcMath()
00507 {
00508 return extension_loaded( 'bcmath' ) ? 2 : 1;
00509 }
00510
00516 public function checkOpenSsl()
00517 {
00518 return extension_loaded( 'openssl' ) ? 2 : 1;
00519 }
00520
00526 public function checkSoap()
00527 {
00528 return extension_loaded( 'soap' ) ? 2 : 1;
00529 }
00530
00536 public function checkMysqlConnect()
00537 {
00538
00539 $iModStat = ( extension_loaded( 'mysql' ) || extension_loaded( 'mysqli' ) || extension_loaded( 'pdo_mysql' ) ) ? 2 : 0;
00540
00541 if ( $iModStat ) {
00542 $sClientVersion = mysql_get_client_info();
00543 if (version_compare( $sClientVersion, '5', '<' )) {
00544 $iModStat = 1;
00545 if (version_compare( $sClientVersion, '4', '<' )) {
00546 $iModStat = 0;
00547 }
00548 } elseif (version_compare($sClientVersion, '5.0.36', '>=') && version_compare($sClientVersion, '5.0.38', '<')) {
00549
00550 $iModStat = 0;
00551 } elseif (version_compare($sClientVersion, '5.0.40', '>') && version_compare($sClientVersion, '5.0.42', '<')) {
00552
00553 $iModStat = 0;
00554 }
00555 if (strpos($sClientVersion, 'mysqlnd') !== false) {
00556
00557 $iModStat = 2;
00558 }
00559 }
00560 return $iModStat;
00561 }
00562
00570 public function checkMysqlVersion( $sVersion = null )
00571 {
00572 if ( $sVersion === null ) {
00573 $aRez = oxDb::getDb()->getAll( "SHOW VARIABLES LIKE 'version'" );
00574 foreach ( $aRez as $aRecord ) {
00575 $sVersion = $aRecord[1];
00576 break;
00577 }
00578 }
00579
00580 $iModStat = 0;
00581 if ( version_compare( $sVersion, '5.0.3', '>=' ) && version_compare( $sVersion, '5.0.37', '<>' ) ) {
00582 $iModStat = 2;
00583 }
00584
00585 return $iModStat;
00586 }
00587
00593 public function checkGdInfo()
00594 {
00595 $iModStat = extension_loaded( 'gd' ) ? 1 : 0;
00596 $iModStat = function_exists( 'imagecreatetruecolor' ) ? 2 : $iModStat;
00597 $iModStat = function_exists( 'imagecreatefromjpeg' ) ? $iModStat : 0;
00598 return $iModStat;
00599 }
00600
00606 public function checkIniSet()
00607 {
00608 return ( @ini_set('session.name', 'sid' ) !== false ) ? 2 : 0;
00609 }
00610
00616 public function checkRegisterGlobals()
00617 {
00618 $sGlobStatus = ( strtolower( (string) @ini_get( 'register_globals' ) ) );
00619 return in_array( $sGlobStatus, array( 'on', '1' ) ) ? 0 : 2;
00620 }
00621
00627 public function checkMemoryLimit()
00628 {
00629 if ( $sMemLimit = @ini_get('memory_limit') ) {
00630
00631 $sDefLimit = '14M';
00632 $sRecLimit = '30M';
00633
00634
00635 $iMemLimit = $this->_getBytes( $sMemLimit );
00636 $iModStat = ( $iMemLimit >= $this->_getBytes( $sDefLimit ) ) ? 1 : 0;
00637 $iModStat = $iModStat ? ( ( $iMemLimit >= $this->_getBytes( $sRecLimit ) ) ? 2 : $iModStat ) : $iModStat;
00638
00639 } else {
00640 $iModStat = -1;
00641 }
00642 return $iModStat;
00643 }
00644
00650 public function checkZendOptimizer()
00651 {
00656 return 2;
00657 }
00658
00664 public function checkZendPlatformOrServer()
00665 {
00666 if (function_exists( 'output_cache_get' )) {
00667 return 2;
00668 }
00669 if (function_exists( 'zend_disk_cache_fetch' )) {
00670 return 2;
00671 }
00672 if (function_exists( 'zend_shm_cache_fetch' )) {
00673 return 2;
00674 }
00675 return 1;
00676 }
00677
00683 protected function _getAdditionalCheck()
00684 {
00685 $sSelect = '';
00686 foreach ( $this->_aException as $sTable => $sColumn ) {
00687 $sSelect .= 'and ( t.TABLE_NAME != "'.$sTable.'" and c.COLUMN_NAME != "'.$sColumn.'" ) ';
00688 }
00689 return $sSelect;
00690 }
00691
00697 public function checkCollation()
00698 {
00699 $myConfig = oxConfig::getInstance();
00700
00701 $aCollations = array();
00702 $sCollation = '';
00703
00704 $sSelect = 'select t.TABLE_NAME, c.COLUMN_NAME, c.COLLATION_NAME from INFORMATION_SCHEMA.tables t ' .
00705 'LEFT JOIN INFORMATION_SCHEMA.columns c ON t.TABLE_NAME = c.TABLE_NAME ' .
00706 'where t.TABLE_SCHEMA = "'.$myConfig->getConfigParam( 'dbName' ).'" ' .
00707 'and c.TABLE_SCHEMA = "'.$myConfig->getConfigParam( 'dbName' ).'" ' .
00708 'and c.COLUMN_NAME in ("'.implode('", "', $this->_aColumns).'") ' . $this->_getAdditionalCheck() .
00709 ' ORDER BY (t.TABLE_NAME = "oxarticles") DESC';
00710 $aRez = oxDb::getDb()->getAll($sSelect);
00711 foreach ( $aRez as $aRetTable ) {
00712 if ( !$sCollation ) {
00713 $sCollation = $aRetTable[2];
00714 } else {
00715 if ( $aRetTable[2] && $sCollation != $aRetTable[2]) {
00716 $aCollations[$aRetTable[0]][$aRetTable[1]] = $aRetTable[2];
00717 }
00718 }
00719 }
00720
00721 if ( $this->_blSysReqStatus === null ) {
00722 $this->_blSysReqStatus = true;
00723 }
00724 if ( count($aCollations) > 0 ) {
00725 $this->_blSysReqStatus = false;
00726 }
00727 return $aCollations;
00728 }
00729
00735 public function checkDatabaseCluster()
00736 {
00737 return 2;
00738 }
00739
00745 public function checkUnicodeSupport()
00746 {
00747 return (@preg_match('/\pL/u', 'a') == 1) ? 2 : 1;
00748 }
00749
00755 public function getSysReqStatus()
00756 {
00757 if ( $this->_blSysReqStatus == null ) {
00758 $this->_blSysReqStatus = true;
00759 $this->getSystemInfo();
00760 $this->checkCollation();
00761 }
00762 return $this->_blSysReqStatus;
00763 }
00764
00779 public function getSystemInfo()
00780 {
00781 $aSysInfo = array();
00782 $aRequiredModules = $this->getRequiredModules();
00783 $this->_blSysReqStatus = true;
00784 foreach ( $aRequiredModules as $sModule => $sGroup ) {
00785 if ( isset($aSysInfo[$sGroup]) && !$aSysInfo[$sGroup] ) {
00786 $aSysInfo[$sGroup] = array();
00787 }
00788 $iModuleState = $this->getModuleInfo( $sModule );
00789 $aSysInfo[$sGroup][$sModule] = $iModuleState;
00790 $this->_blSysReqStatus = $this->_blSysReqStatus && ( bool ) abs( $iModuleState );
00791 }
00792 return $aSysInfo;
00793 }
00794
00802 public function getModuleInfo( $sModule = null )
00803 {
00804 if ( $sModule ) {
00805 $iModStat = null;
00806 $sCheckFunction = "check".str_replace(" ", "", ucwords(str_replace("_", " ", $sModule)));
00807 $iModStat = $this->$sCheckFunction();
00808
00809 return $iModStat;
00810 }
00811 }
00812
00820 public function getReqInfoUrl( $sIdent)
00821 {
00822 $sUrl = $this->_sReqInfoUrl;
00823 $aInfoMap = $this->_aInfoMap;
00824
00825
00826 if ( isset( $aInfoMap[$sIdent] ) ) {
00827 $sUrl .= "#".$aInfoMap[$sIdent];
00828 }
00829
00830 return $sUrl;
00831 }
00832
00840 protected function _getBytes( $sBytes )
00841 {
00842 $sBytes = trim( $sBytes );
00843 $sLast = strtolower($sBytes[strlen($sBytes)-1]);
00844 switch( $sLast ) {
00845
00846 case 'g':
00847 $sBytes *= 1024;
00848 case 'm':
00849 $sBytes *= 1024;
00850 case 'k':
00851 $sBytes *= 1024;
00852 break;
00853 }
00854
00855 return $sBytes;
00856 }
00857
00868 protected function _checkTemplateBlock($sTemplate, $sBlockName)
00869 {
00870 $oConfig = oxConfig::getInstance();
00871
00872 $sTplFile = $oConfig->getTemplatePath($sTemplate, false);
00873 if (!$sTplFile || !file_exists($sTplFile)) {
00874 return false;
00875 }
00876
00877 $sFile = file_get_contents($sTplFile);
00878 $sBlockNameQuoted = preg_quote($sBlockName, '/');
00879 return (bool)preg_match('/\[\{\s*block\s+name\s*=\s*([\'"])'.$sBlockNameQuoted.'\1\s*\}\]/is', $sFile);
00880 }
00881
00891 public function getMissingTemplateBlocks()
00892 {
00893 $aCache = array();
00894 $oConfig = oxConfig::getInstance();
00895
00896 $sShpIdParam = oxDb::getDb()->quote($oConfig->getShopId());
00897 $sSql = "select * from oxtplblocks where oxactive=1 and oxshopid=$sShpIdParam";
00898 $rs = oxDb::getDb(true)->execute($sSql);
00899 $aRet = array();
00900 if ($rs != false && $rs->recordCount() > 0) {
00901 while (!$rs->EOF) {
00902 $blStatus = false;
00903 if (isset($aCache[$rs->fields['OXTEMPLATE']]) && isset($aCache[$rs->fields['OXTEMPLATE']][$rs->fields['OXBLOCKNAME']])) {
00904 $blStatus = $aCache[$rs->fields['OXTEMPLATE']][$rs->fields['OXBLOCKNAME']];
00905 } else {
00906 $blStatus = $this->_checkTemplateBlock($rs->fields['OXTEMPLATE'], $rs->fields['OXBLOCKNAME']);
00907 $aCache[$rs->fields['OXTEMPLATE']][$rs->fields['OXBLOCKNAME']] = $blStatus;
00908 }
00909
00910 if (!$blStatus) {
00911 $aRet[] = array(
00912 'module' => $rs->fields['OXMODULE'],
00913 'block' => $rs->fields['OXBLOCKNAME'],
00914 'template' => $rs->fields['OXTEMPLATE'],
00915 );
00916 }
00917 $rs->moveNext();
00918 }
00919 }
00920
00921 return $aRet;
00922 }
00923 }