OXID eShop CE  4.10.1
 All Classes Namespaces 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 {
12 
18  const FETCH_MODE_NUM = ADODB_FETCH_NUM;
19 
25  const FETCH_MODE_ASSOC = ADODB_FETCH_ASSOC;
26 
32  public static $configSet = false;
33 
39  protected static $_instance = null;
40 
46  protected static $_oDB = null;
47 
53  protected static $_aTblDescCache = array();
54 
60  private static $_dbType = '';
61 
67  private static $_dbUser = '';
68 
74  private static $_dbPwd = '';
75 
81  private static $_dbName = '';
82 
88  private static $_dbHost = '';
89 
95  private static $_iDebug = 0;
96 
102  private static $_blLogChangesInAdmin = false;
103 
109  private static $_iUtfMode = 0;
110 
116  private static $_sDefaultDatabaseConnection = null;
117 
123  private static $_aSlaveHosts;
124 
130  private static $_sAdminEmail;
131 
139  private static $_iMasterSlaveBalance;
140 
146  private static $_sLocalTimeFormat;
147 
153  private static $_sLocalDateFormat;
154 
160  public static function setConfig($oConfig)
161  {
162  self::$_dbType = $oConfig->getVar('dbType');
163  self::$_dbUser = $oConfig->getVar('dbUser');
164  self::$_dbPwd = $oConfig->getVar('dbPwd');
165  self::$_dbName = $oConfig->getVar('dbName');
166  self::$_dbHost = $oConfig->getVar('dbHost');
167  self::$_iDebug = $oConfig->getVar('iDebug');
168  self::$_blLogChangesInAdmin = $oConfig->getVar('blLogChangesInAdmin');
169  self::$_iUtfMode = $oConfig->getVar('iUtfMode');
170  self::$_sDefaultDatabaseConnection = $oConfig->getVar('sDefaultDatabaseConnection');
171  self::$_aSlaveHosts = $oConfig->getVar('aSlaveHosts');
172  //deprecated since v5.3.0 (2016-06-17). Different solution in 6.0.
173  self::$_iMasterSlaveBalance = $oConfig->getVar('iMasterSlaveBalance');
174  //end deprecated
175  self::$_sAdminEmail = $oConfig->getVar('sAdminEmail');
176  self::$_sLocalTimeFormat = $oConfig->getVar('sLocalTimeFormat');
177  self::$_sLocalDateFormat = $oConfig->getVar('sLocalDateFormat');
178  }
179 
187  protected static function _getConfigParam($sConfigName)
188  {
189  if (isset(self::$$sConfigName)) {
190  return self::$$sConfigName;
191  }
192 
193  return null;
194  }
195 
201  public static function getInstance()
202  {
203  // disable caching for test modules
204  if (defined('OXID_PHP_UNIT')) {
205  self::$_instance = modInstances::getMod(__CLASS__);
206  }
207 
208  if (!self::$_instance instanceof oxDb) {
209 
210  //do not use simple oxNew here as it goes to eternal cycle
211  self::$_instance = new oxDb();
212 
213  if (defined('OXID_PHP_UNIT')) {
214  modInstances::addMod(__CLASS__, self::$_instance);
215  }
216  }
217 
218  return self::$_instance;
219  }
220 
226  protected function isAdmin()
227  {
228  return isAdmin();
229  }
230 
236  protected function _getModules()
237  {
238  $_iDebug = self::_getConfigParam('_iDebug');
239 
241 
242  $sModules = '';
243  if ($_iDebug == 2 || $_iDebug == 3 || $_iDebug == 4 || $_iDebug == 7) {
244  $sModules = 'perfmon';
245  }
246 
247  // log admin changes ?
248  if ($this->isAdmin() && self::_getConfigParam('_blLogChangesInAdmin')) {
249  $sModules .= ($sModules ? ':' : '') . 'oxadminlog';
250  }
251 
252  return $sModules;
253  }
254 
258  protected function _registerAdoDbExceptionHandler()
259  {
260  global $ADODB_EXCEPTION;
261  $ADODB_EXCEPTION = 'oxAdoDbException';
262 
263  include_once getShopBasePath() . 'core/adodblite/adodb-exceptions.inc.php';
264  }
265 
271  protected function _setUp($oDb)
272  {
273  // @deprecated since v5.3.0 (2016-06-07).
274  // The SQL logging feature is deprecated. This feature will be removed.
275  $_iDebug = self::_getConfigParam('_iDebug');
276  if ($_iDebug == 2 || $_iDebug == 3 || $_iDebug == 4 || $_iDebug == 7) {
277  try {
278  $oDb->execute('truncate table adodb_logsql');
279  } catch (ADODB_Exception $e) {
280  // nothing
281  }
282  if (method_exists($oDb, "logSQL")) {
283  $oDb->logSQL(true);
284  }
285  }
286  // END deprecated
287 
288  $oDb->cacheSecs = 60 * 10; // 10 minute caching
289  $oDb->execute('SET @@session.sql_mode = ""');
290 
291  if (self::_getConfigParam('_iUtfMode')) {
292  $oDb->execute('SET NAMES "utf8"');
293  $oDb->execute('SET CHARACTER SET utf8');
294  $oDb->execute('SET CHARACTER_SET_CONNECTION = utf8');
295  $oDb->execute('SET CHARACTER_SET_DATABASE = utf8');
296  $oDb->execute('SET character_set_results = utf8');
297  $oDb->execute('SET character_set_server = utf8');
298  } elseif (($sConn = self::_getConfigParam('_sDefaultDatabaseConnection')) != '') {
299  $oDb->execute('SET NAMES "' . $sConn . '"');
300  }
301  }
302 
312  protected function _sendMail($sEmail, $sSubject, $sBody)
313  {
314  include_once getShopBasePath() . 'core/phpmailer/class.phpmailer.php';
315  include_once getShopBasePath() . 'core/phpmailer/class.smtp.php';
316  $oMailer = new phpmailer();
317  $oMailer->isMail();
318 
319  $oMailer->From = $sEmail;
320  $oMailer->AddAddress($sEmail);
321  $oMailer->Subject = $sSubject;
322  $oMailer->Body = $sBody;
323 
324  return $oMailer->send();
325  }
326 
332  protected function _notifyConnectionErrors($oDb)
333  {
334  // notifying shop owner about connection problems
335  if (($sAdminEmail = self::_getConfigParam('_sAdminEmail'))) {
336  $sFailedShop = isset($_REQUEST['shp']) ? addslashes($_REQUEST['shp']) : 'Base shop';
337 
338  $sDate = date('l dS of F Y h:i:s A');
339  $sScript = $_SERVER['SCRIPT_NAME'] . '?' . $_SERVER['QUERY_STRING'];
340  $sReferer = $_SERVER['HTTP_REFERER'];
341 
342  //sending a message to admin
343  $sWarningSubject = 'Offline warning!';
344  $sWarningBody = "
345  Database error in OXID eShop:
346  Date: {$sDate}
347  Shop: {$sFailedShop}
348 
349  mysql error: " . $oDb->errorMsg() . "
350  mysql error no: " . $oDb->errorNo() . "
351 
352  Script: {$sScript}
353  Referer: {$sReferer}";
354 
355  $this->_sendMail($sAdminEmail, $sWarningSubject, $sWarningBody);
356  }
357 
358  //only exception to default construction method
359  $oEx = new oxConnectionException();
360  $oEx->setMessage('EXCEPTION_CONNECTION_NODB');
361  $oEx->setConnectionError(self::_getConfigParam('_dbUser') . 's' . getShopBasePath() . $oDb->errorMsg());
362  throw $oEx;
363  }
364 
371  protected function _onConnectionError($oDb)
372  {
373  $sVerPrefix = '';
374  $sVerPrefix = '_ce';
375 
376 
377  $sConfig = join('', file(getShopBasePath() . 'config.inc.php'));
378 
379  if (strpos($sConfig, '<dbHost' . $sVerPrefix . '>') !== false &&
380  strpos($sConfig, '<dbName' . $sVerPrefix . '>') !== false
381  ) {
382  // pop to setup as there is something wrong
383  //oxRegistry::getUtils()->redirect( "setup/index.php", true, 302 );
384  $sHeaderCode = "HTTP/1.1 302 Found";
385  header($sHeaderCode);
386  header("Location: setup/index.php");
387  header("Connection: close");
388  exit();
389  } else {
390  // notifying about connection problems
391  $this->_notifyConnectionErrors($oDb);
392 
393  }
394  }
395 
396 
404  protected function _getDbInstance($iInstType = false)
405  {
406  $sHost = self::_getConfigParam("_dbHost");
407  $sUser = self::_getConfigParam("_dbUser");
408  $sPwd = self::_getConfigParam("_dbPwd");
409  $sName = self::_getConfigParam("_dbName");
410  $sType = self::_getConfigParam("_dbType");
411 
412  $oDb = ADONewConnection($sType, $this->_getModules());
413 
414 
415  try {
416  $oDb->connect($sHost, $sUser, $sPwd, $sName);
417  } catch (oxAdoDbException $e) {
418  $this->_onConnectionError($oDb);
419  }
420 
421  self::_setUp($oDb);
422 
423  return $oDb;
424  }
425 
435  public static function getDb($iFetchMode = oxDb::FETCH_MODE_NUM)
436  {
437  if (defined('OXID_PHP_UNIT')) {
438  if (isset(modDB::$unitMOD) && is_object(modDB::$unitMOD)) {
439  return modDB::$unitMOD;
440  }
441  }
442 
443  if (self::$_oDB === null) {
444 
445  $oInst = self::getInstance();
446 
447  //setting configuration on the first call
448  $oInst->setConfig(oxRegistry::get("oxConfigFile"));
449 
450  // @deprecated since v5.3.0 (2016-06-07).
451  // As of v6.0 it is not longer possible to use the database for PHP session handling.
452  global $ADODB_SESSION_TBL,
453  $ADODB_SESSION_CONNECT,
454  $ADODB_SESSION_DRIVER,
455  $ADODB_SESSION_USER,
456  $ADODB_SESSION_PWD,
457  $ADODB_SESSION_DB,
458  $ADODB_SESS_LIFE,
459  $ADODB_SESS_DEBUG;
460 
461  // session related parameters. don't change.
462 
463  //Tomas
464  //the default setting is 3000 * 60, but actually changing this will give no effect as now redefinition of this constant
465  //appears after OXID custom settings are loaded and $ADODB_SESS_LIFE depends on user settings.
466  //You can find the redefinition of ADODB_SESS_LIFE @ oxconfig.php:: line ~ 390.
467  $ADODB_SESS_LIFE = 3000 * 60;
468  $ADODB_SESSION_TBL = "oxsessions";
469  $ADODB_SESSION_DRIVER = self::_getConfigParam('_dbType');
470  $ADODB_SESSION_USER = self::_getConfigParam('_dbUser');
471  $ADODB_SESSION_PWD = self::_getConfigParam('_dbPwd');
472  $ADODB_SESSION_DB = self::_getConfigParam('_dbName');
473  $ADODB_SESSION_CONNECT = self::_getConfigParam('_dbHost');
474  $ADODB_SESS_DEBUG = false;
475  // END deprecated
476 
477 
478  $oDb = new oxLegacyDb();
479  $oDbInst = $oInst->_getDbInstance();
480  $oDb->setConnection($oDbInst);
481 
482  self::$_oDB = $oDb;
483  }
484 
485  self::$_oDB->setFetchMode($iFetchMode);
486 
487  return self::$_oDB;
488  }
489 
499  public function quoteArray($aStrArray)
500  {
501  return self::getDb()->quoteArray($aStrArray);
502  }
503 
509  public function resetTblDescCache()
510  {
511  self::$_aTblDescCache = array();
512  }
513 
521  public function getTableDescription($sTableName)
522  {
523  // simple cache
524  if (isset(self::$_aTblDescCache[$sTableName])) {
525  return self::$_aTblDescCache[$sTableName];
526  }
527 
528  $aFields = self::getDb()->MetaColumns($sTableName);
529 
530  self::$_aTblDescCache[$sTableName] = $aFields;
531 
532  return $aFields;
533  }
534 
545  public function isValidFieldName($sField)
546  {
547  return ( boolean ) getStr()->preg_match("#^[\w\d\._]*$#", $sField);
548  }
549 
555  protected function _getConnectionId()
556  {
557  return self::getDb()->getDb()->connectionId;
558  }
559 
570  public function escapeString($sString)
571  {
572  if ('mysql' == self::_getConfigParam("_dbType")) {
573  return mysql_real_escape_string($sString, $this->_getConnectionId());
574  } elseif ('mysqli' == self::_getConfigParam("_dbType")) {
575  return mysqli_real_escape_string($this->_getConnectionId(), $sString);
576  } else {
577  return mysql_real_escape_string($sString, $this->_getConnectionId());
578  }
579  }
580 }