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