00001 <?php
00002
00003
00004
00005 require_once getShopBasePath() . 'core/adodblite/adodb.inc.php';
00006
00010 class oxDb extends oxSuperCfg
00011 {
00017 protected static $_instance = null;
00018
00024 protected static $_oDB = null;
00025
00031 protected static $_aTblDescCache = array();
00032
00038 public static function getInstance()
00039 {
00040
00041 if ( defined( 'OXID_PHP_UNIT' ) ) {
00042 self::$_instance = modInstances::getMod( __CLASS__ );
00043 }
00044
00045
00046 if ( !self::$_instance instanceof oxDb ) {
00047
00048
00049 self::$_instance = oxNew( 'oxdb' );
00050
00051 if ( defined( 'OXID_PHP_UNIT' ) ) {
00052 modInstances::addMod( __CLASS__, self::$_instance);
00053 }
00054 }
00055 return self::$_instance;
00056 }
00057
00067 public static function getDb( $blAssoc = false )
00068 {
00069 global $ADODB_FETCH_MODE;
00070
00071 if ( $blAssoc ) {
00072 $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
00073 } else {
00074 $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
00075 }
00076
00077 if ( defined( 'OXID_PHP_UNIT' ) ) {
00078 if ( isset( modDB::$unitMOD ) && is_object( modDB::$unitMOD ) ) {
00079 return modDB::$unitMOD;
00080 }
00081 }
00082
00083 if ( self::$_oDB !== null ) {
00084 return self::$_oDB;
00085 }
00086
00087 global $ADODB_CACHE_DIR;
00088 global $ADODB_DRIVER,
00089 $ADODB_SESSION_TBL,
00090 $ADODB_SESSION_CONNECT,
00091 $ADODB_SESSION_DRIVER,
00092 $ADODB_SESSION_USER,
00093 $ADODB_SESSION_PWD,
00094 $ADODB_SESSION_DB,
00095 $ADODB_SESS_LIFE,
00096 $ADODB_SESS_DEBUG;
00097
00098
00099 $myConfig = self::getInstance()->getConfig();
00100 $iDebug = $myConfig->getConfigParam( 'iDebug' );
00101 if ( $iDebug ) {
00102 include_once getShopBasePath() . 'core/adodblite/adodb-exceptions.inc.php';
00103 }
00104
00105
00106
00107
00108
00109
00110
00111 $ADODB_SESS_LIFE = 3000 * 60;
00112 $ADODB_SESSION_TBL = "oxsessions";
00113 $ADODB_SESSION_DRIVER = $myConfig->getConfigParam( 'dbType' );
00114 $ADODB_SESSION_USER = $myConfig->getConfigParam( 'dbUser' );
00115 $ADODB_SESSION_PWD = $myConfig->getConfigParam( 'dbPwd' );
00116 $ADODB_SESSION_DB = $myConfig->getConfigParam( 'dbName' );
00117 $ADODB_SESSION_CONNECT = $myConfig->getConfigParam( 'dbHost' );
00118 $ADODB_SESS_DEBUG = false;
00119 $ADODB_CACHE_DIR = $myConfig->getConfigParam( 'sCompileDir' );
00120
00121 $sModules = '';
00122 if ( $iDebug == 2 || $iDebug == 3 || $iDebug == 4 || $iDebug == 7 ) {
00123 $sModules = 'perfmon';
00124 }
00125
00126
00127 if ( $myConfig->isAdmin() && $myConfig->getConfigParam( 'blLogChangesInAdmin' ) ) {
00128 $sModules = ( $sModules ? ':' : '' ) . 'oxadminlog';
00129 }
00130
00131 self::$_oDB = ADONewConnection( $myConfig->getConfigParam( 'dbType' ), $sModules );
00132
00133 $sVerPrefix = '';
00134 $sVerPrefix = '_ce';
00135
00136 if ( !self::$_oDB->connect( $myConfig->getConfigParam( 'dbHost' ), $myConfig->getConfigParam( 'dbUser' ), $myConfig->getConfigParam( 'dbPwd' ), $myConfig->getConfigParam( 'dbName' ) ) ) {
00137 $sConfig = join( '', file( getShopBasePath().'config.inc.php' ) );
00138 if ( strpos( $sConfig, '<dbHost'.$sVerPrefix.'>' ) !== false &&
00139 strpos( $sConfig, '<dbName'.$sVerPrefix.'>' ) !== false ) {
00140 header( 'location:setup/index.php' );
00141 oxUtils::getInstance()->showMessageAndExit( "" );
00142 } else {
00143
00144
00145 $sFailedShop = isset( $_REQUEST['shp'] )?addslashes( $_REQUEST['shp'] ):'Base shop';
00146
00147 $sDate = date( 'l dS of F Y h:i:s A');
00148 $sScript = $_SERVER['SCRIPT_NAME'].'?'.$_SERVER['QUERY_STRING'];
00149 $sReferer = $_SERVER['HTTP_REFERER'];
00150
00151
00152 $sWarningSubject = 'Offline warning!';
00153 $sWarningBody = "
00154 Database error in OXID eShop:
00155 Date: $sDate
00156 Shop: $sFailedShop
00157
00158 mysql error: ".self::$_oDB->errorMsg()."
00159 mysql error no: ".self::$_oDB->errorNo()."
00160
00161 Script: $sScript
00162 Referer: $sReferer";
00163
00164 if ( ( $sAdminEmail = $myConfig->getConfigParam( 'sAdminEmail' ) ) ) {
00165 include 'core/phpmailer/class.phpmailer.php';
00166
00167 $oMailer = new phpmailer();
00168 $oMailer->isMail();
00169 $oMailer->From = $sAdminEmail;
00170 $oMailer->AddAddress( $sAdminEmail );
00171 $oMailer->Subject = $sWarningSubject;
00172 $oMailer->Body = $sWarningBody;
00173 $oMailer->send();
00174 }
00175
00176
00177 $oEx = new oxConnectionException();
00178 $oEx->setMessage( 'EXCEPTION_CONNECTION_NODB' );
00179 $oEx->setConnectionError( $myConfig->getConfigParam( 'dbUser' ).'s'.getShopBasePath().self::$_oDB->errorMsg() );
00180 throw $oEx;
00181 }
00182 }
00183
00184 if ( $iDebug == 2 || $iDebug == 3 || $iDebug == 4 || $iDebug == 7 ) {
00185 try {
00186 self::$_oDB->execute('truncate table adodb_logsql;');
00187 } catch (ADODB_Exception $e) {
00188
00189 }
00190 self::$_oDB->logSQL( true );
00191 }
00192
00193 self::$_oDB->cacheSecs = 60 * 10;
00194 self::$_oDB->execute( 'SET @@session.sql_mode = ""' );
00195
00196 if ( $myConfig->isUtf() ) {
00197 self::$_oDB->execute( 'SET NAMES "utf8"' );
00198 self::$_oDB->execute( 'SET CHARACTER SET utf8' );
00199 self::$_oDB->execute( 'SET CHARACTER_SET_CONNECTION = utf8' );
00200 self::$_oDB->execute( 'SET CHARACTER_SET_DATABASE = utf8' );
00201 self::$_oDB->execute( 'SET character_set_results = utf8' );
00202 self::$_oDB->execute( 'SET character_set_server = utf8' );
00203 } elseif ( $myConfig->getConfigParam('sDefaultDatabaseConnection') != '' ) {
00204 self::$_oDB->execute( 'SET NAMES ' . $myConfig->getConfigParam('sDefaultDatabaseConnection') );
00205 }
00206
00207 return self::$_oDB;
00208 }
00209
00217 public function getMultiLangFieldName( $sField )
00218 {
00219
00220
00221
00222
00223
00224
00225 return $sField . oxLang::getInstance()->getLanguageTag();
00226 }
00227
00236 public function isQuoteNeeded( $sFieldtype)
00237 {
00238 $aTypesWoQuotes = array('int', 'decimal', 'float', 'tinyint', 'smallint', 'mediumint', 'bigint', 'double');
00239 return !in_array( $sFieldtype, $aTypesWoQuotes);
00240 }
00241
00249 public function quoteArray( $aStrArray)
00250 {
00251 foreach ( $aStrArray as $sKey => $sString ) {
00252 $aStrArray[$sKey] = self::getDb()->quote($sString);
00253 }
00254 return $aStrArray;
00255 }
00256
00262 public function resetTblDescCache()
00263 {
00264 self::$_aTblDescCache = array();
00265 }
00266
00274 public function getTableDescription( $sTableName )
00275 {
00276
00277 if ( isset( self::$_aTblDescCache[$sTableName] ) ) {
00278 return self::$_aTblDescCache[$sTableName];
00279 }
00280
00281 $aFields = self::getDb()->MetaColumns( $sTableName );
00282
00283 self::$_aTblDescCache[$sTableName] = $aFields;
00284
00285 return $aFields;
00286 }
00287
00297 public function convertDBDateTime( $oObject, $blToTimeStamp = false, $blOnlyDate = false )
00298 {
00299 $sDate = $oObject->value;
00300
00301
00302 $sLocalDateFormat = $this->_defineAndCheckDefaultDateValues( $blToTimeStamp );
00303 $sLocalTimeFormat = $this->_defineAndCheckDefaultTimeValues( $blToTimeStamp );
00304
00305
00306 $aDefDatePatterns = $this->_defaultDatePattern();
00307
00308
00309 $aDatePatterns = $this->_regexp2ValidateDateInput();
00310 $aTimePatterns = $this->_regexp2ValidateTimeInput();
00311
00312
00313 $aDFormats = $this->_defineDateFormattingRules();
00314 $aTFormats = $this->_defineTimeFormattingRules();
00315
00316
00317 if ( !$sDate) {
00318 $this->_setDefaultDateTimeValue($oObject, $sLocalDateFormat, $sLocalTimeFormat, $blOnlyDate);
00319 return $oObject->value;
00320 }
00321
00322 $blDefDateFound = false;
00323 $oStr = getStr();
00324
00325
00326 foreach ( array_keys( $aDefDatePatterns ) as $sDefDatePattern ) {
00327 if ( $oStr->preg_match( $sDefDatePattern, $sDate)) {
00328 $blDefDateFound = true;
00329 break;
00330 }
00331 }
00332
00333
00334 if ( $blDefDateFound) {
00335 $this->_setDefaultFormatedValue($oObject, $sDate, $sLocalDateFormat, $sLocalTimeFormat, $blOnlyDate);
00336 return $oObject->value;
00337 }
00338
00339 $blDateFound = false;
00340 $blTimeFound = false;
00341 $aDateMatches = array();
00342 $aTimeMatches = array();
00343
00344
00345 foreach ( $aDatePatterns as $sPattern => $sType) {
00346 if ( $oStr->preg_match( $sPattern, $sDate, $aDateMatches)) {
00347 $blDateFound = true;
00348
00349
00350 $sDateFormat = $aDFormats[$sLocalDateFormat][0];
00351 $aDFields = $aDFormats[$sType][1];
00352 break;
00353 }
00354 }
00355
00356
00357 if ( !$blDateFound) {
00358 return $sDate;
00359 }
00360
00361 if ( $blOnlyDate) {
00362 $this->_setDate($oObject, $sDateFormat, $aDFields, $aDateMatches);
00363 return $oObject->value;
00364 }
00365
00366
00367 foreach ( $aTimePatterns as $sPattern => $sType) {
00368 if ( $oStr->preg_match( $sPattern, $sDate, $aTimeMatches)) {
00369 $blTimeFound = true;
00370
00371
00372 $sTimeFormat = $aTFormats[$sLocalTimeFormat][0];
00373 $aTFields = $aTFormats[$sType][1];
00374
00375
00376 if ( $sType == "USA" && isset($aTimeMatches[4])) {
00377 $iIntVal = (int) $aTimeMatches[1];
00378 if ( $aTimeMatches[4] == "PM") {
00379 if ( $iIntVal < 13) {
00380 $iIntVal += 12;
00381 }
00382 } elseif ( $aTimeMatches[4] == "AM" && $aTimeMatches[1] == "12") {
00383 $iIntVal = 0;
00384 }
00385
00386 $aTimeMatches[1] = sprintf("%02d", $iIntVal);
00387 }
00388
00389 break;
00390 }
00391 }
00392
00393 if ( !$blTimeFound) {
00394
00395
00396 $this->_setDate($oObject, $sDateFormat, $aDFields, $aDateMatches);
00397 return $oObject->value;
00398 }
00399
00400 $this->_formatCorrectTimeValue($oObject, $sDateFormat, $sTimeFormat, $aDateMatches, $aTimeMatches, $aTFields, $aDFields);
00401
00402
00403 if ( !$oObject->fldmax_length) {
00404 return $this->convertDBDateTime( $oObject, $blToTimeStamp, $blOnlyDate);
00405 }
00406 return $oObject->value;
00407 }
00408
00417 public function convertDBTimestamp( $oObject, $blToTimeStamp = false )
00418 {
00419
00420 $sSQLTimeStampPattern = "/^([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})$/";
00421 $sISOTimeStampPattern = "/^([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2})$/";
00422 $aMatches = array();
00423 $oStr = getStr();
00424
00425
00426 if ( $blToTimeStamp) {
00427
00428 $this->convertDBDateTime( $oObject, $blToTimeStamp );
00429
00430 if ( $oStr->preg_match( $sISOTimeStampPattern, $oObject->value, $aMatches)) {
00431
00432 $oObject->setValue($aMatches[1].$aMatches[2].$aMatches[3].$aMatches[4].$aMatches[5].$aMatches[6]);
00433 $oObject->fldmax_length = strlen( $oObject->value);
00434 return $oObject->value;
00435 }
00436 } else {
00437
00438
00439
00440 if ( $oStr->preg_match( $sSQLTimeStampPattern, $oObject->value, $aMatches ) ) {
00441 $iTimestamp = mktime( $aMatches[4],
00442 $aMatches[5],
00443 $aMatches[6],
00444 $aMatches[2],
00445 $aMatches[3],
00446 $aMatches[1]);
00447 if ( !$iTimestamp ) {
00448 $iTimestamp = "0";
00449 }
00450
00451 $oObject->setValue(trim( date( "Y-m-d H:i:s", $iTimestamp)));
00452 $oObject->fldmax_length = strlen( $oObject->value);
00453 $this->convertDBDateTime( $oObject, $blToTimeStamp );
00454 return $oObject->value;
00455 }
00456 }
00457 }
00458
00467 public function convertDBDate( $oObject, $blToTimeStamp = false )
00468 {
00469 return $this->convertDBDateTime( $oObject, $blToTimeStamp, true );
00470 }
00471
00479 public function createSQLList( $aArray )
00480 {
00481 $sRet = "";
00482
00483 $blSep = false;
00484 foreach ( $aArray as $aToken) {
00485 if ( !$aToken[0]) {
00486 continue;
00487 }
00488 if ( $blSep) {
00489 $sRet .= ",";
00490 }
00491 $sRet .= "'".$aToken[0]."'";
00492 $blSep = true;
00493 }
00494 return $sRet;
00495 }
00496
00502 static public function startTransaction()
00503 {
00504 self::$_oDB->execute( 'START TRANSACTION' );
00505 }
00506
00512 static public function commitTransaction()
00513 {
00514 self::$_oDB->execute( 'COMMIT' );
00515 }
00516
00522 static public function rollbackTransaction()
00523 {
00524 self::$_oDB->execute( 'ROLLBACK' );
00525 }
00526
00535 static public function setTransactionIsolationLevel( $sLevel = null )
00536 {
00537 $aLevels = array( 'READ UNCOMMITTED', 'READ COMMITTED', 'REPEATABLE READ', 'SERIALIZABLE' );
00538
00539 if (in_array(strtoupper($sLevel), $aLevels)) {
00540 self::$_oDB->execute( 'SET TRANSACTION ISOLATION LEVEL ' . $sLevel );
00541 }
00542 }
00543
00544
00553 public function isValidFieldName( $sField )
00554 {
00555 return ( boolean ) getStr()->preg_match( "#^[\w\d\._]*$#", $sField );
00556 }
00557
00569 protected function _setDefaultFormatedValue( $oObject, $sDate, $sLocalDateFormat, $sLocalTimeFormat, $blOnlyDate )
00570 {
00571 $aDefTimePatterns = $this->_defaultTimePattern();
00572 $aDFormats = $this->_defineDateFormattingRules();
00573 $aTFormats = $this->_defineTimeFormattingRules();
00574 $oStr = getStr();
00575
00576 foreach ( array_keys( $aDefTimePatterns ) as $sDefTimePattern ) {
00577 if ( $oStr->preg_match( $sDefTimePattern, $sDate ) ) {
00578 $blDefTimeFound = true;
00579 break;
00580 }
00581 }
00582
00583
00584 if ( $blOnlyDate) {
00585 $oObject->setValue(trim( $aDFormats[$sLocalDateFormat][2] ));
00586
00587 $oObject->fldmax_length = strlen( $oObject->value );
00588 return ;
00589 } elseif ( $blDefTimeFound ) {
00590
00591 $oObject->setValue(trim( $aDFormats[$sLocalDateFormat][2] . " " . $aTFormats[$sLocalTimeFormat][2] ));
00592
00593 $oObject->fldmax_length = strlen( $oObject->value );
00594 return ;
00595 }
00596 }
00597
00605 protected function _defineAndCheckDefaultTimeValues( $blToTimeStamp )
00606 {
00607
00608
00609 $sLocalTimeFormat = $this->getConfig()->getConfigParam( 'sLocalTimeFormat' );
00610 if ( !$sLocalTimeFormat || $blToTimeStamp) {
00611 $sLocalTimeFormat = "ISO";
00612 }
00613 return $sLocalTimeFormat;
00614 }
00615
00623 protected function _defineAndCheckDefaultDateValues( $blToTimeStamp )
00624 {
00625
00626
00627 $sLocalDateFormat = $this->getConfig()->getConfigParam( 'sLocalDateFormat' );
00628 if ( !$sLocalDateFormat || $blToTimeStamp) {
00629 $sLocalDateFormat = "ISO";
00630 }
00631 return $sLocalDateFormat;
00632 }
00633
00639 protected function _defaultDatePattern()
00640 {
00641
00642 $aDefDatePatterns = array("/^0000-00-00/" => "ISO",
00643 "/^00\.00\.0000/" => "EUR",
00644 "/^00\/00\/0000/" => "USA"
00645 );
00646 return $aDefDatePatterns;
00647 }
00648
00654 protected function _defaultTimePattern()
00655 {
00656
00657 $aDefTimePatterns = array("/00:00:00$/" => "ISO",
00658 "/00\.00\.00$/" => "EUR",
00659 "/00:00:00 AM$/" => "USA"
00660 );
00661 return $aDefTimePatterns;
00662 }
00663
00669 protected function _regexp2ValidateDateInput()
00670 {
00671
00672 $aDatePatterns = array("/^([0-9]{4})-([0-9]{2})-([0-9]{2})/" => "ISO",
00673 "/^([0-9]{2})\.([0-9]{2})\.([0-9]{4})/" => "EUR",
00674 "/^([0-9]{2})\/([0-9]{2})\/([0-9]{4})/" => "USA"
00675 );
00676 return $aDatePatterns;
00677 }
00678
00684 protected function _regexp2ValidateTimeInput()
00685 {
00686
00687 $aTimePatterns = array("/([0-9]{2}):([0-9]{2}):([0-9]{2})$/" => "ISO",
00688 "/([0-9]{2})\.([0-9]{2})\.([0-9]{2})$/" => "EUR",
00689 "/([0-9]{2}):([0-9]{2}):([0-9]{2}) ([AP]{1}[M]{1})$/" => "USA"
00690 );
00691 return $aTimePatterns;
00692 }
00693
00699 protected function _defineDateFormattingRules()
00700 {
00701
00702 $aDFormats = array("ISO" => array("Y-m-d", array(2, 3, 1), "0000-00-00"),
00703 "EUR" => array("d.m.Y", array(2, 1, 3), "00.00.0000"),
00704 "USA" => array("m/d/Y", array(1, 2, 3), "00/00/0000")
00705 );
00706 return $aDFormats;
00707 }
00708
00714 protected function _defineTimeFormattingRules()
00715 {
00716
00717 $aTFormats = array("ISO" => array("H:i:s", array(1, 2, 3 ), "00:00:00"),
00718 "EUR" => array("H.i.s", array(1, 2, 3 ), "00.00.00"),
00719 "USA" => array("h:i:s A", array(1, 2, 3 ), "00:00:00 AM")
00720 );
00721 return $aTFormats;
00722 }
00723
00734 protected function _setDefaultDateTimeValue( $oObject, $sLocalDateFormat, $sLocalTimeFormat, $blOnlyDate )
00735 {
00736 $aDFormats = $this->_defineDateFormattingRules();
00737 $aTFormats = $this->_defineTimeFormattingRules();
00738
00739 $sReturn = $aDFormats[$sLocalDateFormat][2];
00740 if ( !$blOnlyDate) {
00741 $sReturn .= " ".$aTFormats[$sLocalTimeFormat][2];
00742 }
00743
00744 if ($oObject instanceof oxField) {
00745 $oObject->setValue(trim($sReturn));
00746 } else {
00747 $oObject->value = trim($sReturn);
00748 }
00749
00750 $oObject->fldmax_length = strlen( $oObject->value);
00751 }
00752
00763 protected function _setDate( $oObject, $sDateFormat, $aDFields, $aDateMatches )
00764 {
00765
00766 $iTimestamp = mktime( 0, 0, 0, $aDateMatches[$aDFields[0]],
00767 $aDateMatches[$aDFields[1]],
00768 $aDateMatches[$aDFields[2]]);
00769
00770 if ($oObject instanceof oxField) {
00771 $oObject->setValue(@date( $sDateFormat, $iTimestamp ));
00772 } else {
00773 $oObject->value = @date( $sDateFormat, $iTimestamp );
00774 }
00775
00776 $oObject->fldmax_length = strlen( $oObject->value );
00777 }
00778
00792 protected function _formatCorrectTimeValue( $oObject, $sDateFormat, $sTimeFormat, $aDateMatches, $aTimeMatches, $aTFields, $aDFields )
00793 {
00794
00795 $iTimestamp = @mktime( (int) $aTimeMatches[$aTFields[0]],
00796 (int) $aTimeMatches[$aTFields[1]],
00797 (int) $aTimeMatches[$aTFields[2]],
00798 (int) $aDateMatches[$aDFields[0]],
00799 (int) $aDateMatches[$aDFields[1]],
00800 (int) $aDateMatches[$aDFields[2]] );
00801
00802 if ($oObject instanceof oxField) {
00803 $oObject->setValue(trim( @date( $sDateFormat." ".$sTimeFormat, $iTimestamp ) ));
00804 } else {
00805 $oObject->value = trim( @date( $sDateFormat." ".$sTimeFormat, $iTimestamp ) );
00806 }
00807
00808
00809 $oObject->fldmax_length = strlen( $oObject->value );
00810 }
00811
00817 protected function _getConnectionId()
00818 {
00819 if ( self::$_oDB !== null ) {
00820 return self::$_oDB->connectionId;
00821 }
00822
00823 return null;
00824 }
00825
00833 public function escapeString( $sString )
00834 {
00835 return mysql_real_escape_string( $sString, $this->_getConnectionId() );
00836 }
00837
00845 public function updateViews( $aTables = null )
00846 {
00847 $myConfig = $this->getConfig();
00848
00849 $oShopList = oxNew("oxshoplist" );
00850 $oShopList->selectString( "select * from oxshops");
00851
00852 $aTables = $aTables ? $aTables : $myConfig->getConfigParam( 'aMultiShopTables' );
00853 foreach ( $oShopList as $key => $oShop ) {
00854 $oShop->setMultiShopTables( $aTables );
00855 $blMultishopInherit = $myConfig->getShopConfVar( 'blMultishopInherit_oxcategories', $oShop->sOXID );
00856 $aMallInherit = array();
00857 foreach ( $aTables as $sTable ) {
00858 $aMallInherit[$sTable] = $myConfig->getShopConfVar( 'blMallInherit_' . $sTable, $oShop->sOXID );
00859 }
00860 $oShop->generateViews( $blMultishopInherit, $aMallInherit );
00861 }
00862 }
00863 }