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 
00057     public function setLanguage( $iLang = null )
00058     {
00059         $this->_iLanguage = (int) $iLang;
00060         // reset
00061         $this->_sViewTable = false;
00062     }
00063 
00069     public function getLanguage()
00070     {
00071         if ( $this->_iLanguage === null ) {
00072             $this->_iLanguage = oxLang::getInstance()->getBaseLanguage();
00073         }
00074         return $this->_iLanguage;
00075     }
00076 
00085     public function setEnableMultilang( $blEmployMultilanguage )
00086     {
00087         if ($this->_blEmployMultilanguage != $blEmployMultilanguage) {
00088             $this->_blEmployMultilanguage = $blEmployMultilanguage;
00089             if (!$blEmployMultilanguage) {
00090                 //#63T
00091                 $this->modifyCacheKey("_nonml");
00092             }
00093             // reset
00094             $this->_sViewTable = false;
00095             if (count($this->_aFieldNames) > 1) {
00096                 $this->_initDataStructure();
00097             }
00098         }
00099     }
00100 
00109     public function isMultilingualField($sFieldName)
00110     {
00111         if (isset($this->_aFieldNames[$sFieldName])) {
00112             return (bool) $this->_aFieldNames[$sFieldName];
00113         }
00114 
00115         //not inited field yet
00116         //and note that this is should be called only in first call after tmp dir is empty
00117         startProfile('!__CACHABLE2__!');
00118         $blIsMultilang = (bool) $this->_getFieldStatus($sFieldName);
00119         stopProfile('!__CACHABLE2__!');
00120         return (bool) $blIsMultilang;
00121     }
00122 
00129     public function isMultilang()
00130     {
00131         return true;
00132     }
00133 
00142     public function loadInLang( $iLanguage, $sOxid)
00143     {
00144         // set new lang to this object
00145         $this->setLanguage($iLanguage);
00146         // reset
00147         $this->_sViewTable = false;
00148         return $this->load( $sOxid);
00149     }
00150 
00159     public function modifyCacheKey( $sCacheKey, $blOverride = false )
00160     {
00161         if ($blOverride) {
00162             $this->_sCacheKey = $sCacheKey."|i18n";
00163         } else {
00164             $this->_sCacheKey .= $sCacheKey;
00165         }
00166 
00167         if (!$sCacheKey) {
00168             $this->_sCacheKey = null;
00169         }
00170     }
00171 
00178     public function getAvailableInLangs()
00179     {
00180         $aLanguages = oxLang::getInstance()->getLanguageNames();
00181 
00182         $aObjFields = $this->_getTableFields(
00183             getViewName($this->_sCoreTable, -1, -1),
00184             true
00185         );
00186         $aMultiLangFields = array();
00187 
00188         //selecting all object multilang fields
00189         foreach ($aObjFields as $sKey => $sValue ) {
00190 
00191             //skipping oxactive field
00192             if ( preg_match('/^oxactive(_(\d{1,2}))?$/', $sKey) ) {
00193                 continue;
00194             }
00195 
00196             $iFieldLang = $this->_getFieldLang( $sKey );
00197 
00198             //checking, if field is multilanguage
00199             if ( $this->isMultilingualField($sKey) || $iFieldLang >  0 ) {
00200                 $sNewKey = preg_replace('/_(\d{1,2})$/', '', $sKey);
00201                 $aMultiLangFields[$sNewKey][] = (int) $iFieldLang;
00202             }
00203         }
00204 
00205         // if no multilanguage fields, return default languages array
00206         if ( count($aMultiLangFields) < 1 ) {
00207             return $aLanguages;
00208         }
00209 
00210         // select from non-multilanguage core view (all ml tables joined to one)
00211         $query = "select * from ".getViewName($this->_sCoreTable, -1, -1)." where oxid = '" . $this->getId() . "'";
00212         $rs = oxDb::getDb( true )->getAll($query);
00213 
00214         $aNotInLang = $aLanguages;
00215 
00216         // checks if object field data is not empty in all available languages
00217         // and formats not available in languages array
00218         if ( is_array($rs) && count($rs[0]) ) {
00219             foreach ( $aMultiLangFields as $sFieldId => $aMultiLangIds ) {
00220 
00221                 foreach ( $aMultiLangIds as $sMultiLangId ) {
00222                     $sFieldName = ( $sMultiLangId == 0 ) ? $sFieldId : $sFieldId.'_'.$sMultiLangId;
00223                     if ( $rs['0'][strtoupper($sFieldName)] ) {
00224                         unset( $aNotInLang[$sMultiLangId] );
00225                         continue;
00226                     }
00227                 }
00228             }
00229         }
00230 
00231         $aIsInLang = array_diff( $aLanguages, $aNotInLang );
00232 
00233         return $aIsInLang;
00234     }
00235 
00244     protected function _getFieldStatus($sFieldName)
00245     {
00246         $aAllField = $this->_getAllFields(true);
00247         if (isset($aAllField[$sFieldName."_1"])) {
00248             return 1;
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 _getUpdateFieldsForTable( $sTable, $blUseSkipSaveFields = true )
00340     {
00341         $sCoreTable = $this->getCoreTableName();
00342 
00343         $blSkipMultilingual = false;
00344         $blSkipCoreFields = false;
00345 
00346         if ($sTable != $sCoreTable ) {
00347             $blSkipCoreFields = true;
00348         }
00349         if ($this->_blEmployMultilanguage) {
00350             if ( $sTable != getLangTableName($sCoreTable, $this->getLanguage() ) ) {
00351                 $blSkipMultilingual = true;
00352             }
00353         }
00354 
00355         $sSql = '';
00356         $blSep  = false;
00357         foreach (array_keys($this->_aFieldNames) as $sKey) {
00358             $sKeyLowercase = strtolower($sKey);
00359             if ($sKeyLowercase != 'oxid') {
00360                 if ($this->_blEmployMultilanguage) {
00361                     if ($blSkipMultilingual && $this->isMultilingualField($sKey)) {
00362                         continue;
00363                     }
00364                     if ($blSkipCoreFields && !$this->isMultilingualField($sKey)) {
00365                         continue;
00366                     }
00367                 } else {
00368                     // need to explicitly check field language
00369                     $iFieldLang = $this->_getFieldLang($sKey);
00370                     if ($iFieldLang) {
00371                         if ($sTable != getLangTableName($sCoreTable, $iFieldLang)) {
00372                             continue;
00373                         }
00374                     } elseif ($blSkipCoreFields) {
00375                         continue;
00376                     }
00377                 }
00378             }
00379 
00380             $sLongName = $this->_getFieldLongName($sKey);
00381             $oField = $this->$sLongName;
00382 
00383             if ( !$blUseSkipSaveFields || ($blUseSkipSaveFields && !in_array($sKeyLowercase, $this->_aSkipSaveFields)) ) {
00384                 $sKey = $this->getUpdateSqlFieldName($sKey);
00385                 $sSql .= (( $blSep) ? ',':'' ).$sKey." = ".$this->_getUpdateFieldValue($sKey, $oField);
00386                 $blSep = true;
00387             }
00388         }
00389 
00390         return $sSql;
00391     }
00392 
00402     protected function _getUpdateFields( $blUseSkipSaveFields = true )
00403     {
00404         return $this->_getUpdateFieldsForTable( $this->getCoreTableName(), $blUseSkipSaveFields );
00405     }
00406 
00417     protected function _update()
00418     {
00419         $blRet = parent::_update();
00420 
00421         if ($blRet) {
00422             //also update multilang table if it is separate
00423             $aUpdateTables = array();
00424             if ($this->_blEmployMultilanguage) {
00425                 $sCoreTable = $this->getCoreTableName();
00426                 $sLangTable = getLangTableName($sCoreTable, $this->getLanguage() );
00427                 if ($sCoreTable != $sLangTable) {
00428                     $aUpdateTables[] = $sLangTable;
00429                 }
00430             } else {
00431                 $aUpdateTables = $this->_getLanguageSetTables();
00432             }
00433             foreach ($aUpdateTables as $sLangTable) {
00434                 $sUpdate= "insert into $sLangTable set ".$this->_getUpdateFieldsForTable( $sLangTable, false ) . 
00435                           " on duplicate key update ".$this->_getUpdateFieldsForTable( $sLangTable );
00436 
00437                 $blRet = (bool) oxDB::getDb()->execute( $sUpdate);
00438             }
00439         }
00440 
00441         // currently only multilanguage objects are SEO
00442         // if current object is managed by SEO and SEO is ON
00443         if ( $blRet && $this->_blIsSeoObject && $this->isAdmin() ) {
00444             // marks all object db entries as expired
00445             oxSeoEncoder::getInstance()->markAsExpired( $this->getId(), null, 1, $this->getLanguage() );
00446         }
00447 
00448         return $blRet;
00449     }
00450 
00456     protected function _getLanguageSetTables()
00457     {
00458         return oxNew('oxDbMetaDataHandler')->getAllMultiTables($this->getCoreTableName());
00459     }
00460 
00468     protected function _insert()
00469     {
00470         $blRet = parent::_insert();
00471 
00472         if ($blRet) {
00473             //also insert to multilang tables if it is separate
00474             foreach ($this->_getLanguageSetTables() as $sTable) {
00475                 $sSq = "insert into $sTable set ".$this->_getUpdateFieldsForTable( $sTable, false );
00476                 $blRet = $blRet && (bool) oxDB::getDb()->execute( $sSq );
00477             }
00478         }
00479 
00480         return $blRet;
00481     }
00482 
00491     protected function _getObjectViewName( $sTable, $sShopID = null)
00492     {
00493         if (!$this->_blEmployMultilanguage) {
00494             return parent::_getObjectViewName($sTable, $sShopID);
00495         }
00496 
00497         if ( $this->_blForceCoreTableUsage ) {
00498             $sShopID = -1;
00499         }
00500         return getViewName( $sTable, $this->getLanguage(), $sShopID);
00501     }
00502 
00510     public function getViewName($blForceCoreTableUsage = null)
00511     {
00512         if (!$this->_blEmployMultilanguage) {
00513             return parent::getViewName($blForceCoreTableUsage);
00514         }
00515         if (!$this->_sViewTable || ($blForceCoreTableUsage !== null)) {
00516             if ( ($blForceCoreTableUsage !== null)?$blForceCoreTableUsage:$this->_blForceCoreTableUsage ) {
00517                 $iShopId = -1;
00518             } else {
00519                 $iShopId = oxConfig::getInstance()->getShopId();
00520             }
00521             $sViewName = getViewName($this->_sCoreTable, $this->getLanguage(), $iShopId);
00522             if ($blForceCoreTableUsage !== null) {
00523                 return $sViewName;
00524             }
00525             $this->_sViewTable = $sViewName;
00526         }
00527         return $this->_sViewTable;
00528     }
00529 
00541     protected function _getAllFields($blReturnSimple = false)
00542     {
00543         if ($this->_blEmployMultilanguage) {
00544             return parent::_getAllFields($blReturnSimple);
00545         } else {
00546             $sViewName = $this->getViewName();
00547             if (!$sViewName) {
00548                 return array();
00549             }
00550             return $this->_getTableFields($sViewName, $blReturnSimple);
00551         }
00552     }
00553 
00564     protected function _addField($sName, $sStatus, $sType = null, $sLength = null)
00565     {
00566         if ($this->_blEmployMultilanguage && $this->_getFieldLang($sName)) {
00567             return;
00568         }
00569 
00570         return parent::_addField($sName, $sStatus, $sType, $sLength);
00571     }
00572 
00584     protected function _canFieldBeNull($sFieldName)
00585     {
00586         return parent::_canFieldBeNull(
00587                 preg_replace('/_\d{1,2}$/', '', $sFieldName)
00588                 );
00589     }
00590 }