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 if ( $myConfig->isUtf() ) {
00193 self::$_oDB->execute( 'SET NAMES "utf8"' );
00194 self::$_oDB->execute( 'SET CHARACTER SET utf8' );
00195 self::$_oDB->execute( 'SET CHARACTER_SET_CONNECTION = utf8' );
00196 self::$_oDB->execute( 'SET CHARACTER_SET_DATABASE = utf8' );
00197 self::$_oDB->execute( 'SET character_set_results = utf8' );
00198 self::$_oDB->execute( 'SET character_set_server = utf8' );
00199 }
00200
00201 return self::$_oDB;
00202 }
00203
00211 public function getMultiLangFieldName( $sField )
00212 {
00213
00214
00215
00216
00217
00218
00219 return $sField . oxLang::getInstance()->getLanguageTag();
00220 }
00221
00230 public function isQuoteNeeded( $sFieldtype)
00231 {
00232 $aTypesWoQuotes = array('int', 'decimal', 'float', 'tinyint', 'smallint', 'mediumint', 'bigint', 'double');
00233 return !in_array( $sFieldtype, $aTypesWoQuotes);
00234 }
00235
00243 public function getTableDescription( $sTableName )
00244 {
00245
00246 if ( isset( self::$_aTblDescCache[$sTableName] ) ) {
00247 return self::$_aTblDescCache[$sTableName];
00248 }
00249
00250 $aFields = self::getDb()->MetaColumns( $sTableName );
00251
00252 self::$_aTblDescCache[$sTableName] = $aFields;
00253
00254 return $aFields;
00255 }
00256
00266 public function convertDBDateTime( $oObject, $blToTimeStamp = false, $blOnlyDate = false )
00267 {
00268 $sDate = $oObject->value;
00269
00270
00271 $sLocalDateFormat = $this->_defineAndCheckDefaultDateValues( $blToTimeStamp );
00272 $sLocalTimeFormat = $this->_defineAndCheckDefaultTimeValues( $blToTimeStamp );
00273
00274
00275 $aDefDatePatterns = $this->_defaultDatePattern();
00276
00277
00278 $aDatePatterns = $this->_regexp2ValidateDateInput();
00279 $aTimePatterns = $this->_regexp2ValidateTimeInput();
00280
00281
00282 $aDFormats = $this->_defineDateFormattingRules();
00283 $aTFormats = $this->_defineTimeFormattingRules();
00284
00285
00286 if ( !$sDate) {
00287 $this->_setDefaultDateTimeValue($oObject, $sLocalDateFormat, $sLocalTimeFormat, $blOnlyDate);
00288 return $oObject->value;
00289 }
00290
00291 $blDefDateFound = false;
00292
00293
00294 foreach ( array_keys( $aDefDatePatterns ) as $sDefDatePattern ) {
00295 if ( preg_match( $sDefDatePattern, $sDate)) {
00296 $blDefDateFound = true;
00297 break;
00298 }
00299 }
00300
00301
00302 if ( $blDefDateFound) {
00303 $this->_setDefaultFormatedValue($oObject, $sDate, $sLocalDateFormat, $sLocalTimeFormat, $blOnlyDate);
00304 return $oObject->value;
00305 }
00306
00307 $blDateFound = false;
00308 $blTimeFound = false;
00309 $aDateMatches = array();
00310 $aTimeMatches = array();
00311
00312
00313 foreach ( $aDatePatterns as $sPattern => $sType) {
00314 if ( preg_match( $sPattern, $sDate, $aDateMatches)) {
00315 $blDateFound = true;
00316
00317
00318 $sDateFormat = $aDFormats[$sLocalDateFormat][0];
00319 $aDFields = $aDFormats[$sType][1];
00320 break;
00321 }
00322 }
00323
00324
00325 if ( !$blDateFound) {
00326 return $sDate;
00327 }
00328
00329 if ( $blOnlyDate) {
00330 $this->_setDate($oObject, $sDateFormat, $aDFields, $aDateMatches);
00331 return $oObject->value;
00332 }
00333
00334
00335 foreach ( $aTimePatterns as $sPattern => $sType) {
00336 if ( preg_match( $sPattern, $sDate, $aTimeMatches)) {
00337 $blTimeFound = true;
00338
00339
00340 $sTimeFormat = $aTFormats[$sLocalTimeFormat][0];
00341 $aTFields = $aTFormats[$sType][1];
00342
00343
00344 if ( $sType == "USA" && isset($aTimeMatches[4])) {
00345 $iIntVal = (int) $aTimeMatches[1];
00346 if ( $aTimeMatches[4] == "PM") {
00347 if ( $iIntVal < 13) {
00348 $iIntVal += 12;
00349 }
00350 } elseif ( $aTimeMatches[4] == "AM" && $aTimeMatches[1] == "12") {
00351 $iIntVal = 0;
00352 }
00353
00354 $aTimeMatches[1] = sprintf("%02d", $iIntVal);
00355 }
00356
00357 break;
00358 }
00359 }
00360
00361 if ( !$blTimeFound) {
00362
00363
00364 $this->_setDate($oObject, $sDateFormat, $aDFields, $aDateMatches);
00365 return $oObject->value;
00366 }
00367
00368 $this->_formatCorrectTimeValue($oObject, $sDateFormat, $sTimeFormat, $aDateMatches, $aTimeMatches, $aTFields, $aDFields);
00369
00370
00371 if ( !$oObject->fldmax_length) {
00372 return $this->convertDBDateTime( $oObject, $blToTimeStamp, $blOnlyDate);
00373 }
00374 return $oObject->value;
00375 }
00376
00385 public function convertDBTimestamp( $oObject, $blToTimeStamp = false )
00386 {
00387
00388 $sSQLTimeStampPattern = "/^([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})$/";
00389 $sISOTimeStampPattern = "/^([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2})$/";
00390 $aMatches = array();
00391
00392
00393 if ( $blToTimeStamp) {
00394
00395 $this->convertDBDateTime( $oObject, $blToTimeStamp );
00396
00397 if ( preg_match( $sISOTimeStampPattern, $oObject->value, $aMatches)) {
00398
00399 $oObject->setValue($aMatches[1].$aMatches[2].$aMatches[3].$aMatches[4].$aMatches[5].$aMatches[6]);
00400 $oObject->fldmax_length = strlen( $oObject->value);
00401 return $oObject->value;
00402 }
00403 } else {
00404
00405
00406
00407 if ( preg_match( $sSQLTimeStampPattern, $oObject->value, $aMatches ) ) {
00408 $iTimestamp = mktime( $aMatches[4],
00409 $aMatches[5],
00410 $aMatches[6],
00411 $aMatches[2],
00412 $aMatches[3],
00413 $aMatches[1]);
00414 if ( !$iTimestamp ) {
00415 $iTimestamp = "0";
00416 }
00417
00418 $oObject->setValue(trim( date( "Y-m-d H:i:s", $iTimestamp)));
00419 $oObject->fldmax_length = strlen( $oObject->value);
00420 $this->convertDBDateTime( $oObject, $blToTimeStamp );
00421 return $oObject->value;
00422 }
00423 }
00424 }
00425
00434 public function convertDBDate( $oObject, $blToTimeStamp = false )
00435 {
00436 return $this->convertDBDateTime( $oObject, $blToTimeStamp, true );
00437 }
00438
00446 public function createSQLList( $aArray )
00447 {
00448 $sRet = "";
00449
00450 $blSep = false;
00451 foreach ( $aArray as $aToken) {
00452 if ( !$aToken[0]) {
00453 continue;
00454 }
00455 if ( $blSep) {
00456 $sRet .= ",";
00457 }
00458 $sRet .= "'".$aToken[0]."'";
00459 $blSep = true;
00460 }
00461 return $sRet;
00462 }
00463
00469 static public function startTransaction()
00470 {
00471 self::$_oDB->execute( 'START TRANSACTION' );
00472 }
00473
00479 static public function commitTransaction()
00480 {
00481 self::$_oDB->execute( 'COMMIT' );
00482 }
00483
00489 static public function rollbackTransaction()
00490 {
00491 self::$_oDB->execute( 'ROLLBACK' );
00492 }
00493
00502 static public function setTransactionIsolationLevel( $sLevel = null )
00503 {
00504 $aLevels = array( 'READ UNCOMMITTED', 'READ COMMITTED', 'REPEATABLE READ', 'SERIALIZABLE' );
00505
00506 if (in_array(strtoupper($sLevel), $aLevels)) {
00507 self::$_oDB->execute( 'SET TRANSACTION ISOLATION LEVEL ' . $sLevel );
00508 }
00509 }
00510
00511
00520 public function isValidFieldName( $sField )
00521 {
00522 return ( boolean ) preg_match( "#^[\w\d\._]*$#", $sField );
00523 }
00524
00536 protected function _setDefaultFormatedValue( $oObject, $sDate, $sLocalDateFormat, $sLocalTimeFormat, $blOnlyDate )
00537 {
00538 $aDefTimePatterns = $this->_defaultTimePattern();
00539 $aDFormats = $this->_defineDateFormattingRules();
00540 $aTFormats = $this->_defineTimeFormattingRules();
00541
00542 foreach ( array_keys( $aDefTimePatterns ) as $sDefTimePattern ) {
00543 if ( preg_match( $sDefTimePattern, $sDate ) ) {
00544 $blDefTimeFound = true;
00545 break;
00546 }
00547 }
00548
00549
00550 if ( $blOnlyDate) {
00551 $oObject->setValue(trim( $aDFormats[$sLocalDateFormat][2] ));
00552
00553 $oObject->fldmax_length = strlen( $oObject->value );
00554 return ;
00555 } elseif ( $blDefTimeFound ) {
00556
00557 $oObject->setValue(trim( $aDFormats[$sLocalDateFormat][2] . " " . $aTFormats[$sLocalTimeFormat][2] ));
00558
00559 $oObject->fldmax_length = strlen( $oObject->value );
00560 return ;
00561 }
00562 }
00563
00571 protected function _defineAndCheckDefaultTimeValues( $blToTimeStamp )
00572 {
00573
00574
00575 $sLocalTimeFormat = $this->getConfig()->getConfigParam( 'sLocalTimeFormat' );
00576 if ( !$sLocalTimeFormat || $blToTimeStamp) {
00577 $sLocalTimeFormat = "ISO";
00578 }
00579 return $sLocalTimeFormat;
00580 }
00581
00589 protected function _defineAndCheckDefaultDateValues( $blToTimeStamp )
00590 {
00591
00592
00593 $sLocalDateFormat = $this->getConfig()->getConfigParam( 'sLocalDateFormat' );
00594 if ( !$sLocalDateFormat || $blToTimeStamp) {
00595 $sLocalDateFormat = "ISO";
00596 }
00597 return $sLocalDateFormat;
00598 }
00599
00605 protected function _defaultDatePattern()
00606 {
00607
00608 $aDefDatePatterns = array("/^0000-00-00/" => "ISO",
00609 "/^00\.00\.0000/" => "EUR",
00610 "/^00\/00\/0000/" => "USA"
00611 );
00612 return $aDefDatePatterns;
00613 }
00614
00620 protected function _defaultTimePattern()
00621 {
00622
00623 $aDefTimePatterns = array("/00:00:00$/" => "ISO",
00624 "/00\.00\.00$/" => "EUR",
00625 "/00:00:00 AM$/" => "USA"
00626 );
00627 return $aDefTimePatterns;
00628 }
00629
00635 protected function _regexp2ValidateDateInput()
00636 {
00637
00638 $aDatePatterns = array("/^([0-9]{4})-([0-9]{2})-([0-9]{2})/" => "ISO",
00639 "/^([0-9]{2})\.([0-9]{2})\.([0-9]{4})/" => "EUR",
00640 "/^([0-9]{2})\/([0-9]{2})\/([0-9]{4})/" => "USA"
00641 );
00642 return $aDatePatterns;
00643 }
00644
00650 protected function _regexp2ValidateTimeInput()
00651 {
00652
00653 $aTimePatterns = array("/([0-9]{2}):([0-9]{2}):([0-9]{2})$/" => "ISO",
00654 "/([0-9]{2})\.([0-9]{2})\.([0-9]{2})$/" => "EUR",
00655 "/([0-9]{2}):([0-9]{2}):([0-9]{2}) ([AP]{1}[M]{1})$/" => "USA"
00656 );
00657 return $aTimePatterns;
00658 }
00659
00665 protected function _defineDateFormattingRules()
00666 {
00667
00668 $aDFormats = array("ISO" => array("Y-m-d", array(2, 3, 1), "0000-00-00"),
00669 "EUR" => array("d.m.Y", array(2, 1, 3), "00.00.0000"),
00670 "USA" => array("m/d/Y", array(1, 2, 3), "00/00/0000")
00671 );
00672 return $aDFormats;
00673 }
00674
00680 protected function _defineTimeFormattingRules()
00681 {
00682
00683 $aTFormats = array("ISO" => array("H:i:s", array(1, 2, 3 ), "00:00:00"),
00684 "EUR" => array("H.i.s", array(1, 2, 3 ), "00.00.00"),
00685 "USA" => array("h:i:s A", array(1, 2, 3 ), "00:00:00 AM")
00686 );
00687 return $aTFormats;
00688 }
00689
00700 protected function _setDefaultDateTimeValue( $oObject, $sLocalDateFormat, $sLocalTimeFormat, $blOnlyDate )
00701 {
00702 $aDFormats = $this->_defineDateFormattingRules();
00703 $aTFormats = $this->_defineTimeFormattingRules();
00704
00705 $sReturn = $aDFormats[$sLocalDateFormat][2];
00706 if ( !$blOnlyDate) {
00707 $sReturn .= " ".$aTFormats[$sLocalTimeFormat][2];
00708 }
00709
00710 if ($oObject instanceof oxField) {
00711 $oObject->setValue(trim($sReturn));
00712 } else {
00713 $oObject->value = trim($sReturn);
00714 }
00715
00716 $oObject->fldmax_length = strlen( $oObject->value);
00717 }
00718
00729 protected function _setDate( $oObject, $sDateFormat, $aDFields, $aDateMatches )
00730 {
00731
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
00742 $oObject->fldmax_length = strlen( $oObject->value );
00743 }
00744
00758 protected function _formatCorrectTimeValue( $oObject, $sDateFormat, $sTimeFormat, $aDateMatches, $aTimeMatches, $aTFields, $aDFields )
00759 {
00760
00761 $iTimestamp = @mktime( (int) $aTimeMatches[$aTFields[0]],
00762 (int) $aTimeMatches[$aTFields[1]],
00763 (int) $aTimeMatches[$aTFields[2]],
00764 (int) $aDateMatches[$aDFields[0]],
00765 (int) $aDateMatches[$aDFields[1]],
00766 (int) $aDateMatches[$aDFields[2]] );
00767
00768 if ($oObject instanceof oxField) {
00769 $oObject->setValue(trim( @date( $sDateFormat." ".$sTimeFormat, $iTimestamp ) ));
00770 } else {
00771 $oObject->value = trim( @date( $sDateFormat." ".$sTimeFormat, $iTimestamp ) );
00772 }
00773
00774
00775 $oObject->fldmax_length = strlen( $oObject->value );
00776 }
00777
00778 }