OXID eShop CE  4.8.12
 All Classes 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 
57  public function setLanguage( $iLang = null )
58  {
59  $this->_iLanguage = (int) $iLang;
60  // reset
61  $this->_sViewTable = false;
62  }
63 
69  public function getLanguage()
70  {
71  if ( $this->_iLanguage === null ) {
72  $this->_iLanguage = oxRegistry::getLang()->getBaseLanguage();
73  }
74  return $this->_iLanguage;
75  }
76 
85  public function setEnableMultilang( $blEmployMultilanguage )
86  {
87  if ($this->_blEmployMultilanguage != $blEmployMultilanguage) {
88  $this->_blEmployMultilanguage = $blEmployMultilanguage;
89  if (!$blEmployMultilanguage) {
90  //#63T
91  $this->modifyCacheKey("_nonml");
92  }
93  // reset
94  $this->_sViewTable = false;
95  if (count($this->_aFieldNames) > 1) {
96  $this->_initDataStructure();
97  }
98  }
99  }
100 
109  public function isMultilingualField( $sFieldName )
110  {
111  $sFieldName = strtolower( $sFieldName );
112  if ( isset( $this->_aFieldNames[$sFieldName] ) ) {
113  return (bool) $this->_aFieldNames[$sFieldName];
114  }
115 
116  //not inited field yet
117  //and note that this is should be called only in first call after tmp dir is empty
118  startProfile('!__CACHABLE2__!');
119  $blIsMultilang = (bool) $this->_getFieldStatus( $sFieldName );
120  stopProfile('!__CACHABLE2__!');
121  return (bool) $blIsMultilang;
122  }
123 
130  public function isMultilang()
131  {
132  return true;
133  }
134 
143  public function loadInLang( $iLanguage, $sOxid)
144  {
145  // set new lang to this object
146  $this->setLanguage($iLanguage);
147  // reset
148  $this->_sViewTable = false;
149  return $this->load( $sOxid );
150  }
151 
160  public function modifyCacheKey( $sCacheKey, $blOverride = false )
161  {
162  if ($blOverride) {
163  $this->_sCacheKey = $sCacheKey."|i18n";
164  } else {
165  $this->_sCacheKey .= $sCacheKey;
166  }
167 
168  if (!$sCacheKey) {
169  $this->_sCacheKey = null;
170  }
171  }
172 
179  public function getAvailableInLangs()
180  {
181  $aLanguages = oxRegistry::getLang()->getLanguageNames();
182 
183  $aObjFields = $this->_getTableFields(
184  getViewName($this->_sCoreTable, -1, -1),
185  true
186  );
187  $aMultiLangFields = array();
188 
189  //selecting all object multilang fields
190  foreach ($aObjFields as $sKey => $sValue ) {
191 
192  //skipping oxactive field
193  if ( preg_match('/^oxactive(_(\d{1,2}))?$/', $sKey) ) {
194  continue;
195  }
196 
197  $iFieldLang = $this->_getFieldLang( $sKey );
198 
199  //checking, if field is multilanguage
200  if ( $this->isMultilingualField($sKey) || $iFieldLang > 0 ) {
201  $sNewKey = preg_replace('/_(\d{1,2})$/', '', $sKey);
202  $aMultiLangFields[$sNewKey][] = (int) $iFieldLang;
203  }
204  }
205 
206  // if no multilanguage fields, return default languages array
207  if ( count($aMultiLangFields) < 1 ) {
208  return $aLanguages;
209  }
210 
211  // select from non-multilanguage core view (all ml tables joined to one)
213  $query = "select * from ".getViewName($this->_sCoreTable, -1, -1)." where oxid = " . $oDb->quote( $this->getId() );
214  $rs = $oDb->getAll($query);
215 
216  $aNotInLang = $aLanguages;
217 
218  // checks if object field data is not empty in all available languages
219  // and formats not available in languages array
220  if ( is_array($rs) && count($rs[0]) ) {
221  foreach ( $aMultiLangFields as $sFieldId => $aMultiLangIds ) {
222 
223  foreach ( $aMultiLangIds as $sMultiLangId ) {
224  $sFieldName = ( $sMultiLangId == 0 ) ? $sFieldId : $sFieldId.'_'.$sMultiLangId;
225  if ( $rs['0'][strtoupper($sFieldName)] ) {
226  unset( $aNotInLang[$sMultiLangId] );
227  continue;
228  }
229  }
230  }
231  }
232 
233  $aIsInLang = array_diff( $aLanguages, $aNotInLang );
234 
235  return $aIsInLang;
236  }
237 
246  protected function _getFieldStatus( $sFieldName )
247  {
248  $aAllField = $this->_getAllFields( true );
249  if ( isset( $aAllField[strtolower( $sFieldName ) . "_1"] ) ) {
250  return 1;
251  }
252  return 0;
253  }
254 
266  protected function _getNonCachedFieldNames($blForceFullStructure = false)
267  {
268  //Tomas
269  //TODO: this place could be optimized. please check what we can do.
270  $aFields = parent::_getNonCachedFieldNames($blForceFullStructure);
271 
272  if (!$this->_blEmployMultilanguage) {
273  return $aFields;
274  }
275 
276  //lets do some pointer manipulation
277  if ($aFields) {
278  //non admin fields
279  $aWorkingFields = &$aFields;
280  } else {
281  //most likely admin fields so we remove another language
282  $aWorkingFields = &$this->_aFieldNames;
283  }
284 
285  //we have an array of fields, lets remove multilanguage fields
286  foreach ($aWorkingFields as $sName => $sVal) {
287  if ($this->_getFieldLang($sName)) {
288  unset($aWorkingFields[$sName]);
289  } else {
290  $aWorkingFields[$sName] = $this->_getFieldStatus($sName);
291  }
292  }
293 
294  return $aWorkingFields;
295  }
296 
304  protected function _getFieldLang($sFieldName)
305  {
306  if ( false === strpos($sFieldName, '_')) {
307  return 0;
308  }
309  if (preg_match('/_(\d{1,2})$/', $sFieldName, $aRegs)) {
310  return $aRegs[1];
311  } else {
312  return 0;
313  }
314  }
315 
323  public function getUpdateSqlFieldName($sField)
324  {
325  $iLang = $this->getLanguage();
326  if ($iLang && $this->_blEmployMultilanguage && $this->isMultilingualField($sField)) {
327  $sField .= "_" . $iLang;
328  }
329 
330  return $sField;
331  }
332 
341  protected function _setUpdateSeoOnFieldChange($sField)
342  {
344  }
345 
346 
355  protected function _getUpdateFieldsForTable( $sTable, $blUseSkipSaveFields = true )
356  {
357  $sCoreTable = $this->getCoreTableName();
358 
359  $blSkipMultilingual = false;
360  $blSkipCoreFields = false;
361 
362  if ($sTable != $sCoreTable ) {
363  $blSkipCoreFields = true;
364  }
365  if ($this->_blEmployMultilanguage) {
366  if ( $sTable != getLangTableName($sCoreTable, $this->getLanguage() ) ) {
367  $blSkipMultilingual = true;
368  }
369  }
370 
371  $sSql = '';
372  $blSep = false;
373  foreach (array_keys($this->_aFieldNames) as $sKey) {
374  $sKeyLowercase = strtolower($sKey);
375  if ($sKeyLowercase != 'oxid') {
376  if ($this->_blEmployMultilanguage) {
377  if ($blSkipMultilingual && $this->isMultilingualField($sKey)) {
378  continue;
379  }
380  if ($blSkipCoreFields && !$this->isMultilingualField($sKey)) {
381  continue;
382  }
383  } else {
384  // need to explicitly check field language
385  $iFieldLang = $this->_getFieldLang($sKey);
386  if ($iFieldLang) {
387  if ($sTable != getLangTableName($sCoreTable, $iFieldLang)) {
388  continue;
389  }
390  } elseif ($blSkipCoreFields) {
391  continue;
392  }
393  }
394  }
395 
396  $sLongName = $this->_getFieldLongName($sKey);
397  $oField = $this->$sLongName;
398 
399  if ( !$blUseSkipSaveFields || ($blUseSkipSaveFields && !in_array($sKeyLowercase, $this->_aSkipSaveFields)) ) {
400  $sKey = $this->getUpdateSqlFieldName($sKey);
401  $sSql .= (( $blSep) ? ',':'' ).$sKey." = ".$this->_getUpdateFieldValue($sKey, $oField);
402  $blSep = true;
403  }
404  }
405 
406  return $sSql;
407  }
408 
418  protected function _getUpdateFields( $blUseSkipSaveFields = true )
419  {
420  return $this->_getUpdateFieldsForTable( $this->getCoreTableName(), $blUseSkipSaveFields );
421  }
422 
433  protected function _update()
434  {
435  $blRet = parent::_update();
436 
437  if ($blRet) {
438  //also update multilang table if it is separate
439  $aUpdateTables = array();
440  if ($this->_blEmployMultilanguage) {
441  $sCoreTable = $this->getCoreTableName();
442  $sLangTable = getLangTableName($sCoreTable, $this->getLanguage() );
443  if ($sCoreTable != $sLangTable) {
444  $aUpdateTables[] = $sLangTable;
445  }
446  } else {
447  $aUpdateTables = $this->_getLanguageSetTables();
448  }
449  foreach ($aUpdateTables as $sLangTable) {
450  $sUpdate= "insert into $sLangTable set ".$this->_getUpdateFieldsForTable( $sLangTable, $this->getUseSkipSaveFields() ) .
451  " on duplicate key update ".$this->_getUpdateFieldsForTable( $sLangTable );
452 
453  $blRet = (bool) oxDb::getDb()->execute( $sUpdate);
454  }
455  }
456 
457  // currently only multilanguage objects are SEO
458  // if current object is managed by SEO and SEO is ON
459  if ( $blRet && $this->_blIsSeoObject && $this->getUpdateSeo() && $this->isAdmin() ) {
460  // marks all object db entries as expired
461  oxRegistry::get("oxSeoEncoder")->markAsExpired( $this->getId(), null, 1, $this->getLanguage() );
462  }
463 
464  return $blRet;
465  }
466 
474  protected function _getLanguageSetTables( $sCoreTableName = null )
475  {
476  $sCoreTableName = $sCoreTableName ? $sCoreTableName : $this->getCoreTableName();
477  return oxNew('oxDbMetaDataHandler')->getAllMultiTables( $sCoreTableName );
478  }
479 
487  protected function _insert()
488  {
489  $blRet = parent::_insert();
490 
491  if ($blRet) {
492  //also insert to multilang tables if it is separate
493  foreach ($this->_getLanguageSetTables() as $sTable) {
494  $sSq = "insert into $sTable set ".$this->_getUpdateFieldsForTable( $sTable, $this->getUseSkipSaveFields() );
495  $blRet = $blRet && (bool) oxDb::getDb()->execute( $sSq );
496  }
497  }
498 
499  return $blRet;
500  }
501 
510  protected function _getObjectViewName( $sTable, $sShopID = null)
511  {
512  if (!$this->_blEmployMultilanguage) {
513  return parent::_getObjectViewName($sTable, $sShopID);
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  return $this->_getTableFields( $sViewName, $blReturnSimple );
539  }
540  }
541 
552  protected function _addField($sName, $sStatus, $sType = null, $sLength = null)
553  {
554  if ($this->_blEmployMultilanguage && $this->_getFieldLang($sName)) {
555  return;
556  }
557 
558  return parent::_addField($sName, $sStatus, $sType, $sLength);
559  }
560 
572  protected function _canFieldBeNull( $sFieldName )
573  {
574  $sFieldName = preg_replace( '/_\d{1,2}$/', '', $sFieldName );
575  return parent::_canFieldBeNull( $sFieldName );
576  }
577 
585  public function delete( $sOXID = null )
586  {
587  $blDeleted = parent::delete( $sOXID );
588  if ( $blDeleted ) {
589  $oDB = oxDb::getDb();
590  $sOXID = $oDB->quote( $sOXID );
591 
592  //delete the record
593  foreach ( $this->_getLanguageSetTables() as $sSetTbl ) {
594  $oDB->execute( "delete from {$sSetTbl} where oxid = {$sOXID}" );
595  }
596  }
597  return $blDeleted;
598  }
599 }