oxdb.php

Go to the documentation of this file.
00001 <?php
00002 
00003 
00004 // Including main ADODB include
00005 require_once getShopBasePath() . 'core/adodblite/adodb.inc.php';
00006 
00010 class oxDb
00011 {
00012 
00018     const FETCH_MODE_NUM = ADODB_FETCH_NUM;
00019 
00025     const FETCH_MODE_ASSOC = ADODB_FETCH_ASSOC;
00026 
00032     public static $configSet = false;
00033 
00039     protected static $_instance = null;
00040 
00046     protected static $_oDB = null;
00047 
00053     protected static $_aTblDescCache = array();
00054 
00060     private static $_dbType = '';
00061 
00067     private static $_dbUser = '';
00068 
00074     private static $_dbPwd = '';
00075 
00081     private static $_dbName = '';
00082 
00088     private static $_dbHost = '';
00089 
00095     private static $_iDebug = 0;
00096 
00102     private static $_blLogChangesInAdmin = false;
00103 
00109     private static $_iUtfMode = 0;
00110 
00116     private static $_sDefaultDatabaseConnection = null;
00117 
00123     private static $_aSlaveHosts;
00124 
00130     private static $_sAdminEmail;
00131 
00137     private static $_iMasterSlaveBalance;
00138 
00144     private static $_sLocalTimeFormat;
00145 
00151     private static $_sLocalDateFormat;
00152 
00158     public static function setConfig($oConfig)
00159     {
00160         self::$_dbType = $oConfig->getVar('dbType');
00161         self::$_dbUser = $oConfig->getVar('dbUser');
00162         self::$_dbPwd = $oConfig->getVar('dbPwd');
00163         self::$_dbName = $oConfig->getVar('dbName');
00164         self::$_dbHost = $oConfig->getVar('dbHost');
00165         self::$_iDebug = $oConfig->getVar('iDebug');
00166         self::$_blLogChangesInAdmin = $oConfig->getVar('blLogChangesInAdmin');
00167         self::$_iUtfMode = $oConfig->getVar('iUtfMode');
00168         self::$_sDefaultDatabaseConnection = $oConfig->getVar('sDefaultDatabaseConnection');
00169         self::$_aSlaveHosts = $oConfig->getVar('aSlaveHosts');
00170         self::$_iMasterSlaveBalance = $oConfig->getVar('iMasterSlaveBalance');
00171         self::$_sAdminEmail = $oConfig->getVar('sAdminEmail');
00172         self::$_sLocalTimeFormat = $oConfig->getVar('sLocalTimeFormat');
00173         self::$_sLocalDateFormat = $oConfig->getVar('sLocalDateFormat');
00174     }
00175 
00183     protected static function _getConfigParam($sConfigName)
00184     {
00185         if (isset(self::$$sConfigName)) {
00186             return self::$$sConfigName;
00187         }
00188 
00189         return null;
00190     }
00191 
00197     public static function getInstance()
00198     {
00199         // disable caching for test modules
00200         if (defined('OXID_PHP_UNIT')) {
00201             self::$_instance = modInstances::getMod(__CLASS__);
00202         }
00203 
00204         if (!self::$_instance instanceof oxDb) {
00205 
00206             //do not use simple oxNew here as it goes to eternal cycle
00207             self::$_instance = new oxDb();
00208 
00209             if (defined('OXID_PHP_UNIT')) {
00210                 modInstances::addMod(__CLASS__, self::$_instance);
00211             }
00212         }
00213 
00214         return self::$_instance;
00215     }
00216 
00222     protected function isAdmin()
00223     {
00224         return isAdmin();
00225     }
00226 
00232     protected function _getModules()
00233     {
00234         $_iDebug = self::_getConfigParam('_iDebug');
00235 
00236         $this->_registerAdoDbExceptionHandler();
00237 
00238         $sModules = '';
00239         if ($_iDebug == 2 || $_iDebug == 3 || $_iDebug == 4 || $_iDebug == 7) {
00240             $sModules = 'perfmon';
00241         }
00242 
00243         // log admin changes ?
00244         if ($this->isAdmin() && self::_getConfigParam('_blLogChangesInAdmin')) {
00245             $sModules .= ($sModules ? ':' : '') . 'oxadminlog';
00246         }
00247 
00248         return $sModules;
00249     }
00250 
00254     protected function _registerAdoDbExceptionHandler()
00255     {
00256         global $ADODB_EXCEPTION;
00257         $ADODB_EXCEPTION = 'oxAdoDbException';
00258 
00259         include_once getShopBasePath() . 'core/adodblite/adodb-exceptions.inc.php';
00260     }
00261 
00267     protected function _setUp($oDb)
00268     {
00269         $_iDebug = self::_getConfigParam('_iDebug');
00270         if ($_iDebug == 2 || $_iDebug == 3 || $_iDebug == 4 || $_iDebug == 7) {
00271             try {
00272                 $oDb->execute('truncate table adodb_logsql');
00273             } catch (ADODB_Exception $e) {
00274                 // nothing
00275             }
00276             if (method_exists($oDb, "logSQL")) {
00277                 $oDb->logSQL(true);
00278             }
00279         }
00280 
00281         $oDb->cacheSecs = 60 * 10; // 10 minute caching
00282         $oDb->execute('SET @@session.sql_mode = ""');
00283 
00284         if (self::_getConfigParam('_iUtfMode')) {
00285             $oDb->execute('SET NAMES "utf8"');
00286             $oDb->execute('SET CHARACTER SET utf8');
00287             $oDb->execute('SET CHARACTER_SET_CONNECTION = utf8');
00288             $oDb->execute('SET CHARACTER_SET_DATABASE = utf8');
00289             $oDb->execute('SET character_set_results = utf8');
00290             $oDb->execute('SET character_set_server = utf8');
00291         } elseif (($sConn = self::_getConfigParam('_sDefaultDatabaseConnection')) != '') {
00292             $oDb->execute('SET NAMES "' . $sConn . '"');
00293         }
00294     }
00295 
00305     protected function _sendMail($sEmail, $sSubject, $sBody)
00306     {
00307         include_once getShopBasePath() . 'core/phpmailer/class.phpmailer.php';
00308         $oMailer = new phpmailer();
00309         $oMailer->isMail();
00310 
00311         $oMailer->From = $sEmail;
00312         $oMailer->AddAddress($sEmail);
00313         $oMailer->Subject = $sSubject;
00314         $oMailer->Body = $sBody;
00315 
00316         return $oMailer->send();
00317     }
00318 
00324     protected function _notifyConnectionErrors($oDb)
00325     {
00326         // notifying shop owner about connection problems
00327         if (($sAdminEmail = self::_getConfigParam('_sAdminEmail'))) {
00328             $sFailedShop = isset($_REQUEST['shp']) ? addslashes($_REQUEST['shp']) : 'Base shop';
00329 
00330             $sDate = date('l dS of F Y h:i:s A');
00331             $sScript = $_SERVER['SCRIPT_NAME'] . '?' . $_SERVER['QUERY_STRING'];
00332             $sReferer = $_SERVER['HTTP_REFERER'];
00333 
00334             //sending a message to admin
00335             $sWarningSubject = 'Offline warning!';
00336             $sWarningBody = "
00337                 Database error in OXID eShop:
00338                 Date: {$sDate}
00339                 Shop: {$sFailedShop}
00340 
00341                 mysql error: " . $oDb->errorMsg() . "
00342                 mysql error no: " . $oDb->errorNo() . "
00343 
00344                 Script: {$sScript}
00345                 Referer: {$sReferer}";
00346 
00347             $this->_sendMail($sAdminEmail, $sWarningSubject, $sWarningBody);
00348         }
00349 
00350         //only exception to default construction method
00351         $oEx = new oxConnectionException();
00352         $oEx->setMessage('EXCEPTION_CONNECTION_NODB');
00353         $oEx->setConnectionError(self::_getConfigParam('_dbUser') . 's' . getShopBasePath() . $oDb->errorMsg());
00354         throw $oEx;
00355     }
00356 
00363     protected function _onConnectionError($oDb)
00364     {
00365         $sVerPrefix = '';
00366         $sVerPrefix = '_ce';
00367 
00368 
00369         $sConfig = join('', file(getShopBasePath() . 'config.inc.php'));
00370 
00371         if (strpos($sConfig, '<dbHost' . $sVerPrefix . '>') !== false &&
00372             strpos($sConfig, '<dbName' . $sVerPrefix . '>') !== false
00373         ) {
00374             // pop to setup as there is something wrong
00375             //oxRegistry::getUtils()->redirect( "setup/index.php", true, 302 );
00376             $sHeaderCode = "HTTP/1.1 302 Found";
00377             header($sHeaderCode);
00378             header("Location: setup/index.php");
00379             header("Connection: close");
00380             exit();
00381         } else {
00382             // notifying about connection problems
00383             $this->_notifyConnectionErrors($oDb);
00384 
00385         }
00386     }
00387 
00388 
00396     protected function _getDbInstance($iInstType = false)
00397     {
00398         $sHost = self::_getConfigParam("_dbHost");
00399         $sUser = self::_getConfigParam("_dbUser");
00400         $sPwd = self::_getConfigParam("_dbPwd");
00401         $sName = self::_getConfigParam("_dbName");
00402         $sType = self::_getConfigParam("_dbType");
00403 
00404         $oDb = ADONewConnection($sType, $this->_getModules());
00405 
00406 
00407         try {
00408             $oDb->connect($sHost, $sUser, $sPwd, $sName);
00409         } catch (oxAdoDbException $e) {
00410             $this->_onConnectionError($oDb);
00411         }
00412 
00413         self::_setUp($oDb);
00414 
00415         return $oDb;
00416     }
00417 
00427     public static function getDb($iFetchMode = oxDb::FETCH_MODE_NUM)
00428     {
00429         if (defined('OXID_PHP_UNIT')) {
00430             if (isset(modDB::$unitMOD) && is_object(modDB::$unitMOD)) {
00431                 return modDB::$unitMOD;
00432             }
00433         }
00434 
00435         if (self::$_oDB === null) {
00436 
00437             $oInst = self::getInstance();
00438 
00439             //setting configuration on the first call
00440             $oInst->setConfig(oxRegistry::get("oxConfigFile"));
00441 
00442             global $ADODB_SESSION_TBL,
00443                    $ADODB_SESSION_CONNECT,
00444                    $ADODB_SESSION_DRIVER,
00445                    $ADODB_SESSION_USER,
00446                    $ADODB_SESSION_PWD,
00447                    $ADODB_SESSION_DB,
00448                    $ADODB_SESS_LIFE,
00449                    $ADODB_SESS_DEBUG;
00450 
00451             // session related parameters. don't change.
00452 
00453             //Tomas
00454             //the default setting is 3000 * 60, but actually changing this will give no effect as now redefinition of this constant
00455             //appears after OXID custom settings are loaded and $ADODB_SESS_LIFE depends on user settings.
00456             //You can find the redefinition of ADODB_SESS_LIFE @ oxconfig.php:: line ~ 390.
00457             $ADODB_SESS_LIFE = 3000 * 60;
00458             $ADODB_SESSION_TBL = "oxsessions";
00459             $ADODB_SESSION_DRIVER = self::_getConfigParam('_dbType');
00460             $ADODB_SESSION_USER = self::_getConfigParam('_dbUser');
00461             $ADODB_SESSION_PWD = self::_getConfigParam('_dbPwd');
00462             $ADODB_SESSION_DB = self::_getConfigParam('_dbName');
00463             $ADODB_SESSION_CONNECT = self::_getConfigParam('_dbHost');
00464             $ADODB_SESS_DEBUG = false;
00465 
00466             $oDb = new oxLegacyDb();
00467             $oDbInst = $oInst->_getDbInstance();
00468             $oDb->setConnection($oDbInst);
00469 
00470             self::$_oDB = $oDb;
00471         }
00472 
00473         self::$_oDB->setFetchMode($iFetchMode);
00474 
00475         return self::$_oDB;
00476     }
00477 
00487     public function quoteArray($aStrArray)
00488     {
00489         return self::getDb()->quoteArray($aStrArray);
00490     }
00491 
00495     public function resetTblDescCache()
00496     {
00497         self::$_aTblDescCache = array();
00498     }
00499 
00507     public function getTableDescription($sTableName)
00508     {
00509         // simple cache
00510         if (isset(self::$_aTblDescCache[$sTableName])) {
00511             return self::$_aTblDescCache[$sTableName];
00512         }
00513 
00514         $aFields = self::getDb()->MetaColumns($sTableName);
00515 
00516         self::$_aTblDescCache[$sTableName] = $aFields;
00517 
00518         return $aFields;
00519     }
00520 
00529     public function isValidFieldName($sField)
00530     {
00531         return ( boolean ) getStr()->preg_match("#^[\w\d\._]*$#", $sField);
00532     }
00533 
00539     protected function _getConnectionId()
00540     {
00541         return self::getDb()->getDb()->connectionId;
00542     }
00543 
00551     public function escapeString($sString)
00552     {
00553         if ('mysql' == self::_getConfigParam("_dbType")) {
00554             return mysql_real_escape_string($sString, $this->_getConnectionId());
00555         } elseif ('mysqli' == self::_getConfigParam("_dbType")) {
00556             return mysqli_real_escape_string($this->_getConnectionId(), $sString);
00557         } else {
00558             return mysql_real_escape_string($sString, $this->_getConnectionId());
00559         }
00560     }
00561 }