00001 <?php
00002
00007 class oxDbMetaDataHandler extends oxSuperCfg
00008 {
00013 protected $_aDbTablesFields = null;
00014
00015
00020 protected $_aTables = null;
00021
00026 protected $_iCurrentMaxLangId;
00027
00032 protected $_aSkipTablesOnReset = array( "oxcountry" );
00033
00041 public function getFields( $sTableName )
00042 {
00043 $aFields = array();
00044 $aRawFields = oxDb::getDb()->MetaColumns( $sTableName );
00045 if (is_array($aRawFields)) {
00046 foreach ( $aRawFields as $oField ) {
00047 $aFields[] = $oField->name;
00048 }
00049 }
00050 return $aFields;
00051 }
00052
00060 public function tableExists( $sTableName )
00061 {
00062 $oDb = oxDb::getDb();
00063 $aTables = $oDb->getAll("show tables like ". $oDb->quote($sTableName));
00064 return count($aTables) > 0;
00065 }
00066
00075 public function fieldExists( $sFieldName, $sTableName )
00076 {
00077 $aTableFields = $this->getFields( $sTableName );
00078
00079 if ( is_array($aTableFields) ) {
00080 $sFieldName = strtoupper( $sFieldName );
00081 $aTableFields = array_map('strtoupper', $aTableFields);
00082 if ( in_array( $sFieldName, $aTableFields ) ) {
00083 return true;
00084 }
00085 }
00086
00087 return false;
00088 }
00089
00090
00097 public function getAllTables()
00098 {
00099 if ( empty($this->_aTables) ) {
00100
00101 $aTables = oxDb::getDb()->getAll("show tables");
00102
00103 foreach ( $aTables as $aTableInfo) {
00104 $sTableName = $aTableInfo[0];
00105
00106 $this->_aTables[] = $aTableInfo[0];
00107 }
00108 }
00109 return $this->_aTables;
00110 }
00111
00119 public function getAllMultiTables($sTable)
00120 {
00121 $aMLTables = array();
00122 foreach (array_keys(oxRegistry::getLang()->getLanguageIds()) as $iLangId) {
00123 $sLangTableName = getLangTableName($sTable, $iLangId );
00124 if ($sTable != $sLangTableName && !in_array($sLangTableName, $aMLTables)) {
00125 $aMLTables[] = $sLangTableName;
00126 }
00127 }
00128 return $aMLTables;
00129 }
00130
00140 protected function _getCreateTableSetSql( $sTable, $iLang)
00141 {
00142 $sTableSet = getLangTableName($sTable, $iLang);
00143
00144 $aRes = oxDb::getDb()->getAll( "show create table {$sTable}" );
00145 $sSql = "CREATE TABLE `{$sTableSet}` (".
00146 "`OXID` char(32) COLLATE latin1_general_ci NOT NULL, ".
00147 "PRIMARY KEY (`OXID`)".
00148 ") ".strstr($aRes[0][1], 'ENGINE=');
00149 return $sSql;
00150 }
00151
00163 public function getAddFieldSql( $sTable, $sField, $sNewField, $sPrevField, $sTableSet = null )
00164 {
00165 if (!$sTableSet) {
00166 $sTableSet = $sTable;
00167 }
00168 $aRes = oxDb::getDb()->getAll( "show create table {$sTable}" );
00169 $sTableSql = $aRes[0][1];
00170
00171 preg_match( "/.*,\s+(['`]?".preg_quote($sField, '/')."['`]?\s+[^,]+),.*/", $sTableSql, $aMatch );
00172 $sFieldSql = $aMatch[1];
00173
00174 $sSql = "";
00175 if ( !empty($sFieldSql) ) {
00176 $sFieldSql = preg_replace( "/".preg_quote($sField, '/')."/", $sNewField, $sFieldSql );
00177 $sSql = "ALTER TABLE `$sTableSet` ADD " . $sFieldSql;
00178 if ($this->tableExists($sTableSet) && $this->fieldExists($sPrevField, $sTableSet)) {
00179 $sSql .= " AFTER `$sPrevField`";
00180 }
00181 }
00182 return $sSql;
00183 }
00184
00185
00186
00197 public function getAddFieldIndexSql( $sTable, $sField, $sNewField, $sTableSet = null )
00198 {
00199 $aRes = oxDb::getDb()->getAll( "show create table {$sTable}" );
00200
00201 $sTableSql = $aRes[0][1];
00202
00203 preg_match_all("/([\w]+\s+)?\bKEY\s+(`[^`]+`)?\s*\([^)]+\)/iU", $sTableSql, $aMatch);
00204 $aIndex = $aMatch[0];
00205
00206 $blUsingTableSet = $sTableSet ? true : false;
00207
00208 if (!$sTableSet) {
00209 $sTableSet = $sTable;
00210 }
00211
00212 $aIndexSql = array();
00213 $aSql = array();
00214 if ( count($aIndex) ) {
00215 foreach ( $aIndex as $sIndexSql ) {
00216 if ( preg_match("/\([^)]*\b" . $sField . "\b[^)]*\)/i", $sIndexSql ) ) {
00217
00218
00219 $sIndexSql = preg_replace("/(.*\bKEY\s+)`[^`]+`/", "$1", $sIndexSql );
00220
00221 if ( $blUsingTableSet ) {
00222
00223 $sIndexSql = preg_replace("/\([^\)]+\)/", "(`$sNewField`)", $sIndexSql );
00224 } else {
00225
00226 $sIndexSql = preg_replace("/\b" . $sField . "\b/", $sNewField, $sIndexSql );
00227 }
00228
00229 $aIndexSql[] = "ADD ". $sIndexSql;
00230 }
00231 }
00232 if ( count($aIndexSql) ) {
00233 $aSql = array("ALTER TABLE `$sTableSet` ".implode(", ", $aIndexSql));
00234 }
00235 }
00236
00237 return $aSql;
00238 }
00239
00246 public function getCurrentMaxLangId()
00247 {
00248 if ( isset($this->_iCurrentMaxLangId) ) {
00249 return $this->_iCurrentMaxLangId;
00250 }
00251
00252 $sTable = $sTableSet = "oxarticles";
00253 $sField = $sFieldSet = "oxtitle";
00254 $iLang = 0;
00255 while ($this->tableExists($sTableSet) && $this->fieldExists($sFieldSet, $sTableSet)) {
00256 $iLang ++;
00257 $sTableSet = getLangTableName($sTable, $iLang);
00258 $sFieldSet = $sField.'_'.$iLang;
00259 }
00260
00261 $this->_iCurrentMaxLangId = --$iLang;
00262 return $this->_iCurrentMaxLangId;
00263 }
00264
00270 public function getNextLangId()
00271 {
00272 return $this->getCurrentMaxLangId() + 1;
00273 }
00274
00282 public function getMultilangFields( $sTable )
00283 {
00284 $aFields = $this->getFields( $sTable );
00285 $aMultiLangFields = array();
00286
00287 foreach ( $aFields as $sField ) {
00288 if ( preg_match("/(.+)_1$/", $sField, $aMatches) ) {
00289 $aMultiLangFields[] = $aMatches[1];
00290 }
00291 }
00292
00293 return $aMultiLangFields;
00294 }
00295
00304 public function getSinglelangFields( $sTable, $iLang )
00305 {
00306 $aFields = array_merge($this->getFields( $sTable ), $this->getFields(getLangTableName($sTable, $iLang) ));
00307 $aSingleLangFields = array();
00308
00309 foreach ( $aFields as $sField ) {
00310 if ( preg_match("/(.+)_([0-9]+)$/", $sField, $aMatches) ) {
00311 if ($aMatches[2] == $iLang) {
00312 $aSingleLangFields[$aMatches[1]] = $sField;
00313 }
00314 } else {
00315 $aSingleLangFields[$sField] = $sField;
00316 }
00317 }
00318
00319 return $aSingleLangFields;
00320 }
00321
00330 public function addNewMultilangField( $sTable )
00331 {
00332 $aSql = array();
00333 $aFields = $this->getMultilangFields($sTable);
00334 $iMaxLang = $this->getCurrentMaxLangId();
00335 $iNewLang = $this->getNextLangId();
00336
00337 $sTableSet = getLangTableName($sTable, $iNewLang);
00338 if (!$this->tableExists($sTableSet)) {
00339 $aSql[] = $this->_getCreateTableSetSql( $sTable, $iNewLang );
00340 }
00341
00342 if ( is_array($aFields) && count($aFields) > 0 ) {
00343 foreach ( $aFields as $sField ) {
00344 $sNewFieldName = $sField . "_" . $iNewLang;
00345 if ($iNewLang>1) {
00346 $iPrevLang = $iNewLang-1;
00347 $sPrevField = $sField.'_'.$iPrevLang;
00348 } else {
00349 $sPrevField = $sField;
00350 }
00351
00352 if ( !$this->tableExists($sTableSet) || !$this->fieldExists( $sNewFieldName, $sTableSet ) ) {
00353
00354
00355 $aSql[] = $this->getAddFieldSql( $sTable, $sField, $sNewFieldName, $sPrevField, $sTableSet );
00356
00357
00358 $aSql = array_merge($aSql, (array) $this->getAddFieldIndexSql($sTable, $sField, $sNewFieldName, $sTableSet));
00359 }
00360 }
00361 }
00362
00363 $this->executeSql($aSql);
00364 }
00365
00375 public function resetMultilangFields( $iLangId, $sTableName )
00376 {
00377 $iLangId = (int)$iLangId;
00378
00379 if ( $iLangId === 0 ) {
00380 return;
00381 }
00382
00383 $aSql = array();
00384
00385 $aFields = $this->getMultilangFields( $sTableName );
00386 if ( is_array($aFields) && count($aFields) > 0 ) {
00387 foreach ( $aFields as $sFieldName ) {
00388 $sFieldName = $sFieldName . "_" . $iLangId;
00389
00390 if ( $this->fieldExists( $sFieldName, $sTableName ) ) {
00391
00392 $aSql[] = "UPDATE {$sTableName} SET {$sFieldName} = DEFAULT;";
00393 }
00394 }
00395 }
00396
00397 if ( !empty($aSql) ) {
00398 $this->executeSql( $aSql );
00399 }
00400 }
00401
00408 public function addNewLangToDb()
00409 {
00410
00411 $this->_iCurrentMaxLangId = null;
00412
00413 $aTable = $this->getAllTables();
00414
00415 foreach ( $aTable as $sTableName ) {
00416 $this->addNewMultilangField( $sTableName );
00417 }
00418
00419
00420 $this->updateViews();
00421 }
00422
00431 public function resetLanguage( $iLangId )
00432 {
00433 if ( (int)$iLangId === 0 ) {
00434 return;
00435 }
00436
00437 $aTables = $this->getAllTables();
00438
00439
00440 foreach ( $this->_aSkipTablesOnReset as $sSkipTable ) {
00441
00442 if ( ($iSkipId = array_search( $sSkipTable, $aTables )) !== false ) {
00443 unset( $aTables[$iSkipId] );
00444 }
00445 }
00446
00447 foreach ( $aTables as $sTableName ) {
00448 $this->resetMultilangFields( $iLangId, $sTableName );
00449 }
00450 }
00451
00459 public function executeSql( $aSql )
00460 {
00461 $oDb = oxDb::getDb();
00462
00463 if ( is_array($aSql) && !empty($aSql) ) {
00464 foreach ( $aSql as $sSql) {
00465 $sSql = trim($sSql);
00466 if (!empty($sSql)) {
00467 $oDb->execute( $sSql );
00468 }
00469 }
00470 }
00471 }
00472
00480 public function updateViews( $aTables = null )
00481 {
00482 set_time_limit( 0 );
00483
00484 $oDb = oxDb::getDb();
00485 $oConfig = oxRegistry::getConfig();
00486
00487 $aShops = $oDb->getAll( "select * from oxshops" );
00488
00489 $aTables = $aTables ? $aTables : $oConfig->getConfigParam( 'aMultiShopTables' );
00490
00491 $bSuccess = true;
00492 foreach ( $aShops as $aShop ) {
00493 $sShopId = $aShop[0];
00494 $oShop = oxNew( 'oxshop' );
00495 $oShop->load( $sShopId );
00496 $oShop->setMultiShopTables( $aTables );
00497 $blMultishopInherit = $oConfig->getShopConfVar( 'blMultishopInherit_oxcategories', $sShopId );
00498 $aMallInherit = array();
00499 foreach ( $aTables as $sTable ) {
00500 $aMallInherit[$sTable] = $oConfig->getShopConfVar( 'blMallInherit_' . $sTable, $sShopId );
00501 }
00502 if ( !$oShop->generateViews( $blMultishopInherit, $aMallInherit ) && $bSuccess ) {
00503 $bSuccess = false;
00504 }
00505 }
00506
00507 return $bSuccess;
00508 }
00509 }
00510