OXID eShop CE  4.8.12
 All Classes Files Functions Variables Pages
oxdb.php
Go to the documentation of this file.
1 <?php
2 
3 
4 // Including main ADODB include
5 require_once getShopBasePath() . 'core/adodblite/adodb.inc.php';
6 
10 class oxDb
11 {
16  const FETCH_MODE_NUM = ADODB_FETCH_NUM;
17 
22  const FETCH_MODE_ASSOC = ADODB_FETCH_ASSOC;
23 
28  public static $configSet = false;
29 
35  protected static $_instance = null;
36 
42  protected static $_oDB = null;
43 
49  protected static $_aTblDescCache = array();
50 
55  private static $_dbType = '';
56 
61  private static $_dbUser = '';
62 
67  private static $_dbPwd = '';
68 
73  private static $_dbName = '';
74 
79  private static $_dbHost = '';
80 
85  private static $_iDebug = 0;
86 
91  private static $_blLogChangesInAdmin = false;
92 
97  private static $_iUtfMode = 0;
98 
103  private static $_sDefaultDatabaseConnection = null;
104 
109  private static $_aSlaveHosts;
110 
115  private static $_sAdminEmail;
116 
121  private static $_iMasterSlaveBalance;
122 
127  private static $_sLocalTimeFormat;
128 
133  private static $_sLocalDateFormat;
134 
142  public static function setConfig( $oConfig )
143  {
144  self::$_dbType = $oConfig->getVar( 'dbType' );
145  self::$_dbUser = $oConfig->getVar( 'dbUser' );
146  self::$_dbPwd = $oConfig->getVar( 'dbPwd' );
147  self::$_dbName = $oConfig->getVar( 'dbName' );
148  self::$_dbHost = $oConfig->getVar( 'dbHost' );
149  self::$_iDebug = $oConfig->getVar( 'iDebug' );
150  self::$_blLogChangesInAdmin = $oConfig->getVar( 'blLogChangesInAdmin' );
151  self::$_iUtfMode = $oConfig->getVar( 'iUtfMode' );
152  self::$_sDefaultDatabaseConnection = $oConfig->getVar( 'sDefaultDatabaseConnection' );
153  self::$_aSlaveHosts = $oConfig->getVar( 'aSlaveHosts' );
154  self::$_iMasterSlaveBalance = $oConfig->getVar( 'iMasterSlaveBalance' );
155  self::$_sAdminEmail = $oConfig->getVar( 'sAdminEmail' );
156  self::$_sLocalTimeFormat = $oConfig->getVar( 'sLocalTimeFormat' );
157  self::$_sLocalDateFormat = $oConfig->getVar( 'sLocalDateFormat' );
158  }
159 
167  protected static function _getConfigParam( $sConfigName )
168  {
169  if ( isset( self::$$sConfigName ) ) {
170  return self::$$sConfigName;
171  }
172 
173  return null;
174  }
175 
181  public static function getInstance()
182  {
183  // disable caching for test modules
184  if ( defined( 'OXID_PHP_UNIT' ) ) {
185  self::$_instance = modInstances::getMod( __CLASS__ );
186  }
187 
188  if ( !self::$_instance instanceof oxDb ) {
189 
190  //do not use simple oxNew here as it goes to eternal cycle
191  self::$_instance = new oxDb();
192 
193  if ( defined( 'OXID_PHP_UNIT' ) ) {
194  modInstances::addMod( __CLASS__, self::$_instance);
195  }
196  }
197  return self::$_instance;
198  }
199 
205  protected function isAdmin()
206  {
207  return isAdmin();
208  }
209 
215  protected function _getModules()
216  {
217  //adding exception handler for SQL errors
218  $_iDebug = self::_getConfigParam( '_iDebug' );
219 
220  global $ADODB_EXCEPTION;
221  $ADODB_EXCEPTION = 'oxAdoDbException';
222  include_once getShopBasePath() . 'core/adodblite/adodb-exceptions.inc.php';
223 
224  $sModules = '';
225  if ( $_iDebug == 2 || $_iDebug == 3 || $_iDebug == 4 || $_iDebug == 7 ) {
226  $sModules = 'perfmon';
227  }
228 
229  // log admin changes ?
230  if ( $this->isAdmin() && self::_getConfigParam( '_blLogChangesInAdmin' ) ) {
231  $sModules .= ( $sModules ? ':' : '' ) . 'oxadminlog';
232  }
233 
234  return $sModules;
235  }
236 
244  protected function _setUp( $oDb )
245  {
246  $_iDebug = self::_getConfigParam( '_iDebug' );
247  if ( $_iDebug == 2 || $_iDebug == 3 || $_iDebug == 4 || $_iDebug == 7 ) {
248  try {
249  $oDb->execute( 'truncate table adodb_logsql' );
250  } catch ( ADODB_Exception $e ) {
251  // nothing
252  }
253  if ( method_exists( $oDb, "logSQL" ) ) {
254  $oDb->logSQL( true );
255  }
256  }
257 
258  $oDb->cacheSecs = 60 * 10; // 10 minute caching
259  $oDb->execute( 'SET @@session.sql_mode = ""' );
260 
261  if ( self::_getConfigParam( '_iUtfMode' ) ) {
262  $oDb->execute( 'SET NAMES "utf8"' );
263  $oDb->execute( 'SET CHARACTER SET utf8' );
264  $oDb->execute( 'SET CHARACTER_SET_CONNECTION = utf8' );
265  $oDb->execute( 'SET CHARACTER_SET_DATABASE = utf8' );
266  $oDb->execute( 'SET character_set_results = utf8' );
267  $oDb->execute( 'SET character_set_server = utf8' );
268  } elseif ( ( $sConn = self::_getConfigParam('_sDefaultDatabaseConnection') ) != '' ) {
269  $oDb->execute( 'SET NAMES "' . $sConn . '"' );
270  }
271  }
272 
282  protected function _sendMail( $sEmail, $sSubject, $sBody )
283  {
284  include_once getShopBasePath() . 'core/phpmailer/class.phpmailer.php';
285  $oMailer = new phpmailer();
286  $oMailer->isMail();
287 
288  $oMailer->From = $sEmail;
289  $oMailer->AddAddress( $sEmail );
290  $oMailer->Subject = $sSubject;
291  $oMailer->Body = $sBody;
292  return $oMailer->send();
293  }
294 
302  protected function _notifyConnectionErrors( $oDb )
303  {
304  // notifying shop owner about connection problems
305  if ( ( $sAdminEmail = self::_getConfigParam( '_sAdminEmail' ) ) ) {
306  $sFailedShop = isset( $_REQUEST['shp'] ) ? addslashes( $_REQUEST['shp'] ) : 'Base shop';
307 
308  $sDate = date( 'l dS of F Y h:i:s A');
309  $sScript = $_SERVER['SCRIPT_NAME'] . '?' . $_SERVER['QUERY_STRING'];
310  $sReferer = $_SERVER['HTTP_REFERER'];
311 
312  //sending a message to admin
313  $sWarningSubject = 'Offline warning!';
314  $sWarningBody = "
315  Database error in OXID eShop:
316  Date: {$sDate}
317  Shop: {$sFailedShop}
318 
319  mysql error: " . $oDb->errorMsg()."
320  mysql error no: " . $oDb->errorNo()."
321 
322  Script: {$sScript}
323  Referer: {$sReferer}";
324 
325  $this->_sendMail( $sAdminEmail, $sWarningSubject, $sWarningBody );
326  }
327 
328  //only exception to default construction method
329  $oEx = new oxConnectionException();
330  $oEx->setMessage( 'EXCEPTION_CONNECTION_NODB' );
331  $oEx->setConnectionError( self::_getConfigParam( '_dbUser' ) . 's' . getShopBasePath() . $oDb->errorMsg() );
332  throw $oEx;
333  }
334 
343  protected function _onConnectionError( $oDb )
344  {
345  $sVerPrefix = '';
346  $sVerPrefix = '_ce';
347 
348 
349 
350  $sConfig = join( '', file( getShopBasePath().'config.inc.php' ) );
351 
352  if ( strpos( $sConfig, '<dbHost'.$sVerPrefix.'>' ) !== false &&
353  strpos( $sConfig, '<dbName'.$sVerPrefix.'>' ) !== false ) {
354  // pop to setup as there is something wrong
355  //oxRegistry::getUtils()->redirect( "setup/index.php", true, 302 );
356  $sHeaderCode = "HTTP/1.1 302 Found";
357  header( $sHeaderCode );
358  header( "Location: setup/index.php" );
359  header( "Connection: close" );
360  exit();
361  } else {
362  // notifying about connection problems
363  $this->_notifyConnectionErrors( $oDb );
364 
365  }
366  }
367 
368 
376  protected function _getDbInstance( $iInstType = false )
377  {
378  $sHost = self::_getConfigParam( "_dbHost" );
379  $sUser = self::_getConfigParam( "_dbUser" );
380  $sPwd = self::_getConfigParam( "_dbPwd" );
381  $sName = self::_getConfigParam( "_dbName" );
382  $sType = self::_getConfigParam( "_dbType" );
383 
384  $oDb = ADONewConnection( $sType, $this->_getModules() );
385 
386 
387  try {
388  $oDb->connect( $sHost, $sUser, $sPwd, $sName );
389  } catch( oxAdoDbException $e ) {
390  $this->_onConnectionError( $oDb );
391  }
392 
393  self::_setUp( $oDb );
394 
395  return $oDb;
396  }
397 
407  public static function getDb( $iFetchMode = oxDb::FETCH_MODE_NUM )
408  {
409  if ( defined( 'OXID_PHP_UNIT' ) ) {
410  if ( isset( modDB::$unitMOD ) && is_object( modDB::$unitMOD ) ) {
411  return modDB::$unitMOD;
412  }
413  }
414 
415  if ( self::$_oDB === null ) {
416 
417  $oInst = self::getInstance();
418 
419  //setting configuration on the first call
420  $oInst->setConfig( oxRegistry::get("oxConfigFile") );
421 
422  global $ADODB_SESSION_TBL,
423  $ADODB_SESSION_CONNECT,
424  $ADODB_SESSION_DRIVER,
425  $ADODB_SESSION_USER,
426  $ADODB_SESSION_PWD,
427  $ADODB_SESSION_DB,
428  $ADODB_SESS_LIFE,
429  $ADODB_SESS_DEBUG;
430 
431  // session related parameters. don't change.
432 
433  //Tomas
434  //the default setting is 3000 * 60, but actually changing this will give no effect as now redefinition of this constant
435  //appears after OXID custom settings are loaded and $ADODB_SESS_LIFE depends on user settings.
436  //You can find the redefinition of ADODB_SESS_LIFE @ oxconfig.php:: line ~ 390.
437  $ADODB_SESS_LIFE = 3000 * 60;
438  $ADODB_SESSION_TBL = "oxsessions";
439  $ADODB_SESSION_DRIVER = self::_getConfigParam( '_dbType' );
440  $ADODB_SESSION_USER = self::_getConfigParam( '_dbUser' );
441  $ADODB_SESSION_PWD = self::_getConfigParam( '_dbPwd' );
442  $ADODB_SESSION_DB = self::_getConfigParam( '_dbName' );
443  $ADODB_SESSION_CONNECT = self::_getConfigParam( '_dbHost' );
444  $ADODB_SESS_DEBUG = false;
445 
446  $oDb = new oxLegacyDb();
447  $oDbInst = $oInst->_getDbInstance();
448  $oDb->setConnection( $oDbInst );
449 
450  self::$_oDB = $oDb;
451  }
452 
453  self::$_oDB->setFetchMode( $iFetchMode );
454 
455  return self::$_oDB;
456  }
457 
465  public function quoteArray( $aStrArray )
466  {
467  $oDb = self::getDb();
468 
469  foreach ( $aStrArray as $sKey => $sString ) {
470  $aStrArray[$sKey] = $oDb->quote( $sString );
471  }
472  return $aStrArray;
473  }
474 
480  public function resetTblDescCache()
481  {
482  self::$_aTblDescCache = array();
483  }
484 
492  public function getTableDescription( $sTableName )
493  {
494  // simple cache
495  if ( isset( self::$_aTblDescCache[$sTableName] ) ) {
496  return self::$_aTblDescCache[$sTableName];
497  }
498 
499  $aFields = self::getDb()->MetaColumns( $sTableName );
500 
501  self::$_aTblDescCache[$sTableName] = $aFields;
502 
503  return $aFields;
504  }
505 
517  public function convertDBDateTime( $oObject, $blToTimeStamp = false, $blOnlyDate = false )
518  {
519  return oxRegistry::get('oxUtilsDate')->convertDBDateTime( $oObject, $blToTimeStamp, $blOnlyDate );
520  }
521 
532  public function convertDBTimestamp( $oObject, $blToTimeStamp = false )
533  {
534  return oxRegistry::get('oxUtilsDate')->convertDBTimestamp( $oObject, $blToTimeStamp );
535  }
536 
547  public function convertDBDate( $oObject, $blToTimeStamp = false )
548  {
549  return oxRegistry::get('oxUtilsDate')->convertDBDate( $oObject, $blToTimeStamp );
550  }
551 
560  public function isValidFieldName( $sField )
561  {
562  return ( boolean ) getStr()->preg_match( "#^[\w\d\._]*$#", $sField );
563  }
564 
578  protected function _setDefaultFormatedValue( $oObject, $sDate, $sLocalDateFormat, $sLocalTimeFormat, $blOnlyDate )
579  {
580  }
581 
591  protected function _defineAndCheckDefaultTimeValues( $blToTimeStamp )
592  {
593  }
594 
604  protected function _defineAndCheckDefaultDateValues( $blToTimeStamp )
605  {
606  }
607 
615  protected function _defaultDatePattern()
616  {
617  }
618 
626  protected function _defaultTimePattern()
627  {
628  }
629 
637  protected function _regexp2ValidateDateInput()
638  {
639  }
640 
648  protected function _regexp2ValidateTimeInput()
649  {
650  }
651 
659  protected function _defineDateFormattingRules()
660  {
661  // date formatting rules
662  $aDFormats = array("ISO" => array("Y-m-d", array(2, 3, 1), "0000-00-00"),
663  "EUR" => array("d.m.Y", array(2, 1, 3), "00.00.0000"),
664  "USA" => array("m/d/Y", array(1, 2, 3), "00/00/0000")
665  );
666  return $aDFormats;
667  }
668 
676  protected function _defineTimeFormattingRules()
677  {
678  // time formatting rules
679  $aTFormats = array("ISO" => array("H:i:s", array(1, 2, 3 ), "00:00:00"),
680  "EUR" => array("H.i.s", array(1, 2, 3 ), "00.00.00"),
681  "USA" => array("h:i:s A", array(1, 2, 3 ), "00:00:00 AM")
682  );
683  return $aTFormats;
684  }
685 
698  protected function _setDefaultDateTimeValue( $oObject, $sLocalDateFormat, $sLocalTimeFormat, $blOnlyDate )
699  {
700  $aDFormats = $this->_defineDateFormattingRules();
701  $aTFormats = $this->_defineTimeFormattingRules();
702 
703  $sReturn = $aDFormats[$sLocalDateFormat][2];
704  if ( !$blOnlyDate) {
705  $sReturn .= " ".$aTFormats[$sLocalTimeFormat][2];
706  }
707 
708  if ($oObject instanceof oxField) {
709  $oObject->setValue(trim($sReturn));
710  } else {
711  $oObject->value = trim($sReturn);
712  }
713  // increasing(decreasing) field length
714  $oObject->fldmax_length = strlen( $oObject->value);
715  }
716 
729  protected function _setDate( $oObject, $sDateFormat, $aDFields, $aDateMatches )
730  {
731  // formatting correct time value
732  $iTimestamp = mktime( 0, 0, 0, $aDateMatches[$aDFields[0]],
733  $aDateMatches[$aDFields[1]],
734  $aDateMatches[$aDFields[2]]);
735 
736  if ($oObject instanceof oxField) {
737  $oObject->setValue(@date( $sDateFormat, $iTimestamp ));
738  } else {
739  $oObject->value = @date( $sDateFormat, $iTimestamp );
740  }
741  // we should increase (decrease) field length
742  $oObject->fldmax_length = strlen( $oObject->value );
743  }
744 
760  protected function _formatCorrectTimeValue( $oObject, $sDateFormat, $sTimeFormat, $aDateMatches, $aTimeMatches, $aTFields, $aDFields )
761  {
762  // formatting correct time value
763  $iTimestamp = @mktime( (int) $aTimeMatches[$aTFields[0]],
764  (int) $aTimeMatches[$aTFields[1]],
765  (int) $aTimeMatches[$aTFields[2]],
766  (int) $aDateMatches[$aDFields[0]],
767  (int) $aDateMatches[$aDFields[1]],
768  (int) $aDateMatches[$aDFields[2]] );
769 
770  if ($oObject instanceof oxField) {
771  $oObject->setValue(trim( @date( $sDateFormat." ".$sTimeFormat, $iTimestamp ) ));
772  } else {
773  $oObject->value = trim( @date( $sDateFormat." ".$sTimeFormat, $iTimestamp ) );
774  }
775 
776  // we should increase (decrease) field length
777  $oObject->fldmax_length = strlen( $oObject->value );
778  }
779 
785  protected function _getConnectionId()
786  {
787  return self::getDb()->getDb()->connectionId;
788  }
789 
797  public function escapeString( $sString )
798  {
799  if ( 'mysql' == self::_getConfigParam( "_dbType" )) {
800  return mysql_real_escape_string( $sString, $this->_getConnectionId() );
801  } elseif ( 'mysqli' == self::_getConfigParam( "_dbType" )) {
802  return mysqli_real_escape_string( $this->_getConnectionId(), $sString );
803  } else {
804  return mysql_real_escape_string( $sString, $this->_getConnectionId() );
805  }
806  }
807 
817  public function updateViews( $aTables = null )
818  {
819  $oMetaData = oxNew('oxDbMetaDataHandler');
820  return $oMetaData->updateViews();
821  }
822 }