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
00172 $sTableSql = preg_replace('/COMMENT \\\'.*?\\\'/', '', $sTableSql);
00173 preg_match( "/.*,\s+(['`]?".preg_quote($sField, '/')."['`]?\s+[^,]+),.*/", $sTableSql, $aMatch );
00174 $sFieldSql = $aMatch[1];
00175
00176 $sSql = "";
00177 if ( !empty($sFieldSql) ) {
00178 $sFieldSql = preg_replace( "/".preg_quote($sField, '/')."/", $sNewField, $sFieldSql );
00179 $sSql = "ALTER TABLE `$sTableSet` ADD " . $sFieldSql;
00180 if ($this->tableExists($sTableSet) && $this->fieldExists($sPrevField, $sTableSet)) {
00181 $sSql .= " AFTER `$sPrevField`";
00182 }
00183 }
00184 return $sSql;
00185 }
00186
00187
00188
00199 public function getAddFieldIndexSql( $sTable, $sField, $sNewField, $sTableSet = null )
00200 {
00201 $aRes = oxDb::getDb()->getAll( "show create table {$sTable}" );
00202
00203 $sTableSql = $aRes[0][1];
00204
00205 preg_match_all("/([\w]+\s+)?\bKEY\s+(`[^`]+`)?\s*\([^)]+\)/iU", $sTableSql, $aMatch);
00206 $aIndex = $aMatch[0];
00207
00208 $blUsingTableSet = $sTableSet ? true : false;
00209
00210 if (!$sTableSet) {
00211 $sTableSet = $sTable;
00212 }
00213
00214 $aIndexSql = array();
00215 $aSql = array();
00216 if ( count($aIndex) ) {
00217 foreach ( $aIndex as $sIndexSql ) {
00218 if ( preg_match("/\([^)]*\b" . $sField . "\b[^)]*\)/i", $sIndexSql ) ) {
00219
00220
00221 $sIndexSql = preg_replace("/(.*\bKEY\s+)`[^`]+`/", "$1", $sIndexSql );
00222
00223 if ( $blUsingTableSet ) {
00224
00225 $sIndexSql = preg_replace("/\([^\)]+\)/", "(`$sNewField`)", $sIndexSql );
00226 } else {
00227
00228 $sIndexSql = preg_replace("/\b" . $sField . "\b/", $sNewField, $sIndexSql );
00229 }
00230
00231 $aIndexSql[] = "ADD ". $sIndexSql;
00232 }
00233 }
00234 if ( count($aIndexSql) ) {
00235 $aSql = array("ALTER TABLE `$sTableSet` ".implode(", ", $aIndexSql));
00236 }
00237 }
00238
00239 return $aSql;
00240 }
00241
00248 public function getCurrentMaxLangId()
00249 {
00250 if ( isset($this->_iCurrentMaxLangId) ) {
00251 return $this->_iCurrentMaxLangId;
00252 }
00253
00254 $sTable = $sTableSet = "oxarticles";
00255 $sField = $sFieldSet = "oxtitle";
00256 $iLang = 0;
00257 while ($this->tableExists($sTableSet) && $this->fieldExists($sFieldSet, $sTableSet)) {
00258 $iLang ++;
00259 $sTableSet = getLangTableName($sTable, $iLang);
00260 $sFieldSet = $sField.'_'.$iLang;
00261 }
00262
00263 $this->_iCurrentMaxLangId = --$iLang;
00264 return $this->_iCurrentMaxLangId;
00265 }
00266
00272 public function getNextLangId()
00273 {
00274 return $this->getCurrentMaxLangId() + 1;
00275 }
00276
00284 public function getMultilangFields( $sTable )
00285 {
00286 $aFields = $this->getFields( $sTable );
00287 $aMultiLangFields = array();
00288
00289 foreach ( $aFields as $sField ) {
00290 if ( preg_match("/(.+)_1$/", $sField, $aMatches) ) {
00291 $aMultiLangFields[] = $aMatches[1];
00292 }
00293 }
00294
00295 return $aMultiLangFields;
00296 }
00297
00306 public function getSinglelangFields( $sTable, $iLang )
00307 {
00308 $aFields = array_merge($this->getFields( $sTable ), $this->getFields(getLangTableName($sTable, $iLang) ));
00309 $aSingleLangFields = array();
00310
00311 foreach ( $aFields as $sField ) {
00312 if ( preg_match("/(.+)_([0-9]+)$/", $sField, $aMatches) ) {
00313 if ($aMatches[2] == $iLang) {
00314 $aSingleLangFields[$aMatches[1]] = $sField;
00315 }
00316 } else {
00317 $aSingleLangFields[$sField] = $sField;
00318 }
00319 }
00320
00321 return $aSingleLangFields;
00322 }
00323
00332 public function addNewMultilangField( $sTable )
00333 {
00334 $aSql = array();
00335 $aFields = $this->getMultilangFields($sTable);
00336 $iMaxLang = $this->getCurrentMaxLangId();
00337 $iNewLang = $this->getNextLangId();
00338
00339 $sTableSet = getLangTableName($sTable, $iNewLang);
00340 if (!$this->tableExists($sTableSet)) {
00341 $aSql[] = $this->_getCreateTableSetSql( $sTable, $iNewLang );
00342 }
00343
00344 if ( is_array($aFields) && count($aFields) > 0 ) {
00345 foreach ( $aFields as $sField ) {
00346 $sNewFieldName = $sField . "_" . $iNewLang;
00347 if ($iNewLang>1) {
00348 $iPrevLang = $iNewLang-1;
00349 $sPrevField = $sField.'_'.$iPrevLang;
00350 } else {
00351 $sPrevField = $sField;
00352 }
00353
00354 if ( !$this->tableExists($sTableSet) || !$this->fieldExists( $sNewFieldName, $sTableSet ) ) {
00355
00356
00357 $aSql[] = $this->getAddFieldSql( $sTable, $sField, $sNewFieldName, $sPrevField, $sTableSet );
00358
00359
00360 $aSql = array_merge($aSql, (array) $this->getAddFieldIndexSql($sTable, $sField, $sNewFieldName, $sTableSet));
00361 }
00362 }
00363 }
00364
00365 $this->executeSql($aSql);
00366 }
00367
00377 public function resetMultilangFields( $iLangId, $sTableName )
00378 {
00379 $iLangId = (int)$iLangId;
00380
00381 if ( $iLangId === 0 ) {
00382 return;
00383 }
00384
00385 $aSql = array();
00386
00387 $aFields = $this->getMultilangFields( $sTableName );
00388 if ( is_array($aFields) && count($aFields) > 0 ) {
00389 foreach ( $aFields as $sFieldName ) {
00390 $sFieldName = $sFieldName . "_" . $iLangId;
00391
00392 if ( $this->fieldExists( $sFieldName, $sTableName ) ) {
00393
00394 $aSql[] = "UPDATE {$sTableName} SET {$sFieldName} = DEFAULT;";
00395 }
00396 }
00397 }
00398
00399 if ( !empty($aSql) ) {
00400 $this->executeSql( $aSql );
00401 }
00402 }
00403
00410 public function addNewLangToDb()
00411 {
00412
00413 $this->_iCurrentMaxLangId = null;
00414
00415 $aTable = $this->getAllTables();
00416
00417 foreach ( $aTable as $sTableName ) {
00418 $this->addNewMultilangField( $sTableName );
00419 }
00420
00421
00422 $this->updateViews();
00423 }
00424
00433 public function resetLanguage( $iLangId )
00434 {
00435 if ( (int)$iLangId === 0 ) {
00436 return;
00437 }
00438
00439 $aTables = $this->getAllTables();
00440
00441
00442 foreach ( $this->_aSkipTablesOnReset as $sSkipTable ) {
00443
00444 if ( ($iSkipId = array_search( $sSkipTable, $aTables )) !== false ) {
00445 unset( $aTables[$iSkipId] );
00446 }
00447 }
00448
00449 foreach ( $aTables as $sTableName ) {
00450 $this->resetMultilangFields( $iLangId, $sTableName );
00451 }
00452 }
00453
00461 public function executeSql( $aSql )
00462 {
00463 $oDb = oxDb::getDb();
00464
00465 if ( is_array($aSql) && !empty($aSql) ) {
00466 foreach ( $aSql as $sSql) {
00467 $sSql = trim($sSql);
00468 if (!empty($sSql)) {
00469 $oDb->execute( $sSql );
00470 }
00471 }
00472 }
00473 }
00474
00482 public function updateViews( $aTables = null )
00483 {
00484 set_time_limit( 0 );
00485
00486 $oDb = oxDb::getDb();
00487 $oConfig = oxRegistry::getConfig();
00488
00489 $aShops = $oDb->getAll( "select * from oxshops" );
00490
00491 $aTables = $aTables ? $aTables : $oConfig->getConfigParam( 'aMultiShopTables' );
00492
00493 $bSuccess = true;
00494 foreach ( $aShops as $aShop ) {
00495 $sShopId = $aShop[0];
00496 $oShop = oxNew( 'oxshop' );
00497 $oShop->load( $sShopId );
00498 $oShop->setMultiShopTables( $aTables );
00499 $blMultishopInherit = $oConfig->getShopConfVar( 'blMultishopInherit_oxcategories', $sShopId );
00500 $aMallInherit = array();
00501 foreach ( $aTables as $sTable ) {
00502 $aMallInherit[$sTable] = $oConfig->getShopConfVar( 'blMallInherit_' . $sTable, $sShopId );
00503 }
00504 if ( !$oShop->generateViews( $blMultishopInherit, $aMallInherit ) && $bSuccess ) {
00505 $bSuccess = false;
00506 }
00507 }
00508
00509 return $bSuccess;
00510 }
00511 }
00512