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         $oDb = oxDb::getDb();
00063         $aTables = $oDb->getAll("show tables like ". $oDb->quote($sTableName));
00064         return count($aTables) > 0;
00065     }
00066 
00075     public function fieldExists( $sFieldName, $sTableName )
00076     {
00077         $aTableFields = $this->getFields( $sTableName );
00078 
00079         if ( is_array($aTableFields) ) {
00080             $sFieldName = strtoupper( $sFieldName );
00081             $aTableFields = array_map('strtoupper', $aTableFields);
00082             if ( in_array( $sFieldName, $aTableFields ) ) {
00083                 return true;
00084             }
00085         }
00086 
00087         return false;
00088     }
00089 
00090 
00097     public function getAllTables()
00098     {
00099         if ( empty($this->_aTables) ) {
00100 
00101             $aTables = oxDb::getDb()->getAll("show tables");
00102 
00103             foreach ( $aTables as $aTableInfo) {
00104                 $sTableName = $aTableInfo[0];
00105 
00106                 $this->_aTables[] = $aTableInfo[0];
00107             }
00108         }
00109         return $this->_aTables;
00110     }
00111 
00119     public function getAllMultiTables($sTable)
00120     {
00121         $aMLTables = array();
00122         foreach (array_keys(oxRegistry::getLang()->getLanguageIds()) as $iLangId) {
00123             $sLangTableName = getLangTableName($sTable, $iLangId );
00124             if ($sTable != $sLangTableName && !in_array($sLangTableName, $aMLTables)) {
00125                 $aMLTables[] = $sLangTableName;
00126             }
00127         }
00128         return $aMLTables;
00129     }
00130 
00140     protected function _getCreateTableSetSql( $sTable, $iLang)
00141     {
00142         $sTableSet = getLangTableName($sTable, $iLang);
00143 
00144         $aRes = oxDb::getDb()->getAll( "show create table {$sTable}" );
00145         $sSql = "CREATE TABLE `{$sTableSet}` (".
00146                 "`OXID` char(32) COLLATE latin1_general_ci NOT NULL, ".
00147                 "PRIMARY KEY (`OXID`)".
00148                 ") ".strstr($aRes[0][1], 'ENGINE=');
00149         return $sSql;
00150     }
00151 
00163     public function getAddFieldSql( $sTable, $sField, $sNewField, $sPrevField, $sTableSet = null )
00164     {
00165         if (!$sTableSet) {
00166             $sTableSet = $sTable;
00167         }
00168         $aRes = oxDb::getDb()->getAll( "show create table {$sTable}" );
00169         $sTableSql = $aRes[0][1];
00170 
00171         // removing comments;
00172         $sTableSql = preg_replace('/COMMENT \\\'.*?\\\'/', '', $sTableSql);
00173         preg_match( "/.*,\s+(['`]?".preg_quote($sField, '/')."['`]?\s+[^,]+),.*/", $sTableSql, $aMatch );
00174         $sFieldSql = $aMatch[1];
00175 
00176         $sSql = "";
00177         if ( !empty($sFieldSql) ) {
00178             $sFieldSql = preg_replace( "/".preg_quote($sField, '/')."/", $sNewField, $sFieldSql );
00179             $sSql = "ALTER TABLE `$sTableSet` ADD " . $sFieldSql;
00180             if ($this->tableExists($sTableSet) && $this->fieldExists($sPrevField, $sTableSet)) {
00181                 $sSql .= " AFTER `$sPrevField`";
00182             }
00183         }
00184         return $sSql;
00185     }
00186 
00187 
00188 
00199     public function getAddFieldIndexSql( $sTable, $sField, $sNewField, $sTableSet = null )
00200     {
00201         $aRes = oxDb::getDb()->getAll( "show create table {$sTable}" );
00202 
00203         $sTableSql = $aRes[0][1];
00204 
00205         preg_match_all("/([\w]+\s+)?\bKEY\s+(`[^`]+`)?\s*\([^)]+\)/iU", $sTableSql, $aMatch);
00206         $aIndex = $aMatch[0];
00207 
00208         $blUsingTableSet = $sTableSet ?  true : false;
00209 
00210         if (!$sTableSet) {
00211             $sTableSet = $sTable;
00212         }
00213 
00214         $aIndexSql = array();
00215         $aSql      = array();
00216         if ( count($aIndex) ) {
00217             foreach ( $aIndex as $sIndexSql ) {
00218                 if ( preg_match("/\([^)]*\b" . $sField . "\b[^)]*\)/i", $sIndexSql )  ) {
00219 
00220                     //removing index name - new will be added automaticly
00221                     $sIndexSql = preg_replace("/(.*\bKEY\s+)`[^`]+`/", "$1", $sIndexSql );
00222 
00223                     if ( $blUsingTableSet ) {
00224                         // replacing multiple fields to one (#3269)
00225                         $sIndexSql = preg_replace("/\([^\)]+\)/", "(`$sNewField`)", $sIndexSql );
00226                     } else {
00227                         //replacing previous field name with new one
00228                         $sIndexSql = preg_replace("/\b" . $sField . "\b/", $sNewField, $sIndexSql );
00229                     }
00230 
00231                     $aIndexSql[] =  "ADD ". $sIndexSql;
00232                 }
00233             }
00234             if ( count($aIndexSql) ) {
00235                 $aSql = array("ALTER TABLE `$sTableSet` ".implode(", ", $aIndexSql));
00236             }
00237         }
00238 
00239         return $aSql;
00240     }
00241 
00248     public function getCurrentMaxLangId()
00249     {
00250         if ( isset($this->_iCurrentMaxLangId) ) {
00251             return $this->_iCurrentMaxLangId;
00252         }
00253 
00254         $sTable = $sTableSet = "oxarticles";
00255         $sField = $sFieldSet = "oxtitle";
00256         $iLang  = 0;
00257         while ($this->tableExists($sTableSet) && $this->fieldExists($sFieldSet, $sTableSet)) {
00258             $iLang ++;
00259             $sTableSet = getLangTableName($sTable, $iLang);
00260             $sFieldSet = $sField.'_'.$iLang;
00261         }
00262 
00263         $this->_iCurrentMaxLangId = --$iLang;
00264         return $this->_iCurrentMaxLangId;
00265     }
00266 
00272     public function getNextLangId()
00273     {
00274         return $this->getCurrentMaxLangId() + 1;
00275     }
00276 
00284     public function getMultilangFields( $sTable )
00285     {
00286         $aFields = $this->getFields( $sTable );
00287         $aMultiLangFields = array();
00288 
00289         foreach ( $aFields as $sField ) {
00290             if ( preg_match("/(.+)_1$/", $sField, $aMatches) ) {
00291                 $aMultiLangFields[] = $aMatches[1];
00292             }
00293         }
00294 
00295         return $aMultiLangFields;
00296     }
00297 
00306     public function getSinglelangFields( $sTable, $iLang )
00307     {
00308         $aFields = array_merge($this->getFields( $sTable ), $this->getFields(getLangTableName($sTable, $iLang) ));
00309         $aSingleLangFields = array();
00310 
00311         foreach ( $aFields as $sField ) {
00312             if ( preg_match("/(.+)_([0-9]+)$/", $sField, $aMatches) ) {
00313                 if ($aMatches[2] == $iLang) {
00314                     $aSingleLangFields[$aMatches[1]] = $sField;
00315                 }
00316             } else {
00317                 $aSingleLangFields[$sField] = $sField;
00318             }
00319         }
00320 
00321         return $aSingleLangFields;
00322     }
00323 
00332     public function addNewMultilangField( $sTable )
00333     {
00334         $aSql = array();
00335         $aFields  = $this->getMultilangFields($sTable);
00336         $iMaxLang = $this->getCurrentMaxLangId();
00337         $iNewLang = $this->getNextLangId();
00338 
00339         $sTableSet = getLangTableName($sTable, $iNewLang);
00340         if (!$this->tableExists($sTableSet)) {
00341             $aSql[] = $this->_getCreateTableSetSql( $sTable, $iNewLang );
00342         }
00343 
00344         if ( is_array($aFields) && count($aFields) > 0 ) {
00345             foreach ( $aFields as $sField ) {
00346                 $sNewFieldName = $sField . "_" . $iNewLang;
00347                 if ($iNewLang>1) {
00348                     $iPrevLang = $iNewLang-1;
00349                     $sPrevField = $sField.'_'.$iPrevLang;
00350                 } else {
00351                     $sPrevField = $sField;
00352                 }
00353 
00354                 if ( !$this->tableExists($sTableSet) || !$this->fieldExists( $sNewFieldName, $sTableSet ) ) {
00355 
00356                     //getting add field sql
00357                     $aSql[] = $this->getAddFieldSql( $sTable, $sField, $sNewFieldName, $sPrevField, $sTableSet );
00358 
00359                     //getting add index sql on added field
00360                     $aSql = array_merge($aSql, (array) $this->getAddFieldIndexSql($sTable, $sField, $sNewFieldName, $sTableSet));
00361                 }
00362             }
00363         }
00364 
00365         $this->executeSql($aSql);
00366     }
00367 
00377     public function resetMultilangFields( $iLangId, $sTableName )
00378     {
00379         $iLangId = (int)$iLangId;
00380 
00381         if ( $iLangId === 0 ) {
00382             return;
00383         }
00384 
00385         $aSql = array();
00386 
00387         $aFields = $this->getMultilangFields( $sTableName );
00388         if ( is_array($aFields) && count($aFields) > 0 ) {
00389             foreach ( $aFields as $sFieldName ) {
00390                 $sFieldName = $sFieldName . "_" . $iLangId;
00391 
00392                 if ( $this->fieldExists( $sFieldName, $sTableName ) ) {
00393                     //reseting field value to default
00394                     $aSql[] = "UPDATE {$sTableName} SET {$sFieldName} = DEFAULT;";
00395                 }
00396             }
00397         }
00398 
00399         if ( !empty($aSql) ) {
00400             $this->executeSql( $aSql );
00401         }
00402     }
00403 
00410     public function addNewLangToDb()
00411     {
00412         //reset max count
00413         $this->_iCurrentMaxLangId = null;
00414 
00415         $aTable = $this->getAllTables();
00416 
00417         foreach ( $aTable as $sTableName ) {
00418             $this->addNewMultilangField( $sTableName );
00419         }
00420 
00421         //updating views
00422         $this->updateViews();
00423     }
00424 
00433     public function resetLanguage( $iLangId )
00434     {
00435         if ( (int)$iLangId === 0 ) {
00436             return;
00437         }
00438 
00439         $aTables = $this->getAllTables();
00440 
00441         // removing tables which does not requires reset
00442         foreach ( $this->_aSkipTablesOnReset as $sSkipTable ) {
00443 
00444             if ( ($iSkipId = array_search( $sSkipTable, $aTables )) !== false ) {
00445                 unset( $aTables[$iSkipId] );
00446             }
00447         }
00448 
00449         foreach ( $aTables as $sTableName ) {
00450             $this->resetMultilangFields( $iLangId, $sTableName );
00451         }
00452     }
00453 
00461     public function executeSql( $aSql )
00462     {
00463         $oDb = oxDb::getDb();
00464 
00465         if ( is_array($aSql) && !empty($aSql) ) {
00466             foreach ( $aSql as $sSql) {
00467                 $sSql = trim($sSql);
00468                 if (!empty($sSql)) {
00469                     $oDb->execute( $sSql );
00470                 }
00471             }
00472         }
00473     }
00474 
00482     public function updateViews( $aTables = null )
00483     {
00484         set_time_limit( 0 );
00485 
00486         $oDb = oxDb::getDb();
00487         $oConfig = oxRegistry::getConfig();
00488 
00489         $aShops = $oDb->getAll( "select * from oxshops" );
00490 
00491         $aTables = $aTables ? $aTables : $oConfig->getConfigParam( 'aMultiShopTables' );
00492 
00493         $bSuccess = true;
00494         foreach ( $aShops as $aShop ) {
00495             $sShopId = $aShop[0];
00496             $oShop = oxNew( 'oxshop' );
00497             $oShop->load( $sShopId );
00498             $oShop->setMultiShopTables( $aTables );
00499             $blMultishopInherit = $oConfig->getShopConfVar( 'blMultishopInherit_oxcategories', $sShopId );
00500             $aMallInherit = array();
00501             foreach ( $aTables as $sTable ) {
00502                 $aMallInherit[$sTable] = $oConfig->getShopConfVar( 'blMallInherit_' . $sTable, $sShopId );
00503             }
00504             if ( !$oShop->generateViews( $blMultishopInherit, $aMallInherit ) && $bSuccess ) {
00505                 $bSuccess = false;
00506             }
00507         }
00508 
00509         return $bSuccess;
00510     }
00511 }
00512