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 addNewMultilangField( $sTableName )
00256 {
00257 $aSql = array();
00258 $aIndexesSql = array();
00259
00260 $aFields = $this->getMultilangFields( $sTableName );
00261 $iLangNewBaseId = $this->getNextLangId();
00262 $iCurrentMaxLangId = $this->getCurrentMaxLangId();
00263
00264 if ( is_array($aFields) && count($aFields) > 0 ) {
00265 foreach ( $aFields as $sFieldName ) {
00266 $sNewFieldName = $sFieldName . "_" . $iLangNewBaseId;
00267 $sLastMultilangFieldName = ( !empty($iCurrentMaxLangId) ) ? $sFieldName . "_" . $iCurrentMaxLangId : $sFieldName;
00268
00269 if ( !$this->fieldExists( $sNewFieldName, $sTableName ) ) {
00270
00271 $aSql[] = $this->_getDublicatedFieldSql( $sFieldName, $sNewFieldName, $sTableName, $sLastMultilangFieldName );
00272
00273
00274 $aFieldIndexSql = $this->_getDublicatedFieldIndexesSql( $sLastMultilangFieldName, $sNewFieldName, $sTableName );
00275 if ( !empty($aFieldIndexSql) ) {
00276 $aIndexesSql = array_merge( $aIndexesSql, $aFieldIndexSql );
00277 }
00278 }
00279 }
00280 }
00281
00282 if ( !empty($aSql) ) {
00283 $this->_executeSql( $aSql );
00284 }
00285
00286 if ( !empty($aIndexesSql) ) {
00287 $this->_executeSql( $aIndexesSql );
00288 }
00289 }
00290
00300 public function resetMultilangFields( $iLangId, $sTableName )
00301 {
00302 $iLangId = (int)$iLangId;
00303
00304 if ( $iLangId === 0 ) {
00305 return;
00306 }
00307
00308 $aSql = array();
00309
00310 $aFields = $this->getMultilangFields( $sTableName );
00311 if ( is_array($aFields) && count($aFields) > 0 ) {
00312 foreach ( $aFields as $sFieldName ) {
00313 $sFieldName = $sFieldName . "_" . $iLangId;
00314
00315 if ( $this->fieldExists( $sFieldName, $sTableName ) ) {
00316
00317 $aSql[] = "UPDATE {$sTableName} SET {$sFieldName} = DEFAULT;";
00318 }
00319 }
00320 }
00321
00322 if ( !empty($aSql) ) {
00323 $this->_executeSql( $aSql );
00324 }
00325 }
00326
00333 public function addNewLangToDb()
00334 {
00335 $aTable = $this->getAllTables();
00336
00337 foreach ( $aTable as $sTableName ) {
00338 $this->addNewMultilangField( $sTableName );
00339 }
00340
00341 }
00342
00351 public function resetLanguage( $iLangId )
00352 {
00353 if ( (int)$iLangId === 0 ) {
00354 return;
00355 }
00356
00357 $aTables = $this->getAllTables();
00358
00359
00360 foreach ( $this->_aSkipTablesOnReset as $sSkipTable ) {
00361
00362 if ( ($iSkipId = array_search( $sSkipTable, $aTables )) !== false ) {
00363 unset( $aTables[$iSkipId] );
00364 }
00365 }
00366
00367 foreach ( $aTables as $sTableName ) {
00368 $this->resetMultilangFields( $iLangId, $sTableName );
00369 }
00370 }
00371
00379 protected function _executeSql( $aSql )
00380 {
00381 $oDb = oxDb::getDb();
00382
00383 if ( is_array($aSql) && !empty($aSql) ) {
00384 foreach ( $aSql as $sSql) {
00385 $oDb->execute( $sSql );
00386 }
00387 }
00388 }
00389
00390
00391 }
00392