OXID eShop CE  4.9.6
 All Classes Files Functions Variables Pages
oxdbmetadatahandler.php
Go to the documentation of this file.
1 <?php
2 
8 {
9 
14  protected $_aDbTablesFields = null;
15 
16 
21  protected $_aTables = null;
22 
28 
33  protected $_aSkipTablesOnReset = array("oxcountry");
34 
42  public function getFields($sTableName)
43  {
44  $aFields = array();
45  $aRawFields = oxDb::getDb()->MetaColumns($sTableName);
46  if (is_array($aRawFields)) {
47  foreach ($aRawFields as $oField) {
48  $aFields[$oField->name] = "{$sTableName}.{$oField->name}";
49  }
50  }
51 
52  return $aFields;
53  }
54 
62  public function tableExists($sTableName)
63  {
64  $oDb = oxDb::getDb();
65  $aTables = $oDb->getAll("show tables like " . $oDb->quote($sTableName));
66 
67  return count($aTables) > 0;
68  }
69 
78  public function fieldExists($sFieldName, $sTableName)
79  {
80  $aTableFields = $this->getFields($sTableName);
81  $sTableName = strtoupper($sTableName);
82  if (is_array($aTableFields)) {
83  $sFieldName = strtoupper($sFieldName);
84  $aTableFields = array_map('strtoupper', $aTableFields);
85  if (in_array("{$sTableName}.{$sFieldName}", $aTableFields)) {
86  return true;
87  }
88  }
89 
90  return false;
91  }
92 
93 
100  public function getAllTables()
101  {
102  if (empty($this->_aTables)) {
103 
104  $aTables = oxDb::getDb()->getAll("show tables");
105 
106  foreach ($aTables as $aTableInfo) {
107  $sTableName = $aTableInfo[0];
108 
109  $this->_aTables[] = $aTableInfo[0];
110  }
111  }
112 
113  return $this->_aTables;
114  }
115 
123  public function getAllMultiTables($sTable)
124  {
125  $aMLTables = array();
126  foreach (array_keys(oxRegistry::getLang()->getLanguageIds()) as $iLangId) {
127  $sLangTableName = getLangTableName($sTable, $iLangId);
128  if ($sTable != $sLangTableName && !in_array($sLangTableName, $aMLTables)) {
129  $aMLTables[] = $sLangTableName;
130  }
131  }
132 
133  return $aMLTables;
134  }
135 
145  protected function _getCreateTableSetSql($sTable, $iLang)
146  {
147  $sTableSet = getLangTableName($sTable, $iLang);
148 
149  $aRes = oxDb::getDb()->getAll("show create table {$sTable}");
150  $sSql = "CREATE TABLE `{$sTableSet}` (" .
151  "`OXID` char(32) COLLATE latin1_general_ci NOT NULL, " .
152  "PRIMARY KEY (`OXID`)" .
153  ") " . strstr($aRes[0][1], 'ENGINE=');
154 
155  return $sSql;
156  }
157 
169  public function getAddFieldSql($sTable, $sField, $sNewField, $sPrevField, $sTableSet = null)
170  {
171  if (!$sTableSet) {
172  $sTableSet = $sTable;
173  }
174  $aRes = oxDb::getDb()->getAll("show create table {$sTable}");
175  $sTableSql = $aRes[0][1];
176 
177  // removing comments;
178  $sTableSql = preg_replace('/COMMENT \\\'.*?\\\'/', '', $sTableSql);
179  preg_match("/.*,\s+(['`]?" . preg_quote($sField, '/') . "['`]?\s+[^,]+),.*/", $sTableSql, $aMatch);
180  $sFieldSql = $aMatch[1];
181 
182  $sSql = "";
183  if (!empty($sFieldSql)) {
184  $sFieldSql = preg_replace("/" . preg_quote($sField, '/') . "/", $sNewField, $sFieldSql);
185  $sSql = "ALTER TABLE `$sTableSet` ADD " . $sFieldSql;
186  if ($this->tableExists($sTableSet) && $this->fieldExists($sPrevField, $sTableSet)) {
187  $sSql .= " AFTER `$sPrevField`";
188  }
189  }
190 
191  return $sSql;
192  }
193 
194 
205  public function getAddFieldIndexSql($sTable, $sField, $sNewField, $sTableSet = null)
206  {
207  $aRes = oxDb::getDb()->getAll("show create table {$sTable}");
208 
209  $sTableSql = $aRes[0][1];
210 
211  preg_match_all("/([\w]+\s+)?\bKEY\s+(`[^`]+`)?\s*\([^)]+\)/iU", $sTableSql, $aMatch);
212  $aIndex = $aMatch[0];
213 
214  $blUsingTableSet = $sTableSet ? true : false;
215 
216  if (!$sTableSet) {
217  $sTableSet = $sTable;
218  }
219 
220  $aIndexSql = array();
221  $aSql = array();
222  if (count($aIndex)) {
223  foreach ($aIndex as $sIndexSql) {
224  if (preg_match("/\([^)]*\b" . $sField . "\b[^)]*\)/i", $sIndexSql)) {
225 
226  //removing index name - new will be added automaticly
227  $sIndexSql = preg_replace("/(.*\bKEY\s+)`[^`]+`/", "$1", $sIndexSql);
228 
229  if ($blUsingTableSet) {
230  // replacing multiple fields to one (#3269)
231  $sIndexSql = preg_replace("/\([^\)]+\)/", "(`$sNewField`)", $sIndexSql);
232  } else {
233  //replacing previous field name with new one
234  $sIndexSql = preg_replace("/\b" . $sField . "\b/", $sNewField, $sIndexSql);
235  }
236 
237  $aIndexSql[] = "ADD " . $sIndexSql;
238  }
239  }
240  if (count($aIndexSql)) {
241  $aSql = array("ALTER TABLE `$sTableSet` " . implode(", ", $aIndexSql));
242  }
243  }
244 
245  return $aSql;
246  }
247 
254  public function getCurrentMaxLangId()
255  {
256  if (isset($this->_iCurrentMaxLangId)) {
258  }
259 
260  $sTable = $sTableSet = "oxarticles";
261  $sField = $sFieldSet = "oxtitle";
262  $iLang = 0;
263  while ($this->tableExists($sTableSet) && $this->fieldExists($sFieldSet, $sTableSet)) {
264  $iLang++;
265  $sTableSet = getLangTableName($sTable, $iLang);
266  $sFieldSet = $sField . '_' . $iLang;
267  }
268 
269  $this->_iCurrentMaxLangId = --$iLang;
270 
272  }
273 
279  public function getNextLangId()
280  {
281  return $this->getCurrentMaxLangId() + 1;
282  }
283 
291  public function getMultilangFields($sTable)
292  {
293  $aFields = $this->getFields($sTable);
294  $aMultiLangFields = array();
295 
296  foreach ($aFields as $sField) {
297  if (preg_match("/({$sTable}\.)?(?<field>.+)_1$/", $sField, $aMatches)) {
298  $aMultiLangFields[] = $aMatches['field'];
299  }
300  }
301 
302  return $aMultiLangFields;
303  }
304 
313  public function getSinglelangFields($sTable, $iLang)
314  {
315  $sLangTable = getLangTableName($sTable, $iLang);
316 
317  $aBaseFields = $this->getFields($sTable);
318  $aLangFields = $this->getFields($sLangTable);
319  $aFields = array_merge($aLangFields, $aBaseFields);
320  $aSingleLangFields = array();
321 
322  foreach ($aFields as $sFieldName => $sField) {
323  if (preg_match("/(({$sTable}|{$sLangTable})\.)?(?<field>.+)_(?<lang>[0-9]+)$/", $sField, $aMatches)) {
324  if ($aMatches['lang'] == $iLang) {
325  $aSingleLangFields[$aMatches['field']] = $sField;
326  }
327  } else {
328  $aSingleLangFields[$sFieldName] = $sField;
329  }
330  }
331 
332  return $aSingleLangFields;
333  }
334 
341  public function addNewMultilangField($sTable)
342  {
343  $aSql = array();
344  $aFields = $this->getMultilangFields($sTable);
345  $iMaxLang = $this->getCurrentMaxLangId();
346  $iNewLang = $this->getNextLangId();
347 
348  $sTableSet = getLangTableName($sTable, $iNewLang);
349  if (!$this->tableExists($sTableSet)) {
350  $aSql[] = $this->_getCreateTableSetSql($sTable, $iNewLang);
351  }
352 
353  if (is_array($aFields) && count($aFields) > 0) {
354  foreach ($aFields as $sField) {
355  $sNewFieldName = $sField . "_" . $iNewLang;
356  if ($iNewLang > 1) {
357  $iPrevLang = $iNewLang - 1;
358  $sPrevField = $sField . '_' . $iPrevLang;
359  } else {
360  $sPrevField = $sField;
361  }
362 
363  if (!$this->tableExists($sTableSet) || !$this->fieldExists($sNewFieldName, $sTableSet)) {
364 
365  //getting add field sql
366  $aSql[] = $this->getAddFieldSql($sTable, $sField, $sNewFieldName, $sPrevField, $sTableSet);
367 
368  //getting add index sql on added field
369  $aSql = array_merge($aSql, (array) $this->getAddFieldIndexSql($sTable, $sField, $sNewFieldName, $sTableSet));
370  }
371  }
372  }
373 
374  $this->executeSql($aSql);
375  }
376 
386  public function resetMultilangFields($iLangId, $sTableName)
387  {
388  $iLangId = (int) $iLangId;
389 
390  if ($iLangId === 0) {
391  return;
392  }
393 
394  $aSql = array();
395 
396  $aFields = $this->getMultilangFields($sTableName);
397  if (is_array($aFields) && count($aFields) > 0) {
398  foreach ($aFields as $sFieldName) {
399  $sFieldName = $sFieldName . "_" . $iLangId;
400 
401  if ($this->fieldExists($sFieldName, $sTableName)) {
402  //resetting field value to default
403  $aSql[] = "UPDATE {$sTableName} SET {$sFieldName} = DEFAULT;";
404  }
405  }
406  }
407 
408  if (!empty($aSql)) {
409  $this->executeSql($aSql);
410  }
411  }
412 
417  public function addNewLangToDb()
418  {
419  //reset max count
420  $this->_iCurrentMaxLangId = null;
421 
422  $aTable = $this->getAllTables();
423 
424  foreach ($aTable as $sTableName) {
425  $this->addNewMultilangField($sTableName);
426  }
427 
428  //updating views
429  $this->updateViews();
430  }
431 
440  public function resetLanguage($iLangId)
441  {
442  if ((int) $iLangId === 0) {
443  return;
444  }
445 
446  $aTables = $this->getAllTables();
447 
448  // removing tables which does not requires reset
449  foreach ($this->_aSkipTablesOnReset as $sSkipTable) {
450 
451  if (($iSkipId = array_search($sSkipTable, $aTables)) !== false) {
452  unset($aTables[$iSkipId]);
453  }
454  }
455 
456  foreach ($aTables as $sTableName) {
457  $this->resetMultilangFields($iLangId, $sTableName);
458  }
459  }
460 
466  public function executeSql($aSql)
467  {
468  $oDb = oxDb::getDb();
469 
470  if (is_array($aSql) && !empty($aSql)) {
471  foreach ($aSql as $sSql) {
472  $sSql = trim($sSql);
473  if (!empty($sSql)) {
474  $oDb->execute($sSql);
475  }
476  }
477  }
478  }
479 
487  public function updateViews($aTables = null)
488  {
489  set_time_limit(0);
490 
491  $oDb = oxDb::getDb();
492  $oConfig = oxRegistry::getConfig();
493 
494  $aShops = $oDb->getAll("select * from oxshops");
495 
496  $aTables = $aTables ? $aTables : $oConfig->getConfigParam('aMultiShopTables');
497 
498  $bSuccess = true;
499  foreach ($aShops as $aShop) {
500  $sShopId = $aShop[0];
501  $oShop = oxNew('oxshop');
502  $oShop->load($sShopId);
503  $oShop->setMultiShopTables($aTables);
504  $aMallInherit = array();
505  foreach ($aTables as $sTable) {
506  $aMallInherit[$sTable] = $oConfig->getShopConfVar('blMallInherit_' . $sTable, $sShopId);
507  }
508  if (!$oShop->generateViews(false, $aMallInherit) && $bSuccess) {
509  $bSuccess = false;
510  }
511  }
512 
513  return $bSuccess;
514  }
515 }