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 $aTables = oxDb::getDb()->getAll("show tables like ".oxDb::getDb()->quote($sTableName));
00063 return count($aTables) > 0;
00064 }
00065
00074 public function fieldExists( $sFieldName, $sTableName )
00075 {
00076 $aTableFields = $this->getFields( $sTableName );
00077
00078 if ( is_array($aTableFields) ) {
00079 $sFieldName = strtoupper( $sFieldName );
00080 $aTableFields = array_map('strtoupper', $aTableFields);
00081 if ( in_array( $sFieldName, $aTableFields ) ) {
00082 return true;
00083 }
00084 }
00085
00086 return false;
00087 }
00088
00089
00096 public function getAllTables()
00097 {
00098 if ( empty($this->_aTables) ) {
00099
00100 $aTables = oxDb::getDb()->getAll("show tables");
00101
00102 foreach ( $aTables as $aTableInfo) {
00103 $sTableName = $aTableInfo[0];
00104
00105 $this->_aTables[] = $aTableInfo[0];
00106 }
00107 }
00108 return $this->_aTables;
00109 }
00110
00118 public function getAllMultiTables($sTable)
00119 {
00120 $aMLTables = array();
00121 foreach (array_keys(oxLang::getInstance()->getLanguageIds()) as $iLangId) {
00122 $sLangTableName = getLangTableName($sTable, $iLangId );
00123 if ($sTable != $sLangTableName && !in_array($sLangTableName, $aMLTables)) {
00124 $aMLTables[] = $sLangTableName;
00125 }
00126 }
00127 return $aMLTables;
00128 }
00129
00139 protected function _getCreateTableSetSql( $sTable, $iLang)
00140 {
00141 $sTableSet = getLangTableName($sTable, $iLang);
00142
00143 $aRes = oxDb::getDb()->getAll("show create table {$sTable}");
00144 $sSql = "CREATE TABLE `{$sTableSet}` (".
00145 "`OXID` char(32) COLLATE latin1_general_ci NOT NULL, ".
00146 "PRIMARY KEY (`OXID`)".
00147 ") ".strstr($aRes[0][1], 'ENGINE=');
00148 return $sSql;
00149 }
00150
00160 protected function _getAddFieldSql( $sTable, $sField, $iLang )
00161 {
00162 $sTableSet = getLangTableName($sTable, $iLang);
00163 $sNewField = $sField.'_'.$iLang;
00164
00165 if ($iLang>1) {
00166 $iPrevLang = $iLang-1;
00167 $sPrevField = $sField.'_'.$iPrevLang;
00168 } else {
00169 $sPrevField = $sField;
00170 }
00171
00172 $aRes = oxDb::getDb()->getAll("show create table {$sTable}");
00173 $sTableSql = $aRes[0][1];
00174
00175 preg_match( "/.*,\s+(['`]?".preg_quote($sField, '/')."['`]?\s+[^,]+),.*/", $sTableSql, $aMatch );
00176 $sFieldSql = $aMatch[1];
00177
00178 $sSql = "";
00179 if ( !empty($sFieldSql) ) {
00180 $sFieldSql = preg_replace( "/".preg_quote($sField, '/')."/", $sNewField, $sFieldSql );
00181 $sSql = "ALTER TABLE `$sTableSet` ADD " . $sFieldSql;
00182 if ($this->tableExists($sTableSet) && $this->fieldExists($sPrevField, $sTableSet)) {
00183 $sSql .= " AFTER `$sPrevField`";
00184 }
00185 }
00186 return $sSql;
00187 }
00188
00189
00190
00200 protected function _getAddFieldIndexSql( $sTable, $sField, $iLang )
00201 {
00202 $sTableSet = getLangTableName($sTable, $iLang);
00203 $sNewField = $sField.'_'.$iLang;
00204
00205 $aRes = oxDb::getDb()->getAll("show create table {$sTable}");
00206 $sTableSql = $aRes[0][1];
00207
00208 preg_match_all("/([\w]+\s+)?\bKEY\s+(`[^`]+`)?\s*\([^)]+\)/iU", $sTableSql, $aMatch);
00209 $aIndex = $aMatch[0];
00210
00211 $aIndexSql = array();
00212 if ( count($aIndex) ) {
00213 foreach ( $aIndex as $sIndexSql ) {
00214 if ( preg_match("/\([^)]*\b" . $sField . "\b[^)]*\)/i", $sIndexSql ) ) {
00215
00216
00217 $sIndexSql = preg_replace("/(.*\bKEY\s+)`[^`]+`/", "$1", $sIndexSql );
00218
00219
00220 $sIndexSql = preg_replace("/\b" . $sField . "\b/", $sNewField, $sIndexSql );
00221
00222 $aIndexSql[] = "ALTER TABLE `$sTableSet` ADD ". $sIndexSql;
00223 }
00224 }
00225 }
00226
00227 return $aIndexSql;
00228 }
00229
00236 public function getCurrentMaxLangId()
00237 {
00238 if ( isset($this->_iCurrentMaxLangId) ) {
00239 return $this->_iCurrentMaxLangId;
00240 }
00241
00242 $sTable = $sTableSet = "oxarticles";
00243 $sField = $sFieldSet = "oxtitle";
00244 $iLang = 0;
00245 while ($this->tableExists($sTableSet) && $this->fieldExists($sFieldSet, $sTableSet)) {
00246 $iLang ++;
00247 $sTableSet = getLangTableName($sTable, $iLang);
00248 $sFieldSet = $sField.'_'.$iLang;
00249 }
00250
00251 $this->_iCurrentMaxLangId = --$iLang;
00252 return $this->_iCurrentMaxLangId;
00253 }
00254
00260 public function getNextLangId()
00261 {
00262 return $this->getCurrentMaxLangId() + 1;
00263 }
00264
00272 public function getMultilangFields( $sTable )
00273 {
00274 $aFields = $this->getFields( $sTable );
00275 $aMultiLangFields = array();
00276
00277 foreach ( $aFields as $sField ) {
00278 if ( preg_match("/(.+)_1$/", $sField, $aMatches) ) {
00279 $aMultiLangFields[] = $aMatches[1];
00280 }
00281 }
00282
00283 return $aMultiLangFields;
00284 }
00285
00294 public function getSinglelangFields( $sTable, $iLang )
00295 {
00296 $aFields = array_merge($this->getFields( $sTable ), $this->getFields(getLangTableName($sTable, $iLang) ));
00297 $aSingleLangFields = array();
00298
00299 foreach ( $aFields as $sField ) {
00300 if ( preg_match("/(.+)_([0-9]+)$/", $sField, $aMatches) ) {
00301 if ($aMatches[2] == $iLang) {
00302 $aSingleLangFields[$aMatches[1]] = $sField;
00303 }
00304 } else {
00305 $aSingleLangFields[$sField] = $sField;
00306 }
00307 }
00308
00309 return $aSingleLangFields;
00310 }
00311
00320 public function addNewMultilangField( $sTable )
00321 {
00322 $aSql = array();
00323 $aFields = $this->getMultilangFields($sTable);
00324 $iMaxLang = $this->getCurrentMaxLangId();
00325 $iNewLang = $this->getNextLangId();
00326
00327 $sTableSet = getLangTableName($sTable, $iNewLang);
00328 if (!$this->tableExists($sTableSet)) {
00329 $aSql[] = $this->_getCreateTableSetSql( $sTable, $iNewLang );
00330 }
00331
00332 if ( is_array($aFields) && count($aFields) > 0 ) {
00333 foreach ( $aFields as $sField ) {
00334 $sNewFieldName = $sField . "_" . $iNewLang;
00335 if ( !$this->tableExists($sTableSet) || !$this->fieldExists( $sNewFieldName, $sTableSet ) ) {
00336
00337
00338 $aSql[] = $this->_getAddFieldSql($sTable, $sField, $iNewLang);
00339
00340
00341 $aSql = array_merge($aSql, (array) $this->_getAddFieldIndexSql($sTable, $sField, $iNewLang));
00342 }
00343 }
00344 }
00345 $this->_executeSql($aSql);
00346 }
00347
00357 public function resetMultilangFields( $iLangId, $sTableName )
00358 {
00359 $iLangId = (int)$iLangId;
00360
00361 if ( $iLangId === 0 ) {
00362 return;
00363 }
00364
00365 $aSql = array();
00366
00367 $aFields = $this->getMultilangFields( $sTableName );
00368 if ( is_array($aFields) && count($aFields) > 0 ) {
00369 foreach ( $aFields as $sFieldName ) {
00370 $sFieldName = $sFieldName . "_" . $iLangId;
00371
00372 if ( $this->fieldExists( $sFieldName, $sTableName ) ) {
00373
00374 $aSql[] = "UPDATE {$sTableName} SET {$sFieldName} = DEFAULT;";
00375 }
00376 }
00377 }
00378
00379 if ( !empty($aSql) ) {
00380 $this->_executeSql( $aSql );
00381 }
00382 }
00383
00390 public function addNewLangToDb()
00391 {
00392
00393 $this->_iCurrentMaxLangId = null;
00394
00395 $aTable = $this->getAllTables();
00396
00397 foreach ( $aTable as $sTableName ) {
00398 $this->addNewMultilangField( $sTableName );
00399 }
00400
00401
00402 $this->updateViews();
00403 }
00404
00413 public function resetLanguage( $iLangId )
00414 {
00415 if ( (int)$iLangId === 0 ) {
00416 return;
00417 }
00418
00419 $aTables = $this->getAllTables();
00420
00421
00422 foreach ( $this->_aSkipTablesOnReset as $sSkipTable ) {
00423
00424 if ( ($iSkipId = array_search( $sSkipTable, $aTables )) !== false ) {
00425 unset( $aTables[$iSkipId] );
00426 }
00427 }
00428
00429 foreach ( $aTables as $sTableName ) {
00430 $this->resetMultilangFields( $iLangId, $sTableName );
00431 }
00432 }
00433
00441 protected function _executeSql( $aSql )
00442 {
00443 $oDb = oxDb::getDb();
00444
00445 if ( is_array($aSql) && !empty($aSql) ) {
00446 foreach ( $aSql as $sSql) {
00447 $sSql = trim($sSql);
00448 if (!empty($sSql)) {
00449 $oDb->execute( $sSql );
00450 }
00451 }
00452 }
00453 }
00454
00460 public function updateViews()
00461 {
00462 oxDb::getInstance()->updateViews();
00463 }
00464
00465 }
00466