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         $aPathsToCheck = array(
00219                             "out/pictures{$sVerPrefix}/",
00220                             "out/media/",
00221                             "out/basic/src/",
00222                             "log/",
00223                             "tmp{$sVerPrefix}/"
00224                             );
00225 
00226         $iModStat = 2;
00227         $sPathToCheck = reset( $aPathsToCheck );
00228         while ( $sPathToCheck ) {
00229             $sFullPath = $sPath.$sPathToCheck;
00230 
00231             // missing file/folder?
00232             if ( !file_exists( $sFullPath ) ) {
00233                 $iModStat = 0;
00234                 break;
00235             }
00236 
00237             if ( is_dir( $sFullPath ) ) {
00238                 // adding subfolders
00239                 $aSubF = glob( $sFullPath."*", GLOB_ONLYDIR );
00240                 if (is_array($aSubF)) {
00241                     foreach ( $aSubF as $sNewFolder ) {
00242                         $aPathsToCheck[] = str_replace( $sPath, "", $sNewFolder ) . "/";
00243                     }
00244                 }
00245             }
00246 
00247             // testing if file permissions >= $iMinPerm
00248             //if ( ( (int) substr( decoct( fileperms( $sFullPath ) ), 2 ) ) < $iMinPerm ) {
00249             if ( !is_readable( $sFullPath ) || !is_writable( $sFullPath ) ) {
00250                 $iModStat = 0;
00251                 break;
00252             }
00253 
00254             $sPathToCheck = next( $aPathsToCheck );
00255         }
00256 
00257         return $iModStat;
00258     }
00259 
00265     public function checkModRewrite()
00266     {
00267         $iModStat = null;
00268         $sHost   = $_SERVER['HTTP_HOST'];
00269         $sScript = $_SERVER['SCRIPT_NAME'];
00270         if ( $sScript && $rFp = @fsockopen( $sHost, 80, $iErrNo, $sErrStr, 10 ) ) {
00271             if ( isAdmin() ) {
00272                 $sScript = oxConfig::getInstance()->getConfigParam( 'sShopURL' ).'oxseo.php?mod_rewrite_module_is=off';
00273             } else {
00274                 $sScript = str_replace( basename( $sScript ), '../oxseo.php?mod_rewrite_module_is=off', $sScript );
00275             }
00276 
00277             $sReq  = "POST $sScript HTTP/1.1\r\n";
00278             $sReq .= "Host: $sHost\r\n";
00279             $sReq .= "User-Agent: oxid setup\r\n";
00280             $sReq .= "Content-Type: application/x-www-form-urlencoded\r\n";
00281             $sReq .= "Content-Length: 0\r\n"; // empty post
00282             $sReq .= "Connection: close\r\n\r\n";
00283 
00284             $sOut = '';
00285             fwrite( $rFp, $sReq );
00286             while ( !feof( $rFp ) ) {
00287                 $sOut .= fgets( $rFp, 100 );
00288             }
00289             fclose( $rFp );
00290 
00291             $iModStat = ( strpos( $sOut, 'mod_rewrite_on' ) !== false ) ? 2 : 0;
00292         } else {
00293             if ( function_exists( 'apache_get_modules' ) ) {
00294                 // it does not assure that mod_rewrite is enabled on current host, so setting 1
00295                 $iModStat = in_array( 'mod_rewrite', apache_get_modules() ) ? 1 : 0;
00296             } else {
00297                 $iModStat = -1;
00298             }
00299         }
00300         return $iModStat;
00301     }
00302 
00308     public function checkAllowUrlFopen()
00309     {
00310         $iModStat = @ini_get('allow_url_fopen');
00311         $iModStat = ( $iModStat && strcasecmp( '1', $iModStat ) ) ? 2 : 1;
00312         if ( $iModStat == 1 ) {
00313             $iErrNo  = 0;
00314             $sErrStr = '';
00315             if ( $oRes = @fsockopen( 'www.example.com', 80, $iErrNo, $sErrStr, 10 ) ) {
00316                 $iModStat = 2;
00317                 fclose( $oRes );
00318             }
00319         }
00320         $iModStat = ( !$iModStat ) ? 1 : $iModStat;
00321         return $iModStat;
00322     }
00323 
00330     public function checkPhp4Compat()
00331     {
00332         $sZendStatus = ( strtolower( (string) @ini_get( 'zend.ze1_compatibility_mode' ) ) );
00333         return in_array( $sZendStatus, array( 'on', '1' ) ) ? 0 : 2;
00334     }
00335 
00342     public function checkPhpVersion()
00343     {
00344         $iModStat = ( version_compare( PHP_VERSION, '5.1', '>' ) ) ? 1 : 0;
00345         $iModStat = ( $iModStat == 0 ) ? $iModStat : ( version_compare( PHP_VERSION, '5.2', '>=' ) ? 2 : 1 );
00346         return $iModStat;
00347     }
00348 
00354     public function checkRequestUri()
00355     {
00356         return ( isset( $_SERVER['REQUEST_URI'] ) || isset( $_SERVER['SCRIPT_URI'] ) ) ? 2 : 0;
00357     }
00358 
00364     public function checkLibXml2()
00365     {
00366         return class_exists( 'DOMDocument' ) ? 2 : 0;
00367     }
00368 
00374     public function checkPhpXml()
00375     {
00376         return class_exists( 'DOMDocument' ) ? 2 : 0;
00377     }
00378 
00384     public function checkJSon()
00385     {
00386         return extension_loaded( 'json' ) ? 2 : 0;
00387     }
00388 
00394     public function checkIConv()
00395     {
00396         return extension_loaded( 'iconv' ) ? 2 : 0;
00397     }
00398 
00404     public function checkTokenizer()
00405     {
00406         return extension_loaded( 'tokenizer' ) ? 2 : 0;
00407     }
00408 
00414     public function checkBcMath()
00415     {
00416         return extension_loaded( 'bcmath' ) ? 2 : 1;
00417     }
00418 
00424     public function checkMysqlConnect()
00425     {
00426         // MySQL module for MySQL5
00427         $iModStat = ( extension_loaded( 'mysql' ) || extension_loaded( 'mysqli' ) || extension_loaded( 'pdo_mysql' ) ) ? 2 : 0;
00428         // client version must be >=5
00429         if ( $iModStat ) {
00430             $sClientVersion = mysql_get_client_info();
00431             if (version_compare( $sClientVersion, '5', '<' )) {
00432                 $iModStat = 1;
00433                 if (version_compare( $sClientVersion, '4', '<' )) {
00434                     $iModStat = 0;
00435                 }
00436             } elseif (version_compare($sClientVersion, '5.0.36', '>=') && version_compare($sClientVersion, '5.0.38', '<')) {
00437                 // mantis#0001003: Problems with MySQL version 5.0.37
00438                 $iModStat = 0;
00439             } elseif (version_compare($sClientVersion, '5.0.40', '>') && version_compare($sClientVersion, '5.0.42', '<')) {
00440                 // mantis#0001877: Exclude MySQL 5.0.41 from system requirements as not fitting
00441                 $iModStat = 0;
00442             }
00443             if (strpos($sClientVersion, 'mysqlnd') !== false) {
00444                 // PHP 5.3 includes new mysqlnd extension
00445                 $iModStat = 2;
00446             }
00447         }
00448         return $iModStat;
00449     }
00450 
00458     public function checkMysqlVersion( $sVersion = null )
00459     {
00460         if ( $sVersion === null ) {
00461             $aRez = oxDb::getDb()->getAll( "SHOW VARIABLES LIKE 'version'" );
00462             foreach ( $aRez as $aRecord ) {
00463                 $sVersion = $aRecord[1];
00464                 break;
00465             }
00466         }
00467 
00468         $iModStat = 0;
00469         if ( version_compare( $sVersion, '5', '>=' ) && version_compare( $sVersion, '5.0.37', '<>' ) ) {
00470             $iModStat = 2;
00471         }
00472 
00473         return $iModStat;
00474     }
00475 
00481     public function checkGdInfo()
00482     {
00483         $iModStat = extension_loaded( 'gd' ) ? 1 : 0;
00484         $iModStat = function_exists( 'imagecreatetruecolor' ) ? 2 : $iModStat;
00485         $iModStat = function_exists( 'imagecreatefromjpeg' ) ? $iModStat : 0;
00486         return $iModStat;
00487     }
00488 
00494     public function checkIniSet()
00495     {
00496         return ( @ini_set('session.name', 'sid' ) !== false ) ? 2 : 0;
00497     }
00498 
00504     public function checkRegisterGlobals()
00505     {
00506         $sGlobStatus = ( strtolower( (string) @ini_get( 'register_globals' ) ) );
00507         return in_array( $sGlobStatus, array( 'on', '1' ) ) ? 0 : 2;
00508     }
00509 
00515     public function checkMemoryLimit()
00516     {
00517         if ( $sMemLimit = @ini_get('memory_limit') ) {
00518                 // CE - PE at least to 14 MB. We recomend a memory_limit of 30MB.
00519                 $sDefLimit = '14M';
00520                 $sRecLimit = '30M';
00521 
00522 
00523             $iMemLimit = $this->_getBytes( $sMemLimit );
00524             $iModStat = ( $iMemLimit >= $this->_getBytes( $sDefLimit ) ) ? 1 : 0;
00525             $iModStat = $iModStat ? ( ( $iMemLimit >= $this->_getBytes( $sRecLimit ) ) ? 2 : $iModStat ) : $iModStat;
00526 
00527         } else {
00528             $iModStat = -1;
00529         }
00530         return $iModStat;
00531     }
00532 
00538     public function checkZendOptimizer()
00539     {
00540         $iMinStat = 0;
00541         $iModStat = (extension_loaded( 'Zend Optimizer' ) || (function_exists('zend_loader_enabled') && zend_loader_enabled())) ? 2 : $iMinStat;
00542         $sHost   = $_SERVER['HTTP_HOST'];
00543         $sScript = $_SERVER['SCRIPT_NAME'];
00544         if ( $iModStat > $iMinStat && $sScript && $rFp = @fsockopen( $sHost, 80, $iErrNo, $sErrStr, 10 ) ) {
00545             $sScript = str_replace( basename($sScript), '../admin/index.php', $sScript );
00546 
00547             $sReq  = "POST $sScript HTTP/1.1\r\n";
00548             $sReq .= "Host: $sHost\r\n";
00549             $sReq .= "User-Agent: oxid setup\r\n";
00550             $sReq .= "Content-Type: application/x-www-form-urlencoded\r\n";
00551             $sReq .= "Content-Length: 0\r\n"; // empty post
00552             $sReq .= "Connection: close\r\n\r\n";
00553 
00554             $sOut = '';
00555             fwrite( $rFp, $sReq );
00556             while ( !feof( $rFp ) ) {
00557                 $sOut .= fgets( $rFp, 100 );
00558             }
00559 
00560             $iModStat = ( strpos( $sOut, 'Zend Optimizer not installed' ) !== false ) ? $iMinStat : 2;
00561             fclose( $rFp );
00562         }
00563         if ( $iModStat > $iMinStat && $sScript && $rFp = @fsockopen( $sHost, 80, $iErrNo, $sErrStr, 10 ) ) {
00564             $sScript = str_replace( basename($sScript), '../index.php', $sScript );
00565 
00566             $sReq  = "POST $sScript HTTP/1.1\r\n";
00567             $sReq .= "Host: $sHost\r\n";
00568             $sReq .= "User-Agent: oxid setup\r\n";
00569             $sReq .= "Content-Type: application/x-www-form-urlencoded\r\n";
00570             $sReq .= "Content-Length: 0\r\n"; // empty post
00571             $sReq .= "Connection: close\r\n\r\n";
00572 
00573             $sOut = '';
00574             fwrite( $rFp, $sReq );
00575             while ( !feof( $rFp ) ) {
00576                 $sOut .= fgets( $rFp, 100 );
00577             }
00578             $iModStat = ( strpos( $sOut, 'Zend Optimizer not installed' ) !== false ) ? $iMinStat : 2;
00579             fclose( $rFp );
00580         }
00581         return $iModStat;
00582     }
00583 
00589     public function checkZendPlatformOrServer()
00590     {
00591         if (function_exists( 'output_cache_get' )) {
00592             return 2;
00593         }
00594         if (function_exists( 'zend_disk_cache_fetch' )) {
00595             return 2;
00596         }
00597         if (function_exists( 'zend_shm_cache_fetch' )) {
00598             return 2;
00599         }
00600         return 1;
00601     }
00602 
00608     protected function _getAdditionalCheck()
00609     {
00610         $sSelect = '';
00611         foreach ( $this->_aException as $sTable => $sColumn ) {
00612             $sSelect .= 'and ( t.TABLE_NAME != "'.$sTable.'" and c.COLUMN_NAME != "'.$sColumn.'" ) ';
00613         }
00614         return $sSelect;
00615     }
00616 
00622     public function checkCollation()
00623     {
00624         $myConfig = oxConfig::getInstance();
00625 
00626         $aCollations = array();
00627         $sCollation = '';
00628 
00629         $sSelect = 'select t.TABLE_NAME, c.COLUMN_NAME, c.COLLATION_NAME from INFORMATION_SCHEMA.tables t ' .
00630                    'LEFT JOIN INFORMATION_SCHEMA.columns c ON t.TABLE_NAME = c.TABLE_NAME  ' .
00631                    'where t.TABLE_SCHEMA = "'.$myConfig->getConfigParam( 'dbName' ).'" ' .
00632                    'and c.TABLE_SCHEMA = "'.$myConfig->getConfigParam( 'dbName' ).'" ' .
00633                    'and c.COLUMN_NAME in ("'.implode('", "', $this->_aColumns).'") ' . $this->_getAdditionalCheck() .
00634                    ' ORDER BY (t.TABLE_NAME = "oxarticles") DESC';
00635         $aRez = oxDb::getDb()->getAll($sSelect);
00636         foreach ( $aRez as $aRetTable ) {
00637             if ( !$sCollation ) {
00638                 $sCollation = $aRetTable[2];
00639             } else {
00640                 if ( $aRetTable[2] && $sCollation != $aRetTable[2]) {
00641                     $aCollations[$aRetTable[0]][$aRetTable[1]] = $aRetTable[2];
00642                 }
00643             }
00644         }
00645 
00646         if ( $this->_blSysReqStatus === null ) {
00647             $this->_blSysReqStatus = true;
00648         }
00649         if ( count($aCollations) > 0 ) {
00650             $this->_blSysReqStatus = false;
00651         }
00652         return $aCollations;
00653     }
00654 
00660     public function checkDatabaseCluster()
00661     {
00662         return 2;
00663     }
00664 
00670     public function checkUnicodeSupport()
00671     {
00672         return (@preg_match('/\pL/u', 'a') == 1) ? 2 : 1;
00673     }
00674 
00680     public function getSysReqStatus()
00681     {
00682         if ( $this->_blSysReqStatus == null ) {
00683             $this->_blSysReqStatus = true;
00684             $this->getSystemInfo();
00685             $this->checkCollation();
00686         }
00687         return $this->_blSysReqStatus;
00688     }
00689 
00704     public function getSystemInfo()
00705     {
00706         $aSysInfo = array();
00707         $aRequiredModules = $this->getRequiredModules();
00708         $this->_blSysReqStatus = true;
00709         foreach ( $aRequiredModules as $sModule => $sGroup ) {
00710             if ( isset($aSysInfo[$sGroup]) && !$aSysInfo[$sGroup] ) {
00711                 $aSysInfo[$sGroup] = array();
00712             }
00713             $iModuleState = $this->getModuleInfo( $sModule );
00714             $aSysInfo[$sGroup][$sModule] = $iModuleState;
00715             $this->_blSysReqStatus = $this->_blSysReqStatus && ( bool ) abs( $iModuleState );
00716         }
00717         return $aSysInfo;
00718     }
00719 
00727     public function getModuleInfo( $sModule = null )
00728     {
00729         if ( $sModule ) {
00730             $iModStat = null;
00731             $sCheckFunction = "check".str_replace(" ", "", ucwords(str_replace("_", " ", $sModule)));
00732             $iModStat = $this->$sCheckFunction();
00733 
00734             return $iModStat;
00735         }
00736     }
00737 
00745     public function getReqInfoUrl( $sIdent)
00746     {
00747         $sUrl = $this->_sReqInfoUrl;
00748         $aInfoMap = $this->_aInfoMap;
00749 
00750         // only known will be anchored
00751         if ( isset( $aInfoMap[$sIdent] ) ) {
00752             $sUrl .= "#".$aInfoMap[$sIdent];
00753         }
00754 
00755         return $sUrl;
00756     }
00757 
00765     protected function _getBytes( $sBytes )
00766     {
00767         $sBytes = trim( $sBytes );
00768         $sLast = strtolower($sBytes[strlen($sBytes)-1]);
00769         switch( $sLast ) {
00770             // The 'G' modifier is available since PHP 5.1.0
00771             case 'g':
00772                 $sBytes *= 1024;
00773             case 'm':
00774                 $sBytes *= 1024;
00775             case 'k':
00776                 $sBytes *= 1024;
00777                 break;
00778         }
00779 
00780         return $sBytes;
00781     }
00782 }

Generated by  doxygen 1.6.2