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 {
00016     const FETCH_MODE_NUM = ADODB_FETCH_NUM;
00017 
00022     const FETCH_MODE_ASSOC = ADODB_FETCH_ASSOC;
00023 
00028     public static $configSet = false;
00029 
00035     protected static $_instance = null;
00036 
00042     protected static $_oDB = null;
00043 
00049     protected static $_aTblDescCache = array();
00050 
00055     private static $_dbType = '';
00056 
00061     private static $_dbUser = '';
00062 
00067     private static $_dbPwd  = '';
00068 
00073     private static $_dbName = '';
00074 
00079     private static $_dbHost = '';
00080 
00085     private static $_iDebug = 0;
00086 
00091     private static $_blLogChangesInAdmin = false;
00092 
00097     private static $_iUtfMode = 0;
00098 
00103     private static $_sDefaultDatabaseConnection = null;
00104 
00109     private static $_aSlaveHosts;
00110 
00115     private static $_sAdminEmail;
00116 
00121     private static $_iMasterSlaveBalance;
00122 
00127     private static $_sLocalTimeFormat;
00128 
00133     private static $_sLocalDateFormat;
00134 
00142     public static function setConfig( $oConfig )
00143     {
00144         self::$_dbType                     = $oConfig->getVar( 'dbType' );
00145         self::$_dbUser                     = $oConfig->getVar( 'dbUser' );
00146         self::$_dbPwd                      = $oConfig->getVar( 'dbPwd' );
00147         self::$_dbName                     = $oConfig->getVar( 'dbName' );
00148         self::$_dbHost                     = $oConfig->getVar( 'dbHost' );
00149         self::$_iDebug                     = $oConfig->getVar( 'iDebug' );
00150         self::$_blLogChangesInAdmin        = $oConfig->getVar( 'blLogChangesInAdmin' );
00151         self::$_iUtfMode                   = $oConfig->getVar( 'iUtfMode' );
00152         self::$_sDefaultDatabaseConnection = $oConfig->getVar( 'sDefaultDatabaseConnection' );
00153         self::$_aSlaveHosts                = $oConfig->getVar( 'aSlaveHosts' );
00154         self::$_iMasterSlaveBalance        = $oConfig->getVar( 'iMasterSlaveBalance' );
00155         self::$_sAdminEmail                = $oConfig->getVar( 'sAdminEmail' );
00156         self::$_sLocalTimeFormat           = $oConfig->getVar( 'sLocalTimeFormat' );
00157         self::$_sLocalDateFormat           = $oConfig->getVar( 'sLocalDateFormat' );
00158     }
00159 
00167     protected static function _getConfigParam( $sConfigName )
00168     {
00169         if ( isset( self::$$sConfigName ) ) {
00170             return self::$$sConfigName;
00171         }
00172 
00173         return null;
00174     }
00175 
00181     public static function getInstance()
00182     {
00183         // disable caching for test modules
00184         if ( defined( 'OXID_PHP_UNIT' ) ) {
00185             self::$_instance = modInstances::getMod( __CLASS__ );
00186         }
00187 
00188         if ( !self::$_instance instanceof oxDb ) {
00189 
00190             //do not use simple oxNew here as it goes to eternal cycle
00191             self::$_instance = new oxDb();
00192 
00193             if ( defined( 'OXID_PHP_UNIT' ) ) {
00194                 modInstances::addMod( __CLASS__, self::$_instance);
00195             }
00196         }
00197         return self::$_instance;
00198     }
00199 
00205     protected function isAdmin()
00206     {
00207         return isAdmin();
00208     }
00209 
00215     protected function _getModules()
00216     {
00217         //adding exception handler for SQL errors
00218         $_iDebug = self::_getConfigParam( '_iDebug' );
00219 
00220         global $ADODB_EXCEPTION;
00221         $ADODB_EXCEPTION = 'oxAdoDbException';
00222         include_once getShopBasePath() . 'core/adodblite/adodb-exceptions.inc.php';
00223 
00224         $sModules = '';
00225         if (  $_iDebug == 2 || $_iDebug == 3 || $_iDebug == 4 || $_iDebug == 7  ) {
00226             $sModules = 'perfmon';
00227         }
00228 
00229         // log admin changes ?
00230         if ( $this->isAdmin() && self::_getConfigParam( '_blLogChangesInAdmin' ) ) {
00231             $sModules .= ( $sModules ? ':' : '' ) . 'oxadminlog';
00232         }
00233 
00234         return $sModules;
00235     }
00236 
00244     protected function _setUp( $oDb )
00245     {
00246         $_iDebug = self::_getConfigParam( '_iDebug' );
00247         if ( $_iDebug == 2 || $_iDebug == 3 || $_iDebug == 4  || $_iDebug == 7 ) {
00248             try {
00249                 $oDb->execute( 'truncate table adodb_logsql' );
00250             } catch ( ADODB_Exception $e ) {
00251                 // nothing
00252             }
00253             if ( method_exists( $oDb, "logSQL" ) ) {
00254                 $oDb->logSQL( true );
00255             }
00256         }
00257 
00258         $oDb->cacheSecs = 60 * 10; // 10 minute caching
00259         $oDb->execute( 'SET @@session.sql_mode = ""' );
00260 
00261         if ( self::_getConfigParam( '_iUtfMode' ) ) {
00262             $oDb->execute( 'SET NAMES "utf8"' );
00263             $oDb->execute( 'SET CHARACTER SET utf8' );
00264             $oDb->execute( 'SET CHARACTER_SET_CONNECTION = utf8' );
00265             $oDb->execute( 'SET CHARACTER_SET_DATABASE = utf8' );
00266             $oDb->execute( 'SET character_set_results = utf8' );
00267             $oDb->execute( 'SET character_set_server = utf8' );
00268         } elseif ( ( $sConn = self::_getConfigParam('_sDefaultDatabaseConnection') ) != '' ) {
00269             $oDb->execute( 'SET NAMES "' . $sConn . '"' );
00270         }
00271     }
00272 
00282     protected function _sendMail( $sEmail, $sSubject, $sBody )
00283     {
00284         include_once getShopBasePath() . 'core/phpmailer/class.phpmailer.php';
00285         $oMailer = new phpmailer();
00286         $oMailer->isMail();
00287 
00288         $oMailer->From = $sEmail;
00289         $oMailer->AddAddress( $sEmail );
00290         $oMailer->Subject = $sSubject;
00291         $oMailer->Body = $sBody;
00292         return $oMailer->send();
00293     }
00294 
00302     protected function _notifyConnectionErrors( $oDb )
00303     {
00304         // notifying shop owner about connection problems
00305         if ( ( $sAdminEmail = self::_getConfigParam( '_sAdminEmail' ) ) ) {
00306             $sFailedShop = isset( $_REQUEST['shp'] ) ? addslashes( $_REQUEST['shp'] ) : 'Base shop';
00307 
00308             $sDate = date( 'l dS of F Y h:i:s A');
00309             $sScript  = $_SERVER['SCRIPT_NAME'] . '?' . $_SERVER['QUERY_STRING'];
00310             $sReferer = $_SERVER['HTTP_REFERER'];
00311 
00312             //sending a message to admin
00313             $sWarningSubject = 'Offline warning!';
00314             $sWarningBody = "
00315                 Database error in OXID eShop:
00316                 Date: {$sDate}
00317                 Shop: {$sFailedShop}
00318 
00319                 mysql error: " . $oDb->errorMsg()."
00320                 mysql error no: " . $oDb->errorNo()."
00321 
00322                 Script: {$sScript}
00323                 Referer: {$sReferer}";
00324 
00325             $this->_sendMail( $sAdminEmail, $sWarningSubject, $sWarningBody );
00326         }
00327 
00328         //only exception to default construction method
00329         $oEx = new oxConnectionException();
00330         $oEx->setMessage( 'EXCEPTION_CONNECTION_NODB' );
00331         $oEx->setConnectionError( self::_getConfigParam( '_dbUser' ) . 's' . getShopBasePath() . $oDb->errorMsg() );
00332         throw $oEx;
00333     }
00334 
00343     protected function _onConnectionError( $oDb )
00344     {
00345         $sVerPrefix = '';
00346             $sVerPrefix = '_ce';
00347 
00348 
00349 
00350         $sConfig = join( '', file( getShopBasePath().'config.inc.php' ) );
00351 
00352         if ( strpos( $sConfig, '<dbHost'.$sVerPrefix.'>' ) !== false &&
00353              strpos( $sConfig, '<dbName'.$sVerPrefix.'>' ) !== false ) {
00354             // pop to setup as there is something wrong
00355             //oxRegistry::getUtils()->redirect( "setup/index.php", true, 302 );
00356             $sHeaderCode = "HTTP/1.1 302 Found";
00357             header( $sHeaderCode );
00358             header( "Location: setup/index.php" );
00359             header( "Connection: close" );
00360             exit();
00361         } else {
00362             // notifying about connection problems
00363             $this->_notifyConnectionErrors( $oDb );
00364 
00365         }
00366     }
00367 
00368 
00376     protected function _getDbInstance( $iInstType = false )
00377     {
00378         $sHost = self::_getConfigParam( "_dbHost" );
00379         $sUser = self::_getConfigParam( "_dbUser" );
00380         $sPwd  = self::_getConfigParam( "_dbPwd" );
00381         $sName = self::_getConfigParam( "_dbName" );
00382         $sType = self::_getConfigParam( "_dbType" );
00383 
00384         $oDb = ADONewConnection( $sType, $this->_getModules() );
00385 
00386 
00387             try {
00388                 $oDb->connect( $sHost, $sUser, $sPwd, $sName );
00389             } catch( oxAdoDbException $e ) {
00390                 $this->_onConnectionError( $oDb );
00391             }
00392 
00393         self::_setUp( $oDb );
00394 
00395         return $oDb;
00396     }
00397 
00407     public static function getDb( $iFetchMode = oxDb::FETCH_MODE_NUM )
00408     {
00409         if ( defined( 'OXID_PHP_UNIT' ) ) {
00410             if ( isset( modDB::$unitMOD ) && is_object( modDB::$unitMOD ) ) {
00411                 return modDB::$unitMOD;
00412             }
00413         }
00414 
00415         if ( self::$_oDB === null ) {
00416 
00417             $oInst = self::getInstance();
00418 
00419             //setting configuration on the first call
00420             $oInst->setConfig( oxRegistry::get("oxConfigFile") );
00421 
00422              global  $ADODB_SESSION_TBL,
00423                     $ADODB_SESSION_CONNECT,
00424                     $ADODB_SESSION_DRIVER,
00425                     $ADODB_SESSION_USER,
00426                     $ADODB_SESSION_PWD,
00427                     $ADODB_SESSION_DB,
00428                     $ADODB_SESS_LIFE,
00429                     $ADODB_SESS_DEBUG;
00430 
00431              // session related parameters. don't change.
00432 
00433             //Tomas
00434             //the default setting is 3000 * 60, but actually changing this will give no effect as now redefinition of this constant
00435             //appears after OXID custom settings are loaded and $ADODB_SESS_LIFE depends on user settings.
00436             //You can find the redefinition of ADODB_SESS_LIFE @ oxconfig.php:: line ~ 390.
00437             $ADODB_SESS_LIFE       = 3000 * 60;
00438             $ADODB_SESSION_TBL     = "oxsessions";
00439             $ADODB_SESSION_DRIVER  = self::_getConfigParam( '_dbType' );
00440             $ADODB_SESSION_USER    = self::_getConfigParam( '_dbUser' );
00441             $ADODB_SESSION_PWD     = self::_getConfigParam( '_dbPwd' );
00442             $ADODB_SESSION_DB      = self::_getConfigParam( '_dbName' );
00443             $ADODB_SESSION_CONNECT = self::_getConfigParam( '_dbHost' );
00444             $ADODB_SESS_DEBUG      = false;
00445 
00446             $oDb = new oxLegacyDb();
00447             $oDbInst = $oInst->_getDbInstance();
00448             $oDb->setConnection( $oDbInst );
00449 
00450             self::$_oDB = $oDb;
00451         }
00452 
00453         self::$_oDB->setFetchMode( $iFetchMode );
00454 
00455         return self::$_oDB;
00456     }
00457 
00465     public function quoteArray( $aStrArray )
00466     {
00467         $oDb = self::getDb();
00468 
00469         foreach ( $aStrArray as $sKey => $sString ) {
00470             $aStrArray[$sKey] = $oDb->quote( $sString );
00471         }
00472         return $aStrArray;
00473     }
00474 
00480     public function resetTblDescCache()
00481     {
00482         self::$_aTblDescCache = array();
00483     }
00484 
00492     public function getTableDescription( $sTableName )
00493     {
00494         // simple cache
00495         if ( isset( self::$_aTblDescCache[$sTableName] ) ) {
00496             return self::$_aTblDescCache[$sTableName];
00497         }
00498 
00499             $aFields = self::getDb()->MetaColumns( $sTableName );
00500 
00501         self::$_aTblDescCache[$sTableName] = $aFields;
00502 
00503         return $aFields;
00504     }
00505 
00517     public function convertDBDateTime( $oObject, $blToTimeStamp = false, $blOnlyDate = false )
00518     {
00519         return oxRegistry::get('oxUtilsDate')->convertDBDateTime( $oObject, $blToTimeStamp, $blOnlyDate );
00520     }
00521 
00532     public function convertDBTimestamp( $oObject, $blToTimeStamp = false )
00533     {
00534         return oxRegistry::get('oxUtilsDate')->convertDBTimestamp( $oObject, $blToTimeStamp );
00535     }
00536 
00547     public function convertDBDate( $oObject, $blToTimeStamp = false )
00548     {
00549         return oxRegistry::get('oxUtilsDate')->convertDBDate( $oObject, $blToTimeStamp );
00550     }
00551 
00560     public function isValidFieldName( $sField )
00561     {
00562         return ( boolean ) getStr()->preg_match( "#^[\w\d\._]*$#", $sField );
00563     }
00564 
00578     protected function _setDefaultFormatedValue( $oObject, $sDate, $sLocalDateFormat, $sLocalTimeFormat, $blOnlyDate )
00579     {
00580     }
00581 
00591     protected function _defineAndCheckDefaultTimeValues( $blToTimeStamp )
00592     {
00593     }
00594 
00604     protected function _defineAndCheckDefaultDateValues( $blToTimeStamp )
00605     {
00606     }
00607 
00615     protected function _defaultDatePattern()
00616     {
00617     }
00618 
00626     protected function _defaultTimePattern()
00627     {
00628     }
00629 
00637     protected function _regexp2ValidateDateInput()
00638     {
00639     }
00640 
00648     protected function _regexp2ValidateTimeInput()
00649     {
00650     }
00651 
00659     protected function _defineDateFormattingRules()
00660     {
00661         // date formatting rules
00662         $aDFormats  = array("ISO" => array("Y-m-d", array(2, 3, 1), "0000-00-00"),
00663                             "EUR" => array("d.m.Y", array(2, 1, 3), "00.00.0000"),
00664                             "USA" => array("m/d/Y", array(1, 2, 3), "00/00/0000")
00665                            );
00666         return $aDFormats;
00667     }
00668 
00676     protected function _defineTimeFormattingRules()
00677     {
00678         // time formatting rules
00679         $aTFormats  = array("ISO" => array("H:i:s",   array(1, 2, 3 ), "00:00:00"),
00680                             "EUR" => array("H.i.s",   array(1, 2, 3 ), "00.00.00"),
00681                             "USA" => array("h:i:s A", array(1, 2, 3 ), "00:00:00 AM")
00682                            );
00683         return $aTFormats;
00684     }
00685 
00698     protected function _setDefaultDateTimeValue( $oObject, $sLocalDateFormat, $sLocalTimeFormat, $blOnlyDate )
00699     {
00700         $aDFormats  = $this->_defineDateFormattingRules();
00701         $aTFormats  = $this->_defineTimeFormattingRules();
00702 
00703         $sReturn = $aDFormats[$sLocalDateFormat][2];
00704         if ( !$blOnlyDate) {
00705             $sReturn .= " ".$aTFormats[$sLocalTimeFormat][2];
00706         }
00707 
00708         if ($oObject instanceof oxField) {
00709             $oObject->setValue(trim($sReturn));
00710         } else {
00711             $oObject->value = trim($sReturn);
00712         }
00713         // increasing(decreasing) field length
00714         $oObject->fldmax_length = strlen( $oObject->value);
00715     }
00716 
00729     protected function _setDate( $oObject, $sDateFormat, $aDFields, $aDateMatches )
00730     {
00731         // formatting correct time value
00732         $iTimestamp = mktime( 0, 0, 0, $aDateMatches[$aDFields[0]],
00733                               $aDateMatches[$aDFields[1]],
00734                               $aDateMatches[$aDFields[2]]);
00735 
00736         if ($oObject instanceof oxField) {
00737             $oObject->setValue(@date( $sDateFormat, $iTimestamp ));
00738         } else {
00739             $oObject->value = @date( $sDateFormat, $iTimestamp );
00740         }
00741         // we should increase (decrease) field length
00742         $oObject->fldmax_length = strlen( $oObject->value );
00743     }
00744 
00760     protected function _formatCorrectTimeValue( $oObject, $sDateFormat, $sTimeFormat, $aDateMatches, $aTimeMatches, $aTFields, $aDFields )
00761     {
00762         // formatting correct time value
00763         $iTimestamp = @mktime( (int) $aTimeMatches[$aTFields[0]],
00764                                (int) $aTimeMatches[$aTFields[1]],
00765                                (int) $aTimeMatches[$aTFields[2]],
00766                                (int) $aDateMatches[$aDFields[0]],
00767                                (int) $aDateMatches[$aDFields[1]],
00768                                (int) $aDateMatches[$aDFields[2]] );
00769 
00770         if ($oObject instanceof oxField) {
00771             $oObject->setValue(trim( @date( $sDateFormat." ".$sTimeFormat, $iTimestamp ) ));
00772         } else {
00773             $oObject->value = trim( @date( $sDateFormat." ".$sTimeFormat, $iTimestamp ) );
00774         }
00775 
00776         // we should increase (decrease) field length
00777         $oObject->fldmax_length = strlen( $oObject->value );
00778     }
00779 
00785     protected function _getConnectionId()
00786     {
00787         return self::getDb()->getDb()->connectionId;
00788     }
00789 
00797     public function escapeString( $sString )
00798     {
00799         if ( 'mysql' == self::_getConfigParam( "_dbType" )) {
00800             return mysql_real_escape_string( $sString, $this->_getConnectionId() );
00801         } elseif ( 'mysqli' == self::_getConfigParam( "_dbType" )) {
00802             return mysqli_real_escape_string( $this->_getConnectionId(), $sString );
00803         } else {
00804             return mysql_real_escape_string( $sString, $this->_getConnectionId() );
00805         }
00806     }
00807 
00817     public function updateViews( $aTables = null )
00818     {
00819         $oMetaData = oxNew('oxDbMetaDataHandler');
00820         return $oMetaData->updateViews();
00821     }
00822 }