oxdbmetadatahandler.php

Go to the documentation of this file.
00001 <?php
00002 
00007 class oxDbMetaDataHandler extends oxSuperCfg
00008 {
00013     protected $_aDbTablesFields = null;
00014 
00015 
00020     protected $_aTables = null;
00021 
00026     protected $_iCurrentMaxLangId;
00027 
00032     protected $_aSkipTablesOnReset = array( "oxcountry" );
00033 
00041     public function getFields( $sTableName )
00042     {
00043         $aFields    = array();
00044         $aRawFields = oxDb::getDb()->MetaColumns( $sTableName );
00045         if (is_array($aRawFields)) {
00046             foreach ( $aRawFields as $oField ) {
00047                 $aFields[] = $oField->name;
00048             }
00049         }
00050         return $aFields;
00051     }
00052 
00060     public function tableExists( $sTableName )
00061     {
00062         $aTables = oxDb::getDb()->getAll("show tables like ".oxDb::getDb()->quote($sTableName));
00063         return count($aTables) > 0;
00064     }
00065 
00074     public function fieldExists( $sFieldName, $sTableName )
00075     {
00076         $aTableFields = $this->getFields( $sTableName );
00077 
00078         if ( is_array($aTableFields) ) {
00079             $sFieldName = strtoupper( $sFieldName );
00080             $aTableFields = array_map('strtoupper', $aTableFields);
00081             if ( in_array( $sFieldName, $aTableFields ) ) {
00082                 return true;
00083             }
00084         }
00085 
00086         return false;
00087     }
00088 
00089 
00096     public function getAllTables()
00097     {
00098         if ( empty($this->_aTables) ) {
00099 
00100             $aTables = oxDb::getDb()->getAll("show tables");
00101 
00102             foreach ( $aTables as $aTableInfo) {
00103                 $sTableName = $aTableInfo[0];
00104 
00105                 $this->_aTables[] = $aTableInfo[0];
00106             }
00107         }
00108         return $this->_aTables;
00109     }
00110 
00118     public function getAllMultiTables($sTable)
00119     {
00120         $aMLTables = array();
00121         foreach (array_keys(oxLang::getInstance()->getLanguageIds()) as $iLangId) {
00122             $sLangTableName = getLangTableName($sTable, $iLangId );
00123             if ($sTable != $sLangTableName && !in_array($sLangTableName, $aMLTables)) {
00124                 $aMLTables[] = $sLangTableName;
00125             }
00126         }
00127         return $aMLTables;
00128     }
00129 
00139     protected function _getCreateTableSetSql( $sTable, $iLang)
00140     {
00141         $sTableSet = getLangTableName($sTable, $iLang);
00142 
00143         $aRes = oxDb::getDb()->getAll("show create table {$sTable}");
00144         $sSql = "CREATE TABLE `{$sTableSet}` (".
00145                 "`OXID` char(32) COLLATE latin1_general_ci NOT NULL, ".
00146                 "PRIMARY KEY (`OXID`)".
00147                 ") ".strstr($aRes[0][1], 'ENGINE=');
00148         return $sSql;
00149     }
00150 
00160     protected function _getAddFieldSql( $sTable, $sField, $iLang )
00161     {
00162         $sTableSet = getLangTableName($sTable, $iLang);
00163         $sNewField = $sField.'_'.$iLang;
00164 
00165         if ($iLang>1) {
00166             $iPrevLang = $iLang-1;
00167             $sPrevField = $sField.'_'.$iPrevLang;
00168         } else {
00169             $sPrevField = $sField;
00170         }
00171 
00172         $aRes = oxDb::getDb()->getAll("show create table {$sTable}");
00173         $sTableSql = $aRes[0][1];
00174 
00175         preg_match( "/.*,\s+(['`]?".preg_quote($sField, '/')."['`]?\s+[^,]+),.*/", $sTableSql, $aMatch );
00176         $sFieldSql = $aMatch[1];
00177 
00178         $sSql = "";
00179         if ( !empty($sFieldSql) ) {
00180             $sFieldSql = preg_replace( "/".preg_quote($sField, '/')."/", $sNewField, $sFieldSql );
00181             $sSql = "ALTER TABLE `$sTableSet` ADD " . $sFieldSql;
00182             if ($this->tableExists($sTableSet) && $this->fieldExists($sPrevField, $sTableSet)) {
00183                 $sSql .= " AFTER `$sPrevField`";
00184             }
00185         }
00186         return $sSql;
00187     }
00188 
00189 
00190 
00200     protected function _getAddFieldIndexSql( $sTable, $sField, $iLang )
00201     {
00202         $sTableSet = getLangTableName($sTable, $iLang);
00203         $sNewField = $sField.'_'.$iLang;
00204 
00205         $aRes = oxDb::getDb()->getAll("show create table {$sTable}");
00206         $sTableSql = $aRes[0][1];
00207 
00208         preg_match_all("/([\w]+\s+)?\bKEY\s+(`[^`]+`)?\s*\([^)]+\)/iU", $sTableSql, $aMatch);
00209         $aIndex = $aMatch[0];
00210 
00211         $aIndexSql = array();
00212         if ( count($aIndex) ) {
00213             foreach ( $aIndex as $sIndexSql ) {
00214                 if ( preg_match("/\([^)]*\b" . $sField . "\b[^)]*\)/i", $sIndexSql )  ) {
00215 
00216                     //removing index name - new will be added automaticly
00217                     $sIndexSql = preg_replace("/(.*\bKEY\s+)`[^`]+`/", "$1", $sIndexSql );
00218 
00219                     //replacing previous field name with new one
00220                     $sIndexSql = preg_replace("/\b" . $sField . "\b/", $sNewField, $sIndexSql );
00221 
00222                     $aIndexSql[] =  "ALTER TABLE `$sTableSet` ADD ". $sIndexSql;
00223                 }
00224             }
00225         }
00226 
00227         return $aIndexSql;
00228     }
00229 
00236     public function getCurrentMaxLangId()
00237     {
00238         if ( isset($this->_iCurrentMaxLangId) ) {
00239             return $this->_iCurrentMaxLangId;
00240         }
00241 
00242         $sTable = $sTableSet = "oxarticles";
00243         $sField = $sFieldSet = "oxtitle";
00244         $iLang  = 0;
00245         while ($this->tableExists($sTableSet) && $this->fieldExists($sFieldSet, $sTableSet)) {
00246             $iLang ++;
00247             $sTableSet = getLangTableName($sTable, $iLang);
00248             $sFieldSet = $sField.'_'.$iLang;
00249         }
00250 
00251         $this->_iCurrentMaxLangId = --$iLang;
00252         return $this->_iCurrentMaxLangId;
00253     }
00254 
00260     public function getNextLangId()
00261     {
00262         return $this->getCurrentMaxLangId() + 1;
00263     }
00264 
00272     public function getMultilangFields( $sTable )
00273     {
00274         $aFields = $this->getFields( $sTable );
00275         $aMultiLangFields = array();
00276 
00277         foreach ( $aFields as $sField ) {
00278             if ( preg_match("/(.+)_1$/", $sField, $aMatches) ) {
00279                 $aMultiLangFields[] = $aMatches[1];
00280             }
00281         }
00282 
00283         return $aMultiLangFields;
00284     }
00285 
00294     public function getSinglelangFields( $sTable, $iLang )
00295     {
00296         $aFields = array_merge($this->getFields( $sTable ), $this->getFields(getLangTableName($sTable, $iLang) ));
00297         $aSingleLangFields = array();
00298 
00299         foreach ( $aFields as $sField ) {
00300             if ( preg_match("/(.+)_([0-9]+)$/", $sField, $aMatches) ) {
00301                 if ($aMatches[2] == $iLang) {
00302                     $aSingleLangFields[$aMatches[1]] = $sField;
00303                 }
00304             } else {
00305                 $aSingleLangFields[$sField] = $sField;
00306             }
00307         }
00308 
00309         return $aSingleLangFields;
00310     }
00311 
00320     public function addNewMultilangField( $sTable )
00321     {
00322         $aSql = array();
00323         $aFields  = $this->getMultilangFields($sTable);
00324         $iMaxLang = $this->getCurrentMaxLangId();
00325         $iNewLang = $this->getNextLangId();
00326 
00327         $sTableSet = getLangTableName($sTable, $iNewLang);
00328         if (!$this->tableExists($sTableSet)) {
00329             $aSql[] = $this->_getCreateTableSetSql( $sTable, $iNewLang );
00330         }
00331 
00332         if ( is_array($aFields) && count($aFields) > 0 ) {
00333             foreach ( $aFields as $sField ) {
00334                 $sNewFieldName = $sField . "_" . $iNewLang;
00335                 if ( !$this->tableExists($sTableSet) || !$this->fieldExists( $sNewFieldName, $sTableSet ) ) {
00336 
00337                     //getting add field sql
00338                     $aSql[] = $this->_getAddFieldSql($sTable, $sField, $iNewLang);
00339 
00340                     //getting add index sql on added field
00341                     $aSql = array_merge($aSql, (array) $this->_getAddFieldIndexSql($sTable, $sField, $iNewLang));
00342                 }
00343             }
00344         }
00345         $this->_executeSql($aSql);
00346     }
00347 
00357     public function resetMultilangFields( $iLangId, $sTableName )
00358     {
00359         $iLangId = (int)$iLangId;
00360 
00361         if ( $iLangId === 0 ) {
00362             return;
00363         }
00364 
00365         $aSql = array();
00366 
00367         $aFields = $this->getMultilangFields( $sTableName );
00368         if ( is_array($aFields) && count($aFields) > 0 ) {
00369             foreach ( $aFields as $sFieldName ) {
00370                 $sFieldName = $sFieldName . "_" . $iLangId;
00371 
00372                 if ( $this->fieldExists( $sFieldName, $sTableName ) ) {
00373                     //reseting field value to default
00374                     $aSql[] = "UPDATE {$sTableName} SET {$sFieldName} = DEFAULT;";
00375                 }
00376             }
00377         }
00378 
00379         if ( !empty($aSql) ) {
00380             $this->_executeSql( $aSql );
00381         }
00382     }
00383 
00390     public function addNewLangToDb()
00391     {
00392         //reset max count
00393         $this->_iCurrentMaxLangId = null;
00394 
00395         $aTable = $this->getAllTables();
00396 
00397         foreach ( $aTable as $sTableName ) {
00398             $this->addNewMultilangField( $sTableName );
00399         }
00400 
00401         //updating views
00402         $this->updateViews();
00403     }
00404 
00413     public function resetLanguage( $iLangId )
00414     {
00415         if ( (int)$iLangId === 0 ) {
00416             return;
00417         }
00418 
00419         $aTables = $this->getAllTables();
00420 
00421         // removing tables which does not requires reset
00422         foreach ( $this->_aSkipTablesOnReset as $sSkipTable ) {
00423 
00424             if ( ($iSkipId = array_search( $sSkipTable, $aTables )) !== false ) {
00425                 unset( $aTables[$iSkipId] );
00426             }
00427         }
00428 
00429         foreach ( $aTables as $sTableName ) {
00430             $this->resetMultilangFields( $iLangId, $sTableName );
00431         }
00432     }
00433 
00441     protected function _executeSql( $aSql )
00442     {
00443         $oDb = oxDb::getDb();
00444 
00445         if ( is_array($aSql) && !empty($aSql) ) {
00446             foreach ( $aSql as $sSql) {
00447                 $sSql = trim($sSql);
00448                 if (!empty($sSql)) {
00449                     $oDb->execute( $sSql );
00450                 }
00451             }
00452         }
00453     }
00454 
00460     public function updateViews()
00461     {
00462         oxDb::getInstance()->updateViews();
00463     }
00464 
00465 }
00466