Go to the documentation of this file.00001 <?php
00002
00007 class oxDbMetaDataHandler extends oxSuperCfg
00008 {
00013 protected $_aDbTablesFields = null;
00014
00019 protected $_aTables = null;
00020
00025 protected $_iCurrentMaxLangId;
00026
00031 protected $_aSkipTablesOnReset = array( "oxcountry" );
00032
00040 public function getFields( $sTableName )
00041 {
00042
00043 if ( empty($this->_aDbTablesFields[$sTableName]) ) {
00044 $aFields = oxDb::getInstance()->getTableDescription( $sTableName );
00045
00046 $this->_aDbTablesFields[$sTableName] = array();
00047
00048 foreach ( $aFields as $oField ) {
00049 $this->_aDbTablesFields[$sTableName][] = $oField->name;
00050 }
00051 }
00052
00053 return $this->_aDbTablesFields[$sTableName];
00054 }
00055
00064 public function fieldExists( $sFieldName, $sTableName )
00065 {
00066 $aTableFields = $this->getFields( $sTableName );
00067
00068 if ( is_array($aTableFields) ) {
00069 $sFieldName = strtoupper( $sFieldName );
00070 if ( in_array( $sFieldName, $aTableFields ) ) {
00071 return true;
00072 }
00073 }
00074
00075 return false;
00076 }
00077
00078
00085 public function getAllTables()
00086 {
00087 if ( empty($this->_aTables) ) {
00088
00089 $aTables = oxDb::getDb()->getAll("show tables");
00090
00091 foreach ( $aTables as $aTableInfo) {
00092 $sTableName = $aTableInfo[0];
00093
00094 $this->_aTables[] = $aTableInfo[0];
00095 }
00096 }
00097
00098 return $this->_aTables;
00099 }
00100
00112 protected function _getDublicatedFieldSql( $sOldFieldName, $sNewFieldName, $sTableName, $sInsertAfterField = null )
00113 {
00114 if ( empty($sOldFieldName) || empty($sNewFieldName) || empty($sTableName) ) {
00115 return;
00116 }
00117
00118 $aRes = oxDb::getDb()->getAll("show create table {$sTableName}");
00119 $sSql = $aRes[0][1];
00120
00121 preg_match( "/.*,\s+(['`]?".$sOldFieldName."['`]?\s+[^,]+),.*/", $sSql, $aMatch );
00122 $sFieldSql = $aMatch[1];
00123
00124 $sFullSql = "";
00125
00126 if ( !empty($sFieldSql) ) {
00127
00128 $sFieldSql = preg_replace( "/" . $sOldFieldName . "/", $sNewFieldName, $sFieldSql );
00129 $sFullSql = "ALTER TABLE `$sTableName` ADD " . $sFieldSql;
00130
00131 if ( $sInsertAfterField ) {
00132 $sFullSql .= " AFTER `$sInsertAfterField`";
00133 }
00134 }
00135
00136 return $sFullSql;
00137 }
00138
00148 protected function _getDublicatedFieldIndexesSql( $sOldFieldName, $sNewFieldName, $sTableName )
00149 {
00150 if ( empty($sOldFieldName) || empty($sNewFieldName) || empty($sTableName) ) {
00151 return;
00152 }
00153
00154 $aRes = oxDb::getDb()->getAll("show create table {$sTableName}");
00155 $sSql = $aRes[0][1];
00156
00157 preg_match_all("/([\w]+\s+)?\bKEY\s+(`[^`]+`)?\s*\([^)]+\)/iU", $sSql, $aMatch);
00158
00159 $aIndexes = $aMatch[0];
00160
00161 $aNewIndexSql = array();
00162 $sFullSql = "";
00163
00164 if ( !empty($aIndexes) ) {
00165
00166 foreach ( $aIndexes as $sIndexSql ) {
00167 if ( preg_match("/\([^)]*\b" . $sOldFieldName . "\b[^)]*\)/i", $sIndexSql ) ) {
00168
00169
00170 $sIndexSql = preg_replace("/(.*\bKEY\s+)`[^`]+`/", "$1", $sIndexSql );
00171
00172
00173 $sIndexSql = preg_replace("/\b" . $sOldFieldName . "\b/", $sNewFieldName, $sIndexSql );
00174
00175 $sFullSql = "ALTER TABLE `$sTableName` ADD ". $sIndexSql;
00176 $aNewIndexSql[] = $sFullSql;
00177 }
00178 }
00179
00180 }
00181
00182 return $aNewIndexSql;
00183 }
00184
00191 public function getCurrentMaxLangId()
00192 {
00193 if ( isset($this->_iCurrentMaxLangId) ) {
00194 return $this->_iCurrentMaxLangId;
00195 }
00196
00197 $this->_iCurrentMaxLangId = 0;
00198
00199 $aFields = $this->getFields( "oxarticles" );
00200 $aIds = array();
00201
00202
00203 foreach ( $aFields as $sFieldName ) {
00204 if ( preg_match("/^OXTITLE_(\d+)$/i", $sFieldName, $aMatches) ) {
00205 $aIds[] = (int) $aMatches[1];
00206 }
00207 }
00208
00209 if ( count($aIds) > 0 ) {
00210 $this->_iCurrentMaxLangId = max($aIds );
00211 }
00212
00213 return $this->_iCurrentMaxLangId;
00214 }
00215
00221 public function getNextLangId()
00222 {
00223 return $this->getCurrentMaxLangId() + 1;
00224 }
00225
00233 public function getMultilangFields( $sTableName )
00234 {
00235 $aFields = $this->getFields( $sTableName );
00236 $aMultiLangFields = array();
00237
00238 foreach ( $aFields as $sFieldName ) {
00239 if ( preg_match("/(.+)_1$/", $sFieldName, $aMatches) ) {
00240 $aMultiLangFields[] = $aMatches[1];
00241 }
00242 }
00243
00244 return $aMultiLangFields;
00245 }
00246
00255 public function getSinglelangFields( $sTableName, $iLang )
00256 {
00257 $aFields = $this->getFields( $sTableName );
00258 $aSingleLangFields = array();
00259
00260 foreach ( $aFields as $sFieldName ) {
00261 if ( preg_match("/(.+)_([0-9]+)$/", $sFieldName, $aMatches) ) {
00262 if ($aMatches[2] == $iLang) {
00263 $aSingleLangFields[$aMatches[1]] = $sFieldName;
00264 }
00265 } else {
00266 $aSingleLangFields[$sFieldName] = $sFieldName;
00267 }
00268 }
00269
00270 return $aSingleLangFields;
00271 }
00272
00281 public function addNewMultilangField( $sTableName )
00282 {
00283 $aSql = array();
00284 $aIndexesSql = array();
00285
00286 $aFields = $this->getMultilangFields( $sTableName );
00287 $iLangNewBaseId = $this->getNextLangId();
00288 $iCurrentMaxLangId = $this->getCurrentMaxLangId();
00289
00290 if ( is_array($aFields) && count($aFields) > 0 ) {
00291 foreach ( $aFields as $sFieldName ) {
00292 $sNewFieldName = $sFieldName . "_" . $iLangNewBaseId;
00293 $sLastMultilangFieldName = ( !empty($iCurrentMaxLangId) ) ? $sFieldName . "_" . $iCurrentMaxLangId : $sFieldName;
00294
00295 if ( !$this->fieldExists( $sNewFieldName, $sTableName ) ) {
00296
00297 $aSql[] = $this->_getDublicatedFieldSql( $sFieldName, $sNewFieldName, $sTableName, $sLastMultilangFieldName );
00298
00299
00300 $aFieldIndexSql = $this->_getDublicatedFieldIndexesSql( $sLastMultilangFieldName, $sNewFieldName, $sTableName );
00301 if ( !empty($aFieldIndexSql) ) {
00302 $aIndexesSql = array_merge( $aIndexesSql, $aFieldIndexSql );
00303 }
00304 }
00305 }
00306 }
00307
00308 if ( !empty($aSql) ) {
00309 $this->_executeSql( $aSql );
00310 }
00311
00312 if ( !empty($aIndexesSql) ) {
00313 $this->_executeSql( $aIndexesSql );
00314 }
00315 }
00316
00326 public function resetMultilangFields( $iLangId, $sTableName )
00327 {
00328 $iLangId = (int)$iLangId;
00329
00330 if ( $iLangId === 0 ) {
00331 return;
00332 }
00333
00334 $aSql = array();
00335
00336 $aFields = $this->getMultilangFields( $sTableName );
00337 if ( is_array($aFields) && count($aFields) > 0 ) {
00338 foreach ( $aFields as $sFieldName ) {
00339 $sFieldName = $sFieldName . "_" . $iLangId;
00340
00341 if ( $this->fieldExists( $sFieldName, $sTableName ) ) {
00342
00343 $aSql[] = "UPDATE {$sTableName} SET {$sFieldName} = DEFAULT;";
00344 }
00345 }
00346 }
00347
00348 if ( !empty($aSql) ) {
00349 $this->_executeSql( $aSql );
00350 }
00351 }
00352
00359 public function addNewLangToDb()
00360 {
00361 $aTable = $this->getAllTables();
00362
00363 foreach ( $aTable as $sTableName ) {
00364 $this->addNewMultilangField( $sTableName );
00365 }
00366
00367 }
00368
00377 public function resetLanguage( $iLangId )
00378 {
00379 if ( (int)$iLangId === 0 ) {
00380 return;
00381 }
00382
00383 $aTables = $this->getAllTables();
00384
00385
00386 foreach ( $this->_aSkipTablesOnReset as $sSkipTable ) {
00387
00388 if ( ($iSkipId = array_search( $sSkipTable, $aTables )) !== false ) {
00389 unset( $aTables[$iSkipId] );
00390 }
00391 }
00392
00393 foreach ( $aTables as $sTableName ) {
00394 $this->resetMultilangFields( $iLangId, $sTableName );
00395 }
00396 }
00397
00405 protected function _executeSql( $aSql )
00406 {
00407 $oDb = oxDb::getDb();
00408
00409 if ( is_array($aSql) && !empty($aSql) ) {
00410 foreach ( $aSql as $sSql) {
00411 $oDb->execute( $sSql );
00412 }
00413 }
00414 }
00415
00416
00417 }
00418