oxdbmetadatahandler.php

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                     //removing index name - new will be added automaticly
00170                     $sIndexSql = preg_replace("/(.*\bKEY\s+)`[^`]+`/", "$1", $sIndexSql );
00171 
00172                     //replacing old field name with new one
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         //checking max "oxarticles" table field "oxtitle" lang suffics value (_1 ,_2 ...)
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                     //getting creat field sql
00271                     $aSql[] = $this->_getDublicatedFieldSql( $sFieldName, $sNewFieldName, $sTableName, $sLastMultilangFieldName );
00272 
00273                     //getting create index sql on added field
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                     //reseting field value to default
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         // removing tables which does not requires reset
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