00001 <?php
00002
00008 class oxDbMetaDataHandler extends oxSuperCfg
00009 {
00014 protected $_aDbTablesFields = null;
00015
00020 protected $_aTables = null;
00021
00026 protected $_iCurrentMaxLangId;
00027
00032 protected $_aSkipTablesOnReset = array( "oxcountry" );
00033
00038
00039
00047 public function getFields( $sTableName )
00048 {
00049
00050 if ( empty($this->_aDbTablesFields[$sTableName]) ) {
00051 $oaFields = oxDb::getInstance()->getTableDescription( $sTableName );
00052
00053 $this->_aDbTablesFields[$sTableName] = array();
00054
00055 foreach( $oaFields as $oField ) {
00056 $this->_aDbTablesFields[$sTableName][] = $oField->name;
00057 }
00058 }
00059
00060 return $this->_aDbTablesFields[$sTableName];
00061 }
00062
00071 public function fieldExists( $sFieldName, $sTableName )
00072 {
00073 $aTableFields = $this->getFields( $sTableName );
00074
00075 if ( is_array($aTableFields) ) {
00076 $sFieldName = strtoupper( $sFieldName );
00077 if ( in_array( $sFieldName, $aTableFields ) ) {
00078 return true;
00079 }
00080 }
00081
00082 return false;
00083 }
00084
00085
00092 public function getAllTables()
00093 {
00094 if ( empty($this->_aTables) ) {
00095
00096 $aTables = oxDb::getDb()->getAll("show tables");
00097
00098 foreach ( $aTables as $aTableInfo) {
00099 $sTableName = $aTableInfo[0];
00100
00101 $this->_aTables[] = $aTableInfo[0];
00102 }
00103 }
00104
00105 return $this->_aTables;
00106 }
00107
00119 protected function _getDublicatedFieldSql( $sOldFieldName, $sNewFieldName, $sTableName, $sInsertAfterField = null )
00120 {
00121 if ( empty($sOldFieldName) || empty($sNewFieldName) || empty($sTableName) ) {
00122 return;
00123 }
00124
00125 $aRes = oxDb::getDb()->getAll("show create table {$sTableName}");
00126 $sSql = $aRes[0][1];
00127
00128 preg_match( "/.*,\s+(['`]?".$sOldFieldName."['`]?\s+[^,]+),.*/", $sSql, $aMatch );
00129 $sFieldSql = $aMatch[1];
00130
00131 $sFullSql = "";
00132
00133 if ( !empty($sFieldSql) ) {
00134
00135 $sFieldSql = preg_replace( "/" . $sOldFieldName . "/", $sNewFieldName, $sFieldSql );
00136 $sFullSql = "ALTER TABLE `$sTableName` ADD " . $sFieldSql;
00137
00138 if ( $sInsertAfterField ) {
00139 $sFullSql .= " AFTER `$sInsertAfterField`";
00140 }
00141 }
00142
00143 return $sFullSql;
00144 }
00145
00155 protected function _getDublicatedFieldIndexesSql( $sOldFieldName, $sNewFieldName, $sTableName )
00156 {
00157 if ( empty($sOldFieldName) || empty($sNewFieldName) || empty($sTableName) ) {
00158 return;
00159 }
00160
00161 $aRes = oxDb::getDb()->getAll("show create table {$sTableName}");
00162 $sSql = $aRes[0][1];
00163
00164 preg_match_all("/([\w]+\s+)?\bKEY\s+(`[^`]+`)?\s*\([^)]+\)/iU", $sSql, $aMatch);
00165
00166 $aIndexes = $aMatch[0];
00167
00168 $aNewIndexSql = array();
00169 $sFullSql = "";
00170
00171 if ( !empty($aIndexes) ) {
00172
00173 foreach( $aIndexes as $sIndexSql ) {
00174 if ( preg_match("/\([^)]*\b" . $sOldFieldName . "\b[^)]*\)/i", $sIndexSql ) ) {
00175
00176
00177 $sIndexSql = preg_replace("/(.*\bKEY\s+)`[^`]+`/", "$1", $sIndexSql );
00178
00179
00180 $sIndexSql = preg_replace("/\b" . $sOldFieldName . "\b/", $sNewFieldName, $sIndexSql );
00181
00182 $sFullSql = "ALTER TABLE `$sTableName` ADD ". $sIndexSql;
00183 $aNewIndexSql[] = $sFullSql;
00184 }
00185 }
00186
00187 }
00188
00189 return $aNewIndexSql;
00190 }
00191
00198 public function getCurrentMaxLangId()
00199 {
00200 if ( isset($this->_iCurrentMaxLangId) ) {
00201 return $this->_iCurrentMaxLangId;
00202 }
00203
00204 $this->_iCurrentMaxLangId = 0;
00205
00206 $aFields = $this->getFields( "oxarticles" );
00207 $aIds = array();
00208
00209
00210 foreach( $aFields as $sFieldName ) {
00211 if ( preg_match("/^OXTITLE_(\d+)$/i", $sFieldName, $aMatches) ) {
00212 $aIds[] = (int) $aMatches[1];
00213 }
00214 }
00215
00216 if ( count($aIds) > 0 ) {
00217 $this->_iCurrentMaxLangId = max($aIds );
00218 }
00219
00220 return $this->_iCurrentMaxLangId;
00221 }
00222
00228 public function getNextLangId()
00229 {
00230 return $this->getCurrentMaxLangId() + 1;
00231 }
00232
00240 public function getMultilangFields( $sTableName )
00241 {
00242 $aFields = $this->getFields( $sTableName );
00243 $aMultiLangFields = array();
00244
00245 foreach( $aFields as $sFieldName ) {
00246 if ( preg_match("/(.+)_1$/", $sFieldName, $aMatches) ) {
00247 $aMultiLangFields[] = $aMatches[1];
00248 }
00249 }
00250
00251 return $aMultiLangFields;
00252 }
00253
00261 public function addNewMultilangField( $sTableName )
00262 {
00263 $aSql = array();
00264 $aIndexesSql = array();
00265
00266 $aFields = $this->getMultilangFields( $sTableName );
00267 $iLangNewBaseId = $this->getNextLangId();
00268 $iCurrentMaxLangId = $this->getCurrentMaxLangId();
00269
00270 if ( is_array($aFields) && count($aFields) > 0 ) {
00271 foreach( $aFields as $sFieldName ) {
00272 $sNewFieldName = $sFieldName . "_" . $iLangNewBaseId;
00273 $sLastMultilangFieldName = ( !empty($iCurrentMaxLangId) ) ? $sFieldName . "_" . $iCurrentMaxLangId : $sFieldName;
00274
00275 if ( !$this->fieldExists( $sNewFieldName, $sTableName ) ) {
00276
00277 $aSql[] = $this->_getDublicatedFieldSql( $sFieldName, $sNewFieldName, $sTableName, $sLastMultilangFieldName );
00278
00279
00280 $aFieldIndexSql = $this->_getDublicatedFieldIndexesSql( $sLastMultilangFieldName, $sNewFieldName, $sTableName );
00281 if ( !empty($aFieldIndexSql) ) {
00282 $aIndexesSql = array_merge( $aIndexesSql, $aFieldIndexSql );
00283 }
00284 }
00285 }
00286 }
00287
00288 if ( !empty($aSql) ) {
00289 $this->_executeSql( $aSql );
00290 }
00291
00292 if ( !empty($aIndexesSql) ) {
00293 $this->_executeSql( $aIndexesSql );
00294 }
00295 }
00296
00297
00302 public function resetMultilangFields( $iLangId, $sTableName )
00303 {
00304 $iLangId = (int)$iLangId;
00305
00306 if ( $iLangId === 0 ) {
00307 return;
00308 }
00309
00310 $aSql = array();
00311
00312 $aFields = $this->getMultilangFields( $sTableName );
00313 if ( is_array($aFields) && count($aFields) > 0 ) {
00314 foreach( $aFields as $sFieldName ) {
00315 $sFieldName = $sFieldName . "_" . $iLangId;
00316
00317 if ( $this->fieldExists( $sFieldName, $sTableName ) ) {
00318
00319 $aSql[] = "UPDATE {$sTableName} SET {$sFieldName} = DEFAULT;";
00320 }
00321 }
00322 }
00323
00324 if ( !empty($aSql) ) {
00325 $this->_executeSql( $aSql );
00326 }
00327 }
00328
00335 public function addNewLangToDb()
00336 {
00337 $aTable = $this->getAllTables();
00338
00339 foreach( $aTable as $sTableName ) {
00340 $this->addNewMultilangField( $sTableName );
00341 }
00342 }
00343
00349 public function resetLanguage( $iLangId )
00350 {
00351 if ( (int)$iLangId === 0 ) {
00352 return;
00353 }
00354
00355 $aTables = $this->getAllTables();
00356
00357
00358 foreach ( $this->_aSkipTablesOnReset as $sSkipTable ) {
00359
00360 if ( ($iSkipId = array_search( $sSkipTable, $aTables )) !== false ) {
00361 unset( $aTables[$iSkipId] );
00362 }
00363 }
00364
00365 foreach( $aTables as $sTableName ) {
00366 $this->resetMultilangFields( $iLangId, $sTableName );
00367 }
00368 }
00369
00377 protected function _executeSql( $aSql )
00378 {
00379 $oDb = oxDb::getDb();
00380
00381 if ( is_array($aSql) && !empty($aSql) ) {
00382 foreach( $aSql as $sSql) {
00383 $oDb->execute( $sSql );
00384 }
00385 }
00386 }
00387
00388 }
00389