oxsysrequirements.php

Go to the documentation of this file.
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                                      // "zend_platform_or_server"
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         // special config file check
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             // missing file/folder?
00239             if ( !file_exists( $sPathToCheck ) ) {
00240                 $iModStat = 0;
00241                 break;
00242             }
00243 
00244             if ( is_dir( $sPathToCheck ) ) {
00245                 // adding subfolders
00246                 $aSubF = glob( $sPathToCheck."*", GLOB_ONLYDIR );
00247                 if (is_array($aSubF)) {
00248                     foreach ( $aSubF as $sNewFolder ) {
00249                         $aPathsToCheck[] = $sNewFolder . "/";
00250                     }
00251                 }
00252             }
00253 
00254             // testing if file permissions >= $iMinPerm
00255             //if ( ( (int) substr( decoct( fileperms( $sFullPath ) ), 2 ) ) < $iMinPerm ) {
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         // got here from setup dir
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"; // empty post
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                 // it does not assure that mod_rewrite is enabled on current host, so setting 1
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         // MySQL module for MySQL5
00492         $iModStat = ( extension_loaded( 'mysql' ) || extension_loaded( 'mysqli' ) || extension_loaded( 'pdo_mysql' ) ) ? 2 : 0;
00493         // client version must be >=5
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                 // mantis#0001003: Problems with MySQL version 5.0.37
00503                 $iModStat = 0;
00504             } elseif (version_compare($sClientVersion, '5.0.40', '>') && version_compare($sClientVersion, '5.0.42', '<')) {
00505                 // mantis#0001877: Exclude MySQL 5.0.41 from system requirements as not fitting
00506                 $iModStat = 0;
00507             }
00508             if (strpos($sClientVersion, 'mysqlnd') !== false) {
00509                 // PHP 5.3 includes new mysqlnd extension
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                 // CE - PE at least to 14 MB. We recomend a memory_limit of 30MB.
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         // only known will be anchored
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             // The 'G' modifier is available since PHP 5.1.0
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 }