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         $sFieldName = strtolower( $sFieldName );
00112         if ( isset( $this->_aFieldNames[$sFieldName] ) ) {
00113             return (bool) $this->_aFieldNames[$sFieldName];
00114         }
00115 
00116         //not inited field yet
00117         //and note that this is should be called only in first call after tmp dir is empty
00118         startProfile('!__CACHABLE2__!');
00119         $blIsMultilang = (bool) $this->_getFieldStatus( $sFieldName );
00120         stopProfile('!__CACHABLE2__!');
00121         return (bool) $blIsMultilang;
00122     }
00123 
00130     public function isMultilang()
00131     {
00132         return true;
00133     }
00134 
00143     public function loadInLang( $iLanguage, $sOxid)
00144     {
00145         // set new lang to this object
00146         $this->setLanguage($iLanguage);
00147         // reset
00148         $this->_sViewTable = false;
00149         return $this->load( $sOxid);
00150     }
00151 
00160     public function modifyCacheKey( $sCacheKey, $blOverride = false )
00161     {
00162         if ($blOverride) {
00163             $this->_sCacheKey = $sCacheKey."|i18n";
00164         } else {
00165             $this->_sCacheKey .= $sCacheKey;
00166         }
00167 
00168         if (!$sCacheKey) {
00169             $this->_sCacheKey = null;
00170         }
00171     }
00172 
00179     public function getAvailableInLangs()
00180     {
00181         $aLanguages = oxLang::getInstance()->getLanguageNames();
00182 
00183         $aObjFields = $this->_getTableFields(
00184             getViewName($this->_sCoreTable, -1, -1),
00185             true
00186         );
00187         $aMultiLangFields = array();
00188 
00189         //selecting all object multilang fields
00190         foreach ($aObjFields as $sKey => $sValue ) {
00191 
00192             //skipping oxactive field
00193             if ( preg_match('/^oxactive(_(\d{1,2}))?$/', $sKey) ) {
00194                 continue;
00195             }
00196 
00197             $iFieldLang = $this->_getFieldLang( $sKey );
00198 
00199             //checking, if field is multilanguage
00200             if ( $this->isMultilingualField($sKey) || $iFieldLang >  0 ) {
00201                 $sNewKey = preg_replace('/_(\d{1,2})$/', '', $sKey);
00202                 $aMultiLangFields[$sNewKey][] = (int) $iFieldLang;
00203             }
00204         }
00205 
00206         // if no multilanguage fields, return default languages array
00207         if ( count($aMultiLangFields) < 1 ) {
00208             return $aLanguages;
00209         }
00210 
00211         // select from non-multilanguage core view (all ml tables joined to one)
00212         $query = "select * from ".getViewName($this->_sCoreTable, -1, -1)." where oxid = '" . $this->getId() . "'";
00213         $rs = oxDb::getDb( true )->getAll($query);
00214 
00215         $aNotInLang = $aLanguages;
00216 
00217         // checks if object field data is not empty in all available languages
00218         // and formats not available in languages array
00219         if ( is_array($rs) && count($rs[0]) ) {
00220             foreach ( $aMultiLangFields as $sFieldId => $aMultiLangIds ) {
00221 
00222                 foreach ( $aMultiLangIds as $sMultiLangId ) {
00223                     $sFieldName = ( $sMultiLangId == 0 ) ? $sFieldId : $sFieldId.'_'.$sMultiLangId;
00224                     if ( $rs['0'][strtoupper($sFieldName)] ) {
00225                         unset( $aNotInLang[$sMultiLangId] );
00226                         continue;
00227                     }
00228                 }
00229             }
00230         }
00231 
00232         $aIsInLang = array_diff( $aLanguages, $aNotInLang );
00233 
00234         return $aIsInLang;
00235     }
00236 
00245     protected function _getFieldStatus( $sFieldName )
00246     {
00247         $aAllField = $this->_getAllFields( true );
00248         if ( isset( $aAllField[strtolower( $sFieldName ) . "_1"] ) ) {
00249             return 1;
00250         }
00251         return 0;
00252     }
00253 
00265     protected function _getNonCachedFieldNames($blForceFullStructure = false)
00266     {
00267         //Tomas
00268         //TODO: this place could be optimized. please check what we can do.
00269         $aFields = parent::_getNonCachedFieldNames($blForceFullStructure);
00270 
00271         if (!$this->_blEmployMultilanguage) {
00272             return $aFields;
00273         }
00274 
00275         //lets do some pointer manipulation
00276         if ($aFields) {
00277             //non admin fields
00278             $aWorkingFields = &$aFields;
00279         } else {
00280             //most likely admin fields so we remove another language
00281             $aWorkingFields = &$this->_aFieldNames;
00282         }
00283 
00284         //we have an array of fields, lets remove multilanguage fields
00285         foreach ($aWorkingFields as $sName => $sVal) {
00286             if ($this->_getFieldLang($sName)) {
00287                 unset($aWorkingFields[$sName]);
00288             } else {
00289                 $aWorkingFields[$sName] = $this->_getFieldStatus($sName);
00290             }
00291         }
00292 
00293         return $aWorkingFields;
00294     }
00295 
00303     protected function _getFieldLang($sFieldName)
00304     {
00305         if ( false === strpos($sFieldName, '_')) {
00306             return 0;
00307         }
00308         if (preg_match('/_(\d{1,2})$/', $sFieldName, $aRegs)) {
00309             return $aRegs[1];
00310         } else {
00311             return 0;
00312         }
00313     }
00314 
00322     public function getUpdateSqlFieldName($sField)
00323     {
00324         $iLang = $this->getLanguage();
00325         if ($iLang && $this->_blEmployMultilanguage && $this->isMultilingualField($sField)) {
00326             $sField .= "_" . $iLang;
00327         }
00328 
00329         return $sField;
00330     }
00331 
00340     protected function _getUpdateFieldsForTable( $sTable, $blUseSkipSaveFields = true )
00341     {
00342         $sCoreTable = $this->getCoreTableName();
00343 
00344         $blSkipMultilingual = false;
00345         $blSkipCoreFields = false;
00346 
00347         if ($sTable != $sCoreTable ) {
00348             $blSkipCoreFields = true;
00349         }
00350         if ($this->_blEmployMultilanguage) {
00351             if ( $sTable != getLangTableName($sCoreTable, $this->getLanguage() ) ) {
00352                 $blSkipMultilingual = true;
00353             }
00354         }
00355 
00356         $sSql = '';
00357         $blSep  = false;
00358         foreach (array_keys($this->_aFieldNames) as $sKey) {
00359             $sKeyLowercase = strtolower($sKey);
00360             if ($sKeyLowercase != 'oxid') {
00361                 if ($this->_blEmployMultilanguage) {
00362                     if ($blSkipMultilingual && $this->isMultilingualField($sKey)) {
00363                         continue;
00364                     }
00365                     if ($blSkipCoreFields && !$this->isMultilingualField($sKey)) {
00366                         continue;
00367                     }
00368                 } else {
00369                     // need to explicitly check field language
00370                     $iFieldLang = $this->_getFieldLang($sKey);
00371                     if ($iFieldLang) {
00372                         if ($sTable != getLangTableName($sCoreTable, $iFieldLang)) {
00373                             continue;
00374                         }
00375                     } elseif ($blSkipCoreFields) {
00376                         continue;
00377                     }
00378                 }
00379             }
00380 
00381             $sLongName = $this->_getFieldLongName($sKey);
00382             $oField = $this->$sLongName;
00383 
00384             if ( !$blUseSkipSaveFields || ($blUseSkipSaveFields && !in_array($sKeyLowercase, $this->_aSkipSaveFields)) ) {
00385                 $sKey = $this->getUpdateSqlFieldName($sKey);
00386                 $sSql .= (( $blSep) ? ',':'' ).$sKey." = ".$this->_getUpdateFieldValue($sKey, $oField);
00387                 $blSep = true;
00388             }
00389         }
00390 
00391         return $sSql;
00392     }
00393 
00403     protected function _getUpdateFields( $blUseSkipSaveFields = true )
00404     {
00405         return $this->_getUpdateFieldsForTable( $this->getCoreTableName(), $blUseSkipSaveFields );
00406     }
00407 
00418     protected function _update()
00419     {
00420         $blRet = parent::_update();
00421 
00422         if ($blRet) {
00423             //also update multilang table if it is separate
00424             $aUpdateTables = array();
00425             if ($this->_blEmployMultilanguage) {
00426                 $sCoreTable = $this->getCoreTableName();
00427                 $sLangTable = getLangTableName($sCoreTable, $this->getLanguage() );
00428                 if ($sCoreTable != $sLangTable) {
00429                     $aUpdateTables[] = $sLangTable;
00430                 }
00431             } else {
00432                 $aUpdateTables = $this->_getLanguageSetTables();
00433             }
00434             foreach ($aUpdateTables as $sLangTable) {
00435                 $sUpdate= "insert into $sLangTable set ".$this->_getUpdateFieldsForTable( $sLangTable, false ) .
00436                           " on duplicate key update ".$this->_getUpdateFieldsForTable( $sLangTable );
00437 
00438                 $blRet = (bool) oxDB::getDb()->execute( $sUpdate);
00439             }
00440         }
00441 
00442         // currently only multilanguage objects are SEO
00443         // if current object is managed by SEO and SEO is ON
00444         if ( $blRet && $this->_blIsSeoObject && $this->isAdmin() ) {
00445             // marks all object db entries as expired
00446             oxSeoEncoder::getInstance()->markAsExpired( $this->getId(), null, 1, $this->getLanguage() );
00447         }
00448 
00449         return $blRet;
00450     }
00451 
00457     protected function _getLanguageSetTables()
00458     {
00459         return oxNew('oxDbMetaDataHandler')->getAllMultiTables($this->getCoreTableName());
00460     }
00461 
00469     protected function _insert()
00470     {
00471         $blRet = parent::_insert();
00472 
00473         if ($blRet) {
00474             //also insert to multilang tables if it is separate
00475             foreach ($this->_getLanguageSetTables() as $sTable) {
00476                 $sSq = "insert into $sTable set ".$this->_getUpdateFieldsForTable( $sTable, false );
00477                 $blRet = $blRet && (bool) oxDB::getDb()->execute( $sSq );
00478             }
00479         }
00480 
00481         return $blRet;
00482     }
00483 
00492     protected function _getObjectViewName( $sTable, $sShopID = null)
00493     {
00494         if (!$this->_blEmployMultilanguage) {
00495             return parent::_getObjectViewName($sTable, $sShopID);
00496         }
00497 
00498         if ( $this->_blForceCoreTableUsage ) {
00499             $sShopID = -1;
00500         }
00501         return getViewName( $sTable, $this->getLanguage(), $sShopID);
00502     }
00503 
00511     public function getViewName($blForceCoreTableUsage = null)
00512     {
00513         if (!$this->_blEmployMultilanguage) {
00514             return parent::getViewName($blForceCoreTableUsage);
00515         }
00516         if (!$this->_sViewTable || ($blForceCoreTableUsage !== null)) {
00517             if ( ($blForceCoreTableUsage !== null)?$blForceCoreTableUsage:$this->_blForceCoreTableUsage ) {
00518                 $iShopId = -1;
00519             } else {
00520                 $iShopId = oxConfig::getInstance()->getShopId();
00521             }
00522             $sViewName = getViewName($this->_sCoreTable, $this->getLanguage(), $iShopId);
00523             if ($blForceCoreTableUsage !== null) {
00524                 return $sViewName;
00525             }
00526             $this->_sViewTable = $sViewName;
00527         }
00528         return $this->_sViewTable;
00529     }
00530 
00542     protected function _getAllFields( $blReturnSimple = false )
00543     {
00544         if ( $this->_blEmployMultilanguage ) {
00545             return parent::_getAllFields( $blReturnSimple );
00546         } else {
00547             $sViewName = $this->getViewName();
00548             if ( !$sViewName ) {
00549                 return array();
00550             }
00551             return $this->_getTableFields( $sViewName, $blReturnSimple );
00552         }
00553     }
00554 
00565     protected function _addField($sName, $sStatus, $sType = null, $sLength = null)
00566     {
00567         if ($this->_blEmployMultilanguage && $this->_getFieldLang($sName)) {
00568             return;
00569         }
00570 
00571         return parent::_addField($sName, $sStatus, $sType, $sLength);
00572     }
00573 
00585     protected function _canFieldBeNull( $sFieldName )
00586     {
00587         $sFieldName = preg_replace( '/_\d{1,2}$/', '', $sFieldName );
00588         return parent::_canFieldBeNull( $sFieldName );
00589     }
00590 }