OXID eShop CE  4.10.7
 All Classes Namespaces Files Functions Variables Pages
oxi18n.php
Go to the documentation of this file.
1 <?php
2 
10 class oxI18n extends oxBase
11 {
12 
18  protected $_sClassName = 'oxI18n';
19 
25  protected $_iLanguage = null;
26 
33  protected $_blEmployMultilanguage = true;
34 
38  public function __construct()
39  {
41 
42  //T2008-02-22
43  //lets try to differentiate cache keys for oxI18n and oxBase
44  //in order not to load cached structure for the instances of oxbase classe called on same table
45  if ($this->_sCacheKey) {
46  $this->_sCacheKey .= "_i18n";
47  }
48  }
49 
55  public function setLanguage($iLang = null)
56  {
57  $this->_iLanguage = (int) $iLang;
58  // reset
59  $this->_sViewTable = false;
60  }
61 
67  public function getLanguage()
68  {
69  if ($this->_iLanguage === null) {
70  $this->_iLanguage = oxRegistry::getLang()->getBaseLanguage();
71  }
72 
73  return $this->_iLanguage;
74  }
75 
82  public function setEnableMultilang($blEmployMultilanguage)
83  {
84  if ($this->_blEmployMultilanguage != $blEmployMultilanguage) {
85  $this->_blEmployMultilanguage = $blEmployMultilanguage;
86  if (!$blEmployMultilanguage) {
87  //#63T
88  $this->modifyCacheKey("_nonml");
89  }
90  // reset
91  $this->_sViewTable = false;
92  if (count($this->_aFieldNames) > 1) {
93  $this->_initDataStructure();
94  }
95  }
96  }
97 
106  public function isMultilingualField($sFieldName)
107  {
108  $sFieldName = strtolower($sFieldName);
109  if (isset($this->_aFieldNames[$sFieldName])) {
110  return (bool) $this->_aFieldNames[$sFieldName];
111  }
112 
113  //not inited field yet
114  //and note that this is should be called only in first call after tmp dir is empty
115  startProfile('!__CACHABLE2__!');
116  $blIsMultilang = (bool) $this->_getFieldStatus($sFieldName);
117  stopProfile('!__CACHABLE2__!');
118 
119  return (bool) $blIsMultilang;
120  }
121 
128  public function isMultilang()
129  {
130  return true;
131  }
132 
141  public function loadInLang($iLanguage, $sOxid)
142  {
143  // set new lang to this object
144  $this->setLanguage($iLanguage);
145  // reset
146  $this->_sViewTable = false;
147 
148  return $this->load($sOxid);
149  }
150 
157  public function modifyCacheKey($sCacheKey, $blOverride = false)
158  {
159  if ($blOverride) {
160  $this->_sCacheKey = $sCacheKey . "|i18n";
161  } else {
162  $this->_sCacheKey .= $sCacheKey;
163  }
164 
165  if (!$sCacheKey) {
166  $this->_sCacheKey = null;
167  }
168  }
169 
176  public function getAvailableInLangs()
177  {
178  $aLanguages = oxRegistry::getLang()->getLanguageNames();
179 
180  $aObjFields = $this->_getTableFields(
181  getViewName($this->_sCoreTable, -1, -1),
182  true
183  );
184  $aMultiLangFields = array();
185 
186  //selecting all object multilang fields
187  foreach ($aObjFields as $sKey => $sValue) {
188 
189  //skipping oxactive field
190  if (preg_match('/^oxactive(_(\d{1,2}))?$/', $sKey)) {
191  continue;
192  }
193 
194  $iFieldLang = $this->_getFieldLang($sKey);
195 
196  //checking, if field is multilanguage
197  if ($this->isMultilingualField($sKey) || $iFieldLang > 0) {
198  $sNewKey = preg_replace('/_(\d{1,2})$/', '', $sKey);
199  $aMultiLangFields[$sNewKey][] = (int) $iFieldLang;
200  }
201  }
202 
203  // if no multilanguage fields, return default languages array
204  if (count($aMultiLangFields) < 1) {
205  return $aLanguages;
206  }
207 
208  // select from non-multilanguage core view (all ml tables joined to one)
210  $query = "select * from " . getViewName($this->_sCoreTable, -1, -1) . " where oxid = " . $oDb->quote($this->getId());
211  $rs = $oDb->getAll($query);
212 
213  $aNotInLang = $aLanguages;
214 
215  // checks if object field data is not empty in all available languages
216  // and formats not available in languages array
217  if (is_array($rs) && count($rs[0])) {
218  foreach ($aMultiLangFields as $sFieldId => $aMultiLangIds) {
219 
220  foreach ($aMultiLangIds as $sMultiLangId) {
221  $sFieldName = ($sMultiLangId == 0) ? $sFieldId : $sFieldId . '_' . $sMultiLangId;
222  if ($rs['0'][strtoupper($sFieldName)]) {
223  unset($aNotInLang[$sMultiLangId]);
224  continue;
225  }
226  }
227  }
228  }
229 
230  $aIsInLang = array_diff($aLanguages, $aNotInLang);
231 
232  return $aIsInLang;
233  }
234 
243  protected function _getFieldStatus($sFieldName)
244  {
245  $aAllField = $this->_getAllFields(true);
246  if (isset($aAllField[strtolower($sFieldName) . "_1"])) {
247  return 1;
248  }
249 
250  return 0;
251  }
252 
264  protected function _getNonCachedFieldNames($blForceFullStructure = false)
265  {
266  //Tomas
267  //TODO: this place could be optimized. please check what we can do.
268  $aFields = parent::_getNonCachedFieldNames($blForceFullStructure);
269 
270  if (!$this->_blEmployMultilanguage) {
271  return $aFields;
272  }
273 
274  //lets do some pointer manipulation
275  if ($aFields) {
276  //non admin fields
277  $aWorkingFields = & $aFields;
278  } else {
279  //most likely admin fields so we remove another language
280  $aWorkingFields = & $this->_aFieldNames;
281  }
282 
283  //we have an array of fields, lets remove multilanguage fields
284  foreach ($aWorkingFields as $sName => $sVal) {
285  if ($this->_getFieldLang($sName)) {
286  unset($aWorkingFields[$sName]);
287  } else {
288  $aWorkingFields[$sName] = $this->_getFieldStatus($sName);
289  }
290  }
291 
292  return $aWorkingFields;
293  }
294 
302  protected function _getFieldLang($sFieldName)
303  {
304  if (false === strpos($sFieldName, '_')) {
305  return 0;
306  }
307  if (preg_match('/_(\d{1,2})$/', $sFieldName, $aRegs)) {
308  return $aRegs[1];
309  } else {
310  return 0;
311  }
312  }
313 
321  public function getUpdateSqlFieldName($sField)
322  {
323  $iLang = $this->getLanguage();
324  if ($iLang && $this->_blEmployMultilanguage && $this->isMultilingualField($sField)) {
325  $sField .= "_" . $iLang;
326  }
327 
328  return $sField;
329  }
330 
339  protected function _setUpdateSeoOnFieldChange($sField)
340  {
342  }
343 
344 
353  protected function _getUpdateFieldsForTable($sTable, $blUseSkipSaveFields = true)
354  {
355  $sCoreTable = $this->getCoreTableName();
356 
357  $blSkipMultilingual = false;
358  $blSkipCoreFields = false;
359 
360  if ($sTable != $sCoreTable) {
361  $blSkipCoreFields = true;
362  }
363  if ($this->_blEmployMultilanguage) {
364  if ($sTable != getLangTableName($sCoreTable, $this->getLanguage())) {
365  $blSkipMultilingual = true;
366  }
367  }
368 
369  $sSql = '';
370  $blSep = false;
371  foreach (array_keys($this->_aFieldNames) as $sKey) {
372  $sKeyLowercase = strtolower($sKey);
373  if ($sKeyLowercase != 'oxid') {
374  if ($this->_blEmployMultilanguage) {
375  if ($blSkipMultilingual && $this->isMultilingualField($sKey)) {
376  continue;
377  }
378  if ($blSkipCoreFields && !$this->isMultilingualField($sKey)) {
379  continue;
380  }
381  } else {
382  // need to explicitly check field language
383  $iFieldLang = $this->_getFieldLang($sKey);
384  if ($iFieldLang) {
385  if ($sTable != getLangTableName($sCoreTable, $iFieldLang)) {
386  continue;
387  }
388  } elseif ($blSkipCoreFields) {
389  continue;
390  }
391  }
392  }
393 
394  $sLongName = $this->_getFieldLongName($sKey);
395  $oField = $this->$sLongName;
396 
397  if (!$blUseSkipSaveFields || ($blUseSkipSaveFields && !in_array($sKeyLowercase, $this->_aSkipSaveFields))) {
398  $sKey = $this->getUpdateSqlFieldName($sKey);
399  $sSql .= (($blSep) ? ',' : '') . $sKey . " = " . $this->_getUpdateFieldValue($sKey, $oField);
400  $blSep = true;
401  }
402  }
403 
404  return $sSql;
405  }
406 
416  protected function _getUpdateFields($blUseSkipSaveFields = true)
417  {
418  return $this->_getUpdateFieldsForTable($this->getCoreTableName(), $blUseSkipSaveFields);
419  }
420 
431  protected function _update()
432  {
433  $blRet = parent::_update();
434 
435  if ($blRet) {
436  //also update multilang table if it is separate
437  $aUpdateTables = array();
438  if ($this->_blEmployMultilanguage) {
439  $sCoreTable = $this->getCoreTableName();
440  $sLangTable = getLangTableName($sCoreTable, $this->getLanguage());
441  if ($sCoreTable != $sLangTable) {
442  $aUpdateTables[] = $sLangTable;
443  }
444  } else {
445  $aUpdateTables = $this->_getLanguageSetTables();
446  }
447  foreach ($aUpdateTables as $sLangTable) {
448  $sUpdate = "insert into $sLangTable set " . $this->_getUpdateFieldsForTable($sLangTable, $this->getUseSkipSaveFields()) .
449  " on duplicate key update " . $this->_getUpdateFieldsForTable($sLangTable);
450 
451  $blRet = (bool) oxDb::getDb()->execute($sUpdate);
452  }
453  }
454 
455  // currently only multilanguage objects are SEO
456  // if current object is managed by SEO and SEO is ON
457  if ($blRet && $this->_blIsSeoObject && $this->getUpdateSeo() && $this->isAdmin()) {
458  // marks all object db entries as expired
459  oxRegistry::get("oxSeoEncoder")->markAsExpired($this->getId(), null, 1, $this->getLanguage());
460  }
461 
462  return $blRet;
463  }
464 
472  protected function _getLanguageSetTables($sCoreTableName = null)
473  {
474  $sCoreTableName = $sCoreTableName ? $sCoreTableName : $this->getCoreTableName();
475 
476  return oxNew('oxDbMetaDataHandler')->getAllMultiTables($sCoreTableName);
477  }
478 
486  protected function _insert()
487  {
488  $blRet = parent::_insert();
489 
490  if ($blRet) {
491  //also insert to multilang tables if it is separate
492  foreach ($this->_getLanguageSetTables() as $sTable) {
493  $sSq = "insert into $sTable set " . $this->_getUpdateFieldsForTable($sTable, $this->getUseSkipSaveFields());
494  $blRet = $blRet && (bool) oxDb::getDb()->execute($sSq);
495  }
496  }
497 
498  return $blRet;
499  }
500 
509  protected function _getObjectViewName($sTable, $sShopID = null)
510  {
511  if (!$this->_blEmployMultilanguage) {
512  return parent::_getObjectViewName($sTable, $sShopID);
513  }
514 
515  return getViewName($sTable, $this->getLanguage(), $sShopID);
516  }
517 
529  protected function _getAllFields($blReturnSimple = false)
530  {
531  if ($this->_blEmployMultilanguage) {
532  return parent::_getAllFields($blReturnSimple);
533  } else {
534  $sViewName = $this->getViewName();
535  if (!$sViewName) {
536  return array();
537  }
538 
539  return $this->_getTableFields($sViewName, $blReturnSimple);
540  }
541  }
542 
553  protected function _addField($sName, $sStatus, $sType = null, $sLength = null)
554  {
555  if ($this->_blEmployMultilanguage && $this->_getFieldLang($sName)) {
556  return;
557  }
558 
559  return parent::_addField($sName, $sStatus, $sType, $sLength);
560  }
561 
573  protected function _canFieldBeNull($sFieldName)
574  {
575  $sFieldName = preg_replace('/_\d{1,2}$/', '', $sFieldName);
576 
577  return parent::_canFieldBeNull($sFieldName);
578  }
579 
587  public function delete($sOXID = null)
588  {
589  $blDeleted = parent::delete($sOXID);
590  if ($blDeleted) {
591  $oDB = oxDb::getDb();
592  $sOXID = $oDB->quote($sOXID);
593 
594  //delete the record
595  foreach ($this->_getLanguageSetTables() as $sSetTbl) {
596  $oDB->execute("delete from {$sSetTbl} where oxid = {$sOXID}");
597  }
598  }
599 
600  return $blDeleted;
601  }
602 }