00001 <?php
00002
00006 class oxDb extends oxSuperCfg
00007 {
00013 private static $_instance = null;
00014
00020 private static $_oDB = null;
00021
00027 protected static $_aTblDescCache = array();
00028
00034 public static function getInstance()
00035 {
00036
00037 if ( defined( 'OXID_PHP_UNIT' ) ) {
00038 static $inst = array();
00039 self::$_instance = $inst[oxClassCacheKey()];
00040 }
00041
00042
00043 if ( !self::$_instance instanceof oxDb ) {
00044
00045
00046 self::$_instance = oxNew( 'oxdb' );
00047
00048 if ( defined( 'OXID_PHP_UNIT' ) ) {
00049 $inst[oxClassCacheKey()] = self::$_instance;
00050 }
00051 }
00052 return self::$_instance;
00053 }
00054
00064 public static function getDb( $blAssoc = false )
00065 {
00066 if ( defined( 'OXID_PHP_UNIT' ) ) {
00067 if ( isset( modDB::$unitMOD ) && is_object( modDB::$unitMOD ) ) {
00068 return modDB::$unitMOD;
00069 }
00070 }
00071
00072 global $ADODB_FETCH_MODE;
00073
00074 if ( $blAssoc )
00075 $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
00076 else
00077 $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
00078
00079 if ( self::$_oDB !== null ) {
00080 return self::$_oDB;
00081 }
00082
00083 global $ADODB_CACHE_DIR;
00084 global $ADODB_DRIVER,
00085 $ADODB_SESSION_TBL,
00086 $ADODB_SESSION_CONNECT,
00087 $ADODB_SESSION_DRIVER,
00088 $ADODB_SESSION_USER,
00089 $ADODB_SESSION_PWD,
00090 $ADODB_SESSION_DB,
00091 $ADODB_SESS_LIFE,
00092 $ADODB_SESS_DEBUG;
00093
00094
00095 $myConfig = self::getInstance()->getConfig();
00096 $iDebug = $myConfig->getConfigParam( 'iDebug' );
00097 if ( $iDebug ) {
00098 require_once getShopBasePath() . 'core/adodblite/adodb-exceptions.inc.php';
00099 }
00100
00101
00102
00103
00104
00105
00106
00107 $ADODB_SESS_LIFE = 3000 * 60;
00108 $ADODB_SESSION_TBL = "oxsessions";
00109 $ADODB_SESSION_DRIVER = $ADODB_DRIVER;
00110 $ADODB_SESSION_USER = $myConfig->getConfigParam( 'dbUser' );
00111 $ADODB_SESSION_PWD = $myConfig->getConfigParam( 'dbPwd' );
00112 $ADODB_SESSION_DB = $myConfig->getConfigParam( 'dbName' );
00113 $ADODB_SESSION_CONNECT = $myConfig->getConfigParam( 'dbHost' );
00114 $ADODB_SESS_DEBUG = false;
00115 $ADODB_CACHE_DIR = $myConfig->getConfigParam( 'sCompileDir' );
00116
00117 $sModules = '';
00118 if ( $iDebug == 2 || $iDebug == 3 || $iDebug == 4 || $iDebug == 7 ) {
00119 $sModules = 'perfmon';
00120 }
00121
00122
00123 if ( $myConfig->isAdmin() && $myConfig->getConfigParam( 'blLogChangesInAdmin' ) ) {
00124 $sModules = ( $sModules ? ':' : '' ) . 'oxadminlog';
00125 }
00126
00127 self::$_oDB = ADONewConnection( $myConfig->getConfigParam( 'dbType' ), $sModules );
00128
00129 $sVerPrefix = '';
00130 $sVerPrefix = '_ce';
00131
00132 if ( !self::$_oDB->connect( $myConfig->getConfigParam( 'dbHost' ), $myConfig->getConfigParam( 'dbUser' ), $myConfig->getConfigParam( 'dbPwd' ), $myConfig->getConfigParam( 'dbName' ) ) ) {
00133 $sConfig = join( '', file( getShopBasePath().'config.inc.php' ) );
00134 if ( strpos( $sConfig, '<dbHost'.$sVerPrefix.'>' ) !== false &&
00135 strpos( $sConfig, '<dbName'.$sVerPrefix.'>' ) !== false ) {
00136 header( 'location:setup/index.php' );
00137 exit();
00138 } else {
00139
00140
00141 $sFailedShop = isset( $_REQUEST['shp'] )?addslashes( $_REQUEST['shp'] ):'Base shop';
00142
00143 $sDate = date( 'l dS of F Y h:i:s A');
00144 $sScript = $_SERVER['SCRIPT_NAME'].'?'.$_SERVER['QUERY_STRING'];
00145 $sReferer = $_SERVER['HTTP_REFERER'];
00146
00147
00148 $sWarningSubject = 'Offline warning!';
00149 $sWarningBody = "
00150 Database error in OXID eShop:
00151 Date: $sDate
00152 Shop: $sFailedShop
00153
00154 mysql error: ".self::$_oDB->errorMsg()."
00155 mysql error no: ".self::$_oDB->errorNo()."
00156
00157 Script: $sScript
00158 Referer: $sReferer";
00159
00160 if ( ( $sAdminEmail = $myConfig->getConfigParam( 'sAdminEmail' ) ) ) {
00161 include 'core/phpmailer/class.phpmailer.php';
00162
00163 $oMailer = new phpmailer();
00164 $oMailer->isMail();
00165 $oMailer->From = $sAdminEmail;
00166 $oMailer->AddAddress( $sAdminEmail );
00167 $oMailer->Subject = $sWarningSubject;
00168 $oMailer->Body = $sWarningBody;
00169 $oMailer->send();
00170 }
00171
00172
00173 $oEx = new oxConnectionException();
00174 $oEx->setMessage( 'EXCEPTION_CONNECTION_NODB' );
00175 $oEx->setConnectionError( $myConfig->getConfigParam( 'dbUser' ).'s'.getShopBasePath().self::$_oDB->errorMsg() );
00176 throw $oEx;
00177 }
00178 }
00179
00180 if ( $iDebug == 2 || $iDebug == 3 || $iDebug == 4 || $iDebug == 7 ) {
00181 try {
00182 self::$_oDB->execute('truncate table adodb_logsql;');
00183 } catch (ADODB_Exception $e) {
00184
00185 }
00186 self::$_oDB->logSQL( true );
00187 }
00188
00189 self::$_oDB->cacheSecs = 60 * 10;
00190 self::$_oDB->execute( 'SET @@session.sql_mode = ""' );
00191
00192 return self::$_oDB;
00193 }
00194
00202 public function getMultiLangFieldName( $sField )
00203 {
00204
00205
00206
00207
00208
00209
00210 return $sField . oxLang::getInstance()->getLanguageTag();
00211 }
00212
00221 public function isQuoteNeeded( $sFieldtype)
00222 {
00223 $aTypesWoQuotes = array('int', 'decimal', 'float', 'tinyint', 'smallint', 'mediumint', 'bigint', 'double');
00224 return !in_array( $sFieldtype, $aTypesWoQuotes);
00225 }
00226
00234 public function getTableDescription( $sTableName )
00235 {
00236
00237 if ( isset( self::$_aTblDescCache[$sTableName] ) ) {
00238 return self::$_aTblDescCache[$sTableName];
00239 }
00240
00241 $aFields = self::getDb()->MetaColumns( $sTableName );
00242
00243 self::$_aTblDescCache[$sTableName] = $aFields;
00244
00245 return $aFields;
00246 }
00247
00257 public function convertDBDateTime( $oObject, $blToTimeStamp = false, $blOnlyDate = false )
00258 {
00259 $sDate = $oObject->value;
00260
00261
00262 $sLocalDateFormat = $this->_defineAndCheckDefaultDateValues( $blToTimeStamp );
00263 $sLocalTimeFormat = $this->_defineAndCheckDefaultTimeValues( $blToTimeStamp );
00264
00265
00266 $aDefDatePatterns = $this->_defaultDatePattern();
00267
00268
00269 $aDatePatterns = $this->_regexp2ValidateDateInput();
00270 $aTimePatterns = $this->_regexp2ValidateTimeInput();
00271
00272
00273 $aDFormats = $this->_defineDateFormattingRules();
00274 $aTFormats = $this->_defineTimeFormattingRules();
00275
00276
00277 if ( !$sDate) {
00278 $this->_setDefaultDateTimeValue($oObject, $sLocalDateFormat, $sLocalTimeFormat, $blOnlyDate);
00279 return $oObject->value;
00280 }
00281
00282 $blDefDateFound = false;
00283
00284
00285 foreach ( array_keys( $aDefDatePatterns ) as $sDefDatePattern ) {
00286 if ( preg_match( $sDefDatePattern, $sDate)) {
00287 $blDefDateFound = true;
00288 break;
00289 }
00290 }
00291
00292
00293 if ( $blDefDateFound) {
00294 $this->_setDefaultFormatedValue($oObject, $sDate, $sLocalDateFormat, $sLocalTimeFormat, $blOnlyDate);
00295 return $oObject->value;
00296 }
00297
00298 $blDateFound = false;
00299 $blTimeFound = false;
00300 $aDateMatches = array();
00301 $aTimeMatches = array();
00302
00303
00304 foreach ( $aDatePatterns as $sPattern => $sType) {
00305 if ( preg_match( $sPattern, $sDate, $aDateMatches)) {
00306 $blDateFound = true;
00307
00308
00309 $sDateFormat = $aDFormats[$sLocalDateFormat][0];
00310 $aDFields = $aDFormats[$sType][1];
00311 break;
00312 }
00313 }
00314
00315
00316 if ( !$blDateFound) {
00317 return $sDate;
00318 }
00319
00320 if ( $blOnlyDate) {
00321 $this->_setDate($oObject, $sDateFormat, $aDFields, $aDateMatches);
00322 return $oObject->value;
00323 }
00324
00325
00326 foreach ( $aTimePatterns as $sPattern => $sType) {
00327 if ( preg_match( $sPattern, $sDate, $aTimeMatches)) {
00328 $blTimeFound = true;
00329
00330
00331 $sTimeFormat = $aTFormats[$sLocalTimeFormat][0];
00332 $aTFields = $aTFormats[$sType][1];
00333
00334
00335 if ( $sType == "USA" && isset($aTimeMatches[4])) {
00336 $iIntVal = (int) $aTimeMatches[1];
00337 if ( $aTimeMatches[4] == "PM") {
00338 if ( $iIntVal < 13) {
00339 $iIntVal += 12;
00340 }
00341 } elseif ( $aTimeMatches[4] == "AM" && $aTimeMatches[1] == "12") {
00342 $iIntVal = 0;
00343 }
00344
00345 $aTimeMatches[1] = sprintf("%02d", $iIntVal);
00346 }
00347
00348 break;
00349 }
00350 }
00351
00352 if ( !$blTimeFound) {
00353
00354
00355 $this->_setDate($oObject, $sDateFormat, $aDFields, $aDateMatches);
00356 return $oObject->value;
00357 }
00358
00359 $this->_formatCorrectTimeValue($oObject, $sDateFormat, $sTimeFormat, $aDateMatches, $aTimeMatches, $aTFields, $aDFields);
00360
00361
00362 if ( !$oObject->fldmax_length) {
00363 return $this->convertDBDateTime( $oObject, $blToTimeStamp, $blOnlyDate);
00364 }
00365 return $oObject->value;
00366 }
00367
00376 public function convertDBTimestamp( $oObject, $blToTimeStamp = false )
00377 {
00378
00379 $sSQLTimeStampPattern = "/^([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})$/";
00380 $sISOTimeStampPattern = "/^([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2})$/";
00381 $aMatches = array();
00382
00383
00384 if ( $blToTimeStamp) {
00385
00386 $this->convertDBDateTime( $oObject, $blToTimeStamp );
00387
00388 if ( preg_match( $sISOTimeStampPattern, $oObject->value, $aMatches)) {
00389
00390 $oObject->setValue($aMatches[1].$aMatches[2].$aMatches[3].$aMatches[4].$aMatches[5].$aMatches[6]);
00391 $oObject->fldmax_length = strlen( $oObject->value);
00392 return $oObject->value;
00393 }
00394 } else {
00395
00396
00397
00398 if ( preg_match( $sSQLTimeStampPattern, $oObject->value, $aMatches ) ) {
00399 $iTimestamp = mktime( $aMatches[4],
00400 $aMatches[5],
00401 $aMatches[6],
00402 $aMatches[2],
00403 $aMatches[3],
00404 $aMatches[1]);
00405 if ( !$iTimestamp ) {
00406 $iTimestamp = "0";
00407 }
00408
00409 $oObject->setValue(trim( date( "Y-m-d H:i:s", $iTimestamp)));
00410 $oObject->fldmax_length = strlen( $oObject->value);
00411 $this->convertDBDateTime( $oObject, $blToTimeStamp );
00412 return $oObject->value;
00413 }
00414 }
00415 }
00416
00425 public function convertDBDate( $oObject, $blToTimeStamp = false )
00426 {
00427 return $this->convertDBDateTime( $oObject, $blToTimeStamp, true );
00428 }
00429
00437 public function createSQLList( $aArray )
00438 {
00439 $sRet = "";
00440
00441 $blSep = false;
00442 foreach ( $aArray as $aToken) {
00443 if ( !$aToken[0]) {
00444 continue;
00445 }
00446 if ( $blSep) {
00447 $sRet .= ",";
00448 }
00449 $sRet .= "'".$aToken[0]."'";
00450 $blSep = true;
00451 }
00452 return $sRet;
00453 }
00454
00460 static public function startTransaction()
00461 {
00462 self::$_oDB->execute( 'START TRANSACTION' );
00463 }
00464
00470 static public function commitTransaction()
00471 {
00472 self::$_oDB->execute( 'COMMIT' );
00473 }
00474
00480 static public function rollbackTransaction()
00481 {
00482 self::$_oDB->execute( 'ROLLBACK' );
00483 }
00484
00493 static public function setTransactionIsolationLevel( $sLevel = null )
00494 {
00495 $aLevels = array( 'READ UNCOMMITTED', 'READ COMMITTED', 'REPEATABLE READ', 'SERIALIZABLE' );
00496
00497 if (in_array(strtoupper($sLevel), $aLevels)) {
00498 self::$_oDB->execute( 'SET TRANSACTION ISOLATION LEVEL ' . $sLevel );
00499 }
00500 }
00501
00502
00511 public function isValidFieldName( $sField )
00512 {
00513 return ( boolean ) preg_match( "#^[\w\d\._]*$#", $sField );
00514 }
00515
00527 protected function _setDefaultFormatedValue( $oObject, $sDate, $sLocalDateFormat, $sLocalTimeFormat, $blOnlyDate )
00528 {
00529 $aDefTimePatterns = $this->_defaultTimePattern();
00530 $aDFormats = $this->_defineDateFormattingRules();
00531 $aTFormats = $this->_defineTimeFormattingRules();
00532
00533 foreach ( array_keys( $aDefTimePatterns ) as $sDefTimePattern ) {
00534 if ( preg_match( $sDefTimePattern, $sDate ) ) {
00535 $blDefTimeFound = true;
00536 break;
00537 }
00538 }
00539
00540
00541 if ( $blOnlyDate) {
00542 $oObject->setValue(trim( $aDFormats[$sLocalDateFormat][2] ));
00543
00544 $oObject->fldmax_length = strlen( $oObject->value );
00545 return ;
00546 } elseif ( $blDefTimeFound ) {
00547
00548 $oObject->setValue(trim( $aDFormats[$sLocalDateFormat][2] . " " . $aTFormats[$sLocalTimeFormat][2] ));
00549
00550 $oObject->fldmax_length = strlen( $oObject->value );
00551 return ;
00552 }
00553 }
00554
00562 protected function _defineAndCheckDefaultTimeValues( $blToTimeStamp )
00563 {
00564
00565
00566 $sLocalTimeFormat = $this->getConfig()->getConfigParam( 'sLocalTimeFormat' );
00567 if ( !$sLocalTimeFormat || $blToTimeStamp) {
00568 $sLocalTimeFormat = "ISO";
00569 }
00570 return $sLocalTimeFormat;
00571 }
00572
00580 protected function _defineAndCheckDefaultDateValues( $blToTimeStamp )
00581 {
00582
00583
00584 $sLocalDateFormat = $this->getConfig()->getConfigParam( 'sLocalDateFormat' );
00585 if ( !$sLocalDateFormat || $blToTimeStamp) {
00586 $sLocalDateFormat = "ISO";
00587 }
00588 return $sLocalDateFormat;
00589 }
00590
00596 protected function _defaultDatePattern()
00597 {
00598
00599 $aDefDatePatterns = array("/^0000-00-00/" => "ISO",
00600 "/^00\.00\.0000/" => "EUR",
00601 "/^00\/00\/0000/" => "USA"
00602 );
00603 return $aDefDatePatterns;
00604 }
00605
00611 protected function _defaultTimePattern()
00612 {
00613
00614 $aDefTimePatterns = array("/00:00:00$/" => "ISO",
00615 "/00\.00\.00$/" => "EUR",
00616 "/00:00:00 AM$/" => "USA"
00617 );
00618 return $aDefTimePatterns;
00619 }
00620
00626 protected function _regexp2ValidateDateInput()
00627 {
00628
00629 $aDatePatterns = array("/^([0-9]{4})-([0-9]{2})-([0-9]{2})/" => "ISO",
00630 "/^([0-9]{2})\.([0-9]{2})\.([0-9]{4})/" => "EUR",
00631 "/^([0-9]{2})\/([0-9]{2})\/([0-9]{4})/" => "USA"
00632 );
00633 return $aDatePatterns;
00634 }
00635
00641 protected function _regexp2ValidateTimeInput()
00642 {
00643
00644 $aTimePatterns = array("/([0-9]{2}):([0-9]{2}):([0-9]{2})$/" => "ISO",
00645 "/([0-9]{2})\.([0-9]{2})\.([0-9]{2})$/" => "EUR",
00646 "/([0-9]{2}):([0-9]{2}):([0-9]{2}) ([AP]{1}[M]{1})$/" => "USA"
00647 );
00648 return $aTimePatterns;
00649 }
00650
00656 protected function _defineDateFormattingRules()
00657 {
00658
00659 $aDFormats = array("ISO" => array("Y-m-d", array(2, 3, 1), "0000-00-00"),
00660 "EUR" => array("d.m.Y", array(2, 1, 3), "00.00.0000"),
00661 "USA" => array("m/d/Y", array(1, 2, 3), "00/00/0000")
00662 );
00663 return $aDFormats;
00664 }
00665
00671 protected function _defineTimeFormattingRules()
00672 {
00673
00674 $aTFormats = array("ISO" => array("H:i:s", array(1, 2, 3 ), "00:00:00"),
00675 "EUR" => array("H.i.s", array(1, 2, 3 ), "00.00.00"),
00676 "USA" => array("h:i:s A", array(1, 2, 3 ), "00:00:00 AM")
00677 );
00678 return $aTFormats;
00679 }
00680
00691 protected function _setDefaultDateTimeValue( $oObject, $sLocalDateFormat, $sLocalTimeFormat, $blOnlyDate )
00692 {
00693 $aDFormats = $this->_defineDateFormattingRules();
00694 $aTFormats = $this->_defineTimeFormattingRules();
00695
00696 $sReturn = $aDFormats[$sLocalDateFormat][2];
00697 if ( !$blOnlyDate) {
00698 $sReturn .= " ".$aTFormats[$sLocalTimeFormat][2];
00699 }
00700
00701 if ($oObject instanceof oxField) {
00702 $oObject->setValue(trim($sReturn));
00703 } else {
00704 $oObject->value = trim($sReturn);
00705 }
00706
00707 $oObject->fldmax_length = strlen( $oObject->value);
00708 }
00709
00720 protected function _setDate( $oObject, $sDateFormat, $aDFields, $aDateMatches )
00721 {
00722
00723 $iTimestamp = mktime( 0, 0, 0, $aDateMatches[$aDFields[0]],
00724 $aDateMatches[$aDFields[1]],
00725 $aDateMatches[$aDFields[2]]);
00726
00727 if ($oObject instanceof oxField) {
00728 $oObject->setValue(@date( $sDateFormat, $iTimestamp ));
00729 } else {
00730 $oObject->value = @date( $sDateFormat, $iTimestamp );
00731 }
00732
00733 $oObject->fldmax_length = strlen( $oObject->value );
00734 }
00735
00749 protected function _formatCorrectTimeValue( $oObject, $sDateFormat, $sTimeFormat, $aDateMatches, $aTimeMatches, $aTFields, $aDFields )
00750 {
00751
00752 $iTimestamp = @mktime( (int) $aTimeMatches[$aTFields[0]],
00753 (int) $aTimeMatches[$aTFields[1]],
00754 (int) $aTimeMatches[$aTFields[2]],
00755 (int) $aDateMatches[$aDFields[0]],
00756 (int) $aDateMatches[$aDFields[1]],
00757 (int) $aDateMatches[$aDFields[2]] );
00758
00759 if ($oObject instanceof oxField) {
00760 $oObject->setValue(trim( @date( $sDateFormat." ".$sTimeFormat, $iTimestamp ) ));
00761 } else {
00762 $oObject->value = trim( @date( $sDateFormat." ".$sTimeFormat, $iTimestamp ) );
00763 }
00764
00765
00766 $oObject->fldmax_length = strlen( $oObject->value );
00767 }
00768
00769 }