oxi18n.php

Go to the documentation of this file.
00001 <?php
00002 
00010 class oxI18n extends oxBase
00011 {
00012 
00018     protected $_sClassName = 'oxI18n';
00019 
00025     protected $_iLanguage = null;
00026 
00033     protected $_blEmployMultilanguage = true;
00034 
00038     public function __construct()
00039     {
00040         parent::__construct();
00041 
00042         //T2008-02-22
00043         //lets try to differentiate cache keys for oxI18n and oxBase
00044         //in order not to load cached structure for the instances of oxbase classe called on same table
00045         if ($this->_sCacheKey) {
00046             $this->_sCacheKey .= "_i18n";
00047         }
00048     }
00049 
00055     public function setLanguage($iLang = null)
00056     {
00057         $this->_iLanguage = (int) $iLang;
00058         // reset
00059         $this->_sViewTable = false;
00060     }
00061 
00067     public function getLanguage()
00068     {
00069         if ($this->_iLanguage === null) {
00070             $this->_iLanguage = oxRegistry::getLang()->getBaseLanguage();
00071         }
00072 
00073         return $this->_iLanguage;
00074     }
00075 
00082     public function setEnableMultilang($blEmployMultilanguage)
00083     {
00084         if ($this->_blEmployMultilanguage != $blEmployMultilanguage) {
00085             $this->_blEmployMultilanguage = $blEmployMultilanguage;
00086             if (!$blEmployMultilanguage) {
00087                 //#63T
00088                 $this->modifyCacheKey("_nonml");
00089             }
00090             // reset
00091             $this->_sViewTable = false;
00092             if (count($this->_aFieldNames) > 1) {
00093                 $this->_initDataStructure();
00094             }
00095         }
00096     }
00097 
00106     public function isMultilingualField($sFieldName)
00107     {
00108         $sFieldName = strtolower($sFieldName);
00109         if (isset($this->_aFieldNames[$sFieldName])) {
00110             return (bool) $this->_aFieldNames[$sFieldName];
00111         }
00112 
00113         //not inited field yet
00114         //and note that this is should be called only in first call after tmp dir is empty
00115         startProfile('!__CACHABLE2__!');
00116         $blIsMultilang = (bool) $this->_getFieldStatus($sFieldName);
00117         stopProfile('!__CACHABLE2__!');
00118 
00119         return (bool) $blIsMultilang;
00120     }
00121 
00128     public function isMultilang()
00129     {
00130         return true;
00131     }
00132 
00141     public function loadInLang($iLanguage, $sOxid)
00142     {
00143         // set new lang to this object
00144         $this->setLanguage($iLanguage);
00145         // reset
00146         $this->_sViewTable = false;
00147 
00148         return $this->load($sOxid);
00149     }
00150 
00157     public function modifyCacheKey($sCacheKey, $blOverride = false)
00158     {
00159         if ($blOverride) {
00160             $this->_sCacheKey = $sCacheKey . "|i18n";
00161         } else {
00162             $this->_sCacheKey .= $sCacheKey;
00163         }
00164 
00165         if (!$sCacheKey) {
00166             $this->_sCacheKey = null;
00167         }
00168     }
00169 
00176     public function getAvailableInLangs()
00177     {
00178         $aLanguages = oxRegistry::getLang()->getLanguageNames();
00179 
00180         $aObjFields = $this->_getTableFields(
00181             getViewName($this->_sCoreTable, -1, -1),
00182             true
00183         );
00184         $aMultiLangFields = array();
00185 
00186         //selecting all object multilang fields
00187         foreach ($aObjFields as $sKey => $sValue) {
00188 
00189             //skipping oxactive field
00190             if (preg_match('/^oxactive(_(\d{1,2}))?$/', $sKey)) {
00191                 continue;
00192             }
00193 
00194             $iFieldLang = $this->_getFieldLang($sKey);
00195 
00196             //checking, if field is multilanguage
00197             if ($this->isMultilingualField($sKey) || $iFieldLang > 0) {
00198                 $sNewKey = preg_replace('/_(\d{1,2})$/', '', $sKey);
00199                 $aMultiLangFields[$sNewKey][] = (int) $iFieldLang;
00200             }
00201         }
00202 
00203         // if no multilanguage fields, return default languages array
00204         if (count($aMultiLangFields) < 1) {
00205             return $aLanguages;
00206         }
00207 
00208         // select from non-multilanguage core view (all ml tables joined to one)
00209         $oDb = oxDb::getDb(oxDb::FETCH_MODE_ASSOC);
00210         $query = "select * from " . getViewName($this->_sCoreTable, -1, -1) . " where oxid = " . $oDb->quote($this->getId());
00211         $rs = $oDb->getAll($query);
00212 
00213         $aNotInLang = $aLanguages;
00214 
00215         // checks if object field data is not empty in all available languages
00216         // and formats not available in languages array
00217         if (is_array($rs) && count($rs[0])) {
00218             foreach ($aMultiLangFields as $sFieldId => $aMultiLangIds) {
00219 
00220                 foreach ($aMultiLangIds as $sMultiLangId) {
00221                     $sFieldName = ($sMultiLangId == 0) ? $sFieldId : $sFieldId . '_' . $sMultiLangId;
00222                     if ($rs['0'][strtoupper($sFieldName)]) {
00223                         unset($aNotInLang[$sMultiLangId]);
00224                         continue;
00225                     }
00226                 }
00227             }
00228         }
00229 
00230         $aIsInLang = array_diff($aLanguages, $aNotInLang);
00231 
00232         return $aIsInLang;
00233     }
00234 
00243     protected function _getFieldStatus($sFieldName)
00244     {
00245         $aAllField = $this->_getAllFields(true);
00246         if (isset($aAllField[strtolower($sFieldName) . "_1"])) {
00247             return 1;
00248         }
00249 
00250         return 0;
00251     }
00252 
00264     protected function _getNonCachedFieldNames($blForceFullStructure = false)
00265     {
00266         //Tomas
00267         //TODO: this place could be optimized. please check what we can do.
00268         $aFields = parent::_getNonCachedFieldNames($blForceFullStructure);
00269 
00270         if (!$this->_blEmployMultilanguage) {
00271             return $aFields;
00272         }
00273 
00274         //lets do some pointer manipulation
00275         if ($aFields) {
00276             //non admin fields
00277             $aWorkingFields = & $aFields;
00278         } else {
00279             //most likely admin fields so we remove another language
00280             $aWorkingFields = & $this->_aFieldNames;
00281         }
00282 
00283         //we have an array of fields, lets remove multilanguage fields
00284         foreach ($aWorkingFields as $sName => $sVal) {
00285             if ($this->_getFieldLang($sName)) {
00286                 unset($aWorkingFields[$sName]);
00287             } else {
00288                 $aWorkingFields[$sName] = $this->_getFieldStatus($sName);
00289             }
00290         }
00291 
00292         return $aWorkingFields;
00293     }
00294 
00302     protected function _getFieldLang($sFieldName)
00303     {
00304         if (false === strpos($sFieldName, '_')) {
00305             return 0;
00306         }
00307         if (preg_match('/_(\d{1,2})$/', $sFieldName, $aRegs)) {
00308             return $aRegs[1];
00309         } else {
00310             return 0;
00311         }
00312     }
00313 
00321     public function getUpdateSqlFieldName($sField)
00322     {
00323         $iLang = $this->getLanguage();
00324         if ($iLang && $this->_blEmployMultilanguage && $this->isMultilingualField($sField)) {
00325             $sField .= "_" . $iLang;
00326         }
00327 
00328         return $sField;
00329     }
00330 
00339     protected function _setUpdateSeoOnFieldChange($sField)
00340     {
00341         parent::_setUpdateSeoOnFieldChange($this->getUpdateSqlFieldName($sField));
00342     }
00343 
00344 
00353     protected function _getUpdateFieldsForTable($sTable, $blUseSkipSaveFields = true)
00354     {
00355         $sCoreTable = $this->getCoreTableName();
00356 
00357         $blSkipMultilingual = false;
00358         $blSkipCoreFields = false;
00359 
00360         if ($sTable != $sCoreTable) {
00361             $blSkipCoreFields = true;
00362         }
00363         if ($this->_blEmployMultilanguage) {
00364             if ($sTable != getLangTableName($sCoreTable, $this->getLanguage())) {
00365                 $blSkipMultilingual = true;
00366             }
00367         }
00368 
00369         $sSql = '';
00370         $blSep = false;
00371         foreach (array_keys($this->_aFieldNames) as $sKey) {
00372             $sKeyLowercase = strtolower($sKey);
00373             if ($sKeyLowercase != 'oxid') {
00374                 if ($this->_blEmployMultilanguage) {
00375                     if ($blSkipMultilingual && $this->isMultilingualField($sKey)) {
00376                         continue;
00377                     }
00378                     if ($blSkipCoreFields && !$this->isMultilingualField($sKey)) {
00379                         continue;
00380                     }
00381                 } else {
00382                     // need to explicitly check field language
00383                     $iFieldLang = $this->_getFieldLang($sKey);
00384                     if ($iFieldLang) {
00385                         if ($sTable != getLangTableName($sCoreTable, $iFieldLang)) {
00386                             continue;
00387                         }
00388                     } elseif ($blSkipCoreFields) {
00389                         continue;
00390                     }
00391                 }
00392             }
00393 
00394             $sLongName = $this->_getFieldLongName($sKey);
00395             $oField = $this->$sLongName;
00396 
00397             if (!$blUseSkipSaveFields || ($blUseSkipSaveFields && !in_array($sKeyLowercase, $this->_aSkipSaveFields))) {
00398                 $sKey = $this->getUpdateSqlFieldName($sKey);
00399                 $sSql .= (($blSep) ? ',' : '') . $sKey . " = " . $this->_getUpdateFieldValue($sKey, $oField);
00400                 $blSep = true;
00401             }
00402         }
00403 
00404         return $sSql;
00405     }
00406 
00416     protected function _getUpdateFields($blUseSkipSaveFields = true)
00417     {
00418         return $this->_getUpdateFieldsForTable($this->getCoreTableName(), $blUseSkipSaveFields);
00419     }
00420 
00431     protected function _update()
00432     {
00433         $blRet = parent::_update();
00434 
00435         if ($blRet) {
00436             //also update multilang table if it is separate
00437             $aUpdateTables = array();
00438             if ($this->_blEmployMultilanguage) {
00439                 $sCoreTable = $this->getCoreTableName();
00440                 $sLangTable = getLangTableName($sCoreTable, $this->getLanguage());
00441                 if ($sCoreTable != $sLangTable) {
00442                     $aUpdateTables[] = $sLangTable;
00443                 }
00444             } else {
00445                 $aUpdateTables = $this->_getLanguageSetTables();
00446             }
00447             foreach ($aUpdateTables as $sLangTable) {
00448                 $sUpdate = "insert into $sLangTable set " . $this->_getUpdateFieldsForTable($sLangTable, $this->getUseSkipSaveFields()) .
00449                            " on duplicate key update " . $this->_getUpdateFieldsForTable($sLangTable);
00450 
00451                 $blRet = (bool) oxDb::getDb()->execute($sUpdate);
00452             }
00453         }
00454 
00455         // currently only multilanguage objects are SEO
00456         // if current object is managed by SEO and SEO is ON
00457         if ($blRet && $this->_blIsSeoObject && $this->getUpdateSeo() && $this->isAdmin()) {
00458             // marks all object db entries as expired
00459             oxRegistry::get("oxSeoEncoder")->markAsExpired($this->getId(), null, 1, $this->getLanguage());
00460         }
00461 
00462         return $blRet;
00463     }
00464 
00472     protected function _getLanguageSetTables($sCoreTableName = null)
00473     {
00474         $sCoreTableName = $sCoreTableName ? $sCoreTableName : $this->getCoreTableName();
00475 
00476         return oxNew('oxDbMetaDataHandler')->getAllMultiTables($sCoreTableName);
00477     }
00478 
00486     protected function _insert()
00487     {
00488         $blRet = parent::_insert();
00489 
00490         if ($blRet) {
00491             //also insert to multilang tables if it is separate
00492             foreach ($this->_getLanguageSetTables() as $sTable) {
00493                 $sSq = "insert into $sTable set " . $this->_getUpdateFieldsForTable($sTable, $this->getUseSkipSaveFields());
00494                 $blRet = $blRet && (bool) oxDb::getDb()->execute($sSq);
00495             }
00496         }
00497 
00498         return $blRet;
00499     }
00500 
00509     protected function _getObjectViewName($sTable, $sShopID = null)
00510     {
00511         if (!$this->_blEmployMultilanguage) {
00512             return parent::_getObjectViewName($sTable, $sShopID);
00513         }
00514 
00515         return getViewName($sTable, $this->getLanguage(), $sShopID);
00516     }
00517 
00529     protected function _getAllFields($blReturnSimple = false)
00530     {
00531         if ($this->_blEmployMultilanguage) {
00532             return parent::_getAllFields($blReturnSimple);
00533         } else {
00534             $sViewName = $this->getViewName();
00535             if (!$sViewName) {
00536                 return array();
00537             }
00538 
00539             return $this->_getTableFields($sViewName, $blReturnSimple);
00540         }
00541     }
00542 
00553     protected function _addField($sName, $sStatus, $sType = null, $sLength = null)
00554     {
00555         if ($this->_blEmployMultilanguage && $this->_getFieldLang($sName)) {
00556             return;
00557         }
00558 
00559         return parent::_addField($sName, $sStatus, $sType, $sLength);
00560     }
00561 
00573     protected function _canFieldBeNull($sFieldName)
00574     {
00575         $sFieldName = preg_replace('/_\d{1,2}$/', '', $sFieldName);
00576 
00577         return parent::_canFieldBeNull($sFieldName);
00578     }
00579 
00587     public function delete($sOXID = null)
00588     {
00589         $blDeleted = parent::delete($sOXID);
00590         if ($blDeleted) {
00591             $oDB = oxDb::getDb();
00592             $sOXID = $oDB->quote($sOXID);
00593 
00594             //delete the record
00595             foreach ($this->_getLanguageSetTables() as $sSetTbl) {
00596                 $oDB->execute("delete from {$sSetTbl} where oxid = {$sOXID}");
00597             }
00598         }
00599 
00600         return $blDeleted;
00601     }
00602 }