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 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                     //getting creat field sql
00297                     $aSql[] = $this->_getDublicatedFieldSql( $sFieldName, $sNewFieldName, $sTableName, $sLastMultilangFieldName );
00298 
00299                     //getting create index sql on added field
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                     //reseting field value to default
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         // removing tables which does not requires reset
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