Main Page | Directories | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members | Related Pages | Examples

lang.php

Go to the documentation of this file.
00001 <?php
00002 /***************************************************************
00003 *  Copyright notice
00004 *
00005 *  (c) 1999-2004 Kasper Skaarhoj (kasperYYYY@typo3.com)
00006 *  All rights reserved
00007 *
00008 *  This script is part of the TYPO3 project. TYPO3 is free software;
00009 *  You can redistribute it and/or modify it under the terms of the
00010 *  TYPO3 License as published from the www.typo3.com website.
00011 *
00012 *  This script is distributed in the hope that it will be useful,
00013 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00015 *
00016 *  This copyright notice MUST APPEAR in all copies of this script
00017 ***************************************************************/
00080 class language {
00081    var $lang='default';    // This is set to the language that is currently running for the user
00082    var $langSplit='default';  // Values like the labels in the tables.php-document are split by '|'. This values defines which language is represented by which position in the resulting array after splitting a value. (NOTICE: Obsolete concept!)
00083 
00084       // Default charset in backend
00085    var $charSet = 'iso-8859-1';
00086 
00087       // Array with alternative charsets for other languages. (Moved to t3lib_cs, Set from csConvObj!)
00088    var $charSetArray = array();
00089 
00090       // This is the url to the TYPO3 manual
00091    var $typo3_help_url= 'http://www.typo3.com/man_uk/';
00092       // Array with alternative URLs based on language.
00093    var $helpUrlArray = array(
00094       'dk' => 'http://www.typo3.com/man_dk/',
00095    );
00096 
00097 
00098    var $moduleLabels = Array();  // Can contain labels and image references from the backend modules. Relies on t3lib_loadmodules to initialize modules after a global instance of $LANG has been created.
00099 
00100       // Internal
00101    var $langSplitIndex=0;        // Points to the position of the current language key as found in constant TYPO3_languages
00102    var $LL_files_cache=array();  // Internal cache for read LL-files
00103    var $LL_labels_cache=array(); // Internal cache for ll-labels (filled as labels are requested)
00104 
00105       // Internal charset conversion:
00106    var $origCharSet='';    // If set, then it means that the this->charSet is set to a forced, common value for the WHOLE backend regardless of user language. And THIS variable will contain the original charset for the language labels. With ->csConvObj we must then convert the original charset to the charset used in the backend from now on.
00107    var $csConvObj;            // An instance of the "t3lib_cs" class. May be used by any application.
00108 
00109 
00110 
00111 
00112 
00113 
00114 
00115 
00128    function init($lang,$altPath='') {
00129 
00130          // Initialize the conversion object:
00131       $this->csConvObj = t3lib_div::makeInstance('t3lib_cs');
00132       $this->charSetArray = $this->csConvObj->charSetArray;
00133 
00134          // Internally setting the list of TYPO3 backend languages.
00135       $this->langSplit=TYPO3_languages;
00136 
00137          // Finding the requested language in this list based on the $lang key being inputted to this function.
00138       $ls = explode('|',$this->langSplit);
00139       while(list($i,$v)=each($ls))  {
00140          if ($v==$lang) {  // Language is found. Configure it:
00141             $this->langSplitIndex=$i;     // The index of the language as found in the TYPO3_languages list
00142             $this->lang = $lang;       // The current language key
00143             if ($this->helpUrlArray[$this->lang])  $this->typo3_help_url=$this->helpUrlArray[$this->lang];  // The help URL if different from the default.
00144             if ($this->charSetArray[$this->lang])  $this->charSet=$this->charSetArray[$this->lang];      // The charset if different from the default.
00145          }
00146       }
00147 
00148          // If a forced charset is used and different from the charset otherwise used:
00149       if ($GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'] && $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset']!=$this->charSet)   {
00150             // Set the forced charset:
00151          $this->origCharSet = $this->charSet;
00152          $this->charSet = $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'];
00153 
00154          if ($this->charSet!='utf-8' && !$this->csConvObj->initCharset($this->charSet))      {
00155             t3lib_BEfunc::typo3PrintError ('The forced character set "'.$this->charSet.'" was not found in t3lib/csconvtbl/','Forced charset not found');
00156             exit;
00157          }
00158          if ($this->origCharSet!='utf-8' && !$this->csConvObj->initCharset($this->origCharSet))    {
00159             t3lib_BEfunc::typo3PrintError ('The original character set "'.$this->origCharSet.'" was not found in t3lib/csconvtbl/','Forced charset not found');
00160             exit;
00161          }
00162       }
00163    }
00164 
00173    function addModuleLabels($arr,$prefix) {
00174       if (is_array($arr))  {
00175          reset($arr);
00176          while(list($k,$larr)=each($arr)) {
00177             if (!isset($this->moduleLabels[$k]))   {
00178                $this->moduleLabels[$k]=array();
00179             }
00180             if (is_array($larr)) {
00181                reset($larr);
00182                while(list($l,$v)=each($larr))   {
00183                   $this->moduleLabels[$k][$prefix.$l]=$v;
00184                }
00185             }
00186          }
00187       }
00188    }
00189 
00199    function hscAndCharConv($lStr,$hsc) {
00200       $lStr = $hsc ? htmlspecialchars($lStr) : $lStr;
00201       if ($this->origCharSet) {
00202          $lStr = $this->csConvObj->conv($lStr,$this->origCharSet,$this->charSet,1);
00203       }
00204       return $lStr;
00205    }
00206 
00214    function makeEntities($str)   {
00215          // Convert string to UTF-8:
00216       if ($this->charSet!='utf-8')  $str = $this->csConvObj->utf8_encode($str,$this->charSet);
00217 
00218          // Convert string back again, but using the full entity conversion:
00219       $str = $this->csConvObj->utf8_to_entities($str);
00220       return $str;
00221    }
00222 
00231    function JScharCode($str)  {
00232 
00233          // Convert string to UTF-8:
00234       if ($this->charSet!='utf-8')  $str = $this->csConvObj->utf8_encode($str,$this->charSet);
00235 
00236          // Convert the UTF-8 string into a array of char numbers:
00237       $nArr = $this->csConvObj->utf8_to_numberarray($str);
00238 
00239       return 'String.fromCharCode('.implode(',',$nArr).')';
00240    }
00241 
00250    function getLL($index,$hsc=0) {
00251       // Get Local Language
00252       if (strcmp($GLOBALS['LOCAL_LANG'][$this->lang][$index],'')) {
00253          return $this->hscAndCharConv($GLOBALS['LOCAL_LANG'][$this->lang][$index], $hsc); // Returns local label if not blank.
00254       } else {
00255          return $this->hscAndCharConv($GLOBALS['LOCAL_LANG']['default'][$index], $hsc);   // Returns default label
00256       }
00257    }
00258 
00267    function getLLL($index,$LOCAL_LANG,$hsc=0)   {
00268       // Get Local Language
00269       if (strcmp($LOCAL_LANG[$this->lang][$index],''))   {
00270          return $this->hscAndCharConv($LOCAL_LANG[$this->lang][$index], $hsc);   // Returns local label if not blank.
00271       } else {
00272          return $this->hscAndCharConv($LOCAL_LANG['default'][$index], $hsc);     // Returns default label
00273       }
00274    }
00275 
00287    function sL($input,$hsc=0) {
00288       if (strcmp(substr($input,0,4),'LLL:')) {  // Using obsolete 'language-splitted' labels:
00289          $t = explode('|',$input);
00290          $out = $t[$this->langSplitIndex] ? $t[$this->langSplitIndex] : $t[0];
00291          return $this->hscAndCharConv($out, $hsc);
00292       } else { // LOCAL_LANG:
00293          if (!isset($this->LL_labels_cache[$this->lang][$input])) {  // If cached label
00294             $restStr = trim(substr($input,4));
00295             $extPrfx='';
00296             if (!strcmp(substr($restStr,0,4),'EXT:')) {  // ll-file refered to is found in an extension.
00297                $restStr = trim(substr($restStr,4));
00298                $extPrfx='EXT:';
00299             }
00300             $parts = explode(':',$restStr);
00301             $parts[0]=$extPrfx.$parts[0];
00302             if (!isset($this->LL_files_cache[$parts[0]]))   {  // Getting data if not cached
00303                $this->LL_files_cache[$parts[0]] = $this->readLLfile($parts[0]);
00304 
00305                   // If the current language is found in another file, load that as well:
00306                $lFileRef = $this->localizedFileRef($parts[0]);
00307                if ($lFileRef && is_string($this->LL_files_cache[$parts[0]][$this->lang]) && $this->LL_files_cache[$parts[0]][$this->lang]=='EXT')  {
00308                   $tempLL = $this->readLLfile($lFileRef);
00309                   $this->LL_files_cache[$parts[0]][$this->lang] = $tempLL[$this->lang];
00310                }
00311 
00312                   // Overriding file?
00313                if (isset($GLOBALS['TYPO3_CONF_VARS']['BE']['XLLfile'][$parts[0]]))  {
00314                   $ORarray = $this->readLLfile($GLOBALS['TYPO3_CONF_VARS']['BE']['XLLfile'][$parts[0]]);
00315                   $this->LL_files_cache[$parts[0]] = t3lib_div::array_merge_recursive_overrule($this->LL_files_cache[$parts[0]],$ORarray);
00316                }
00317             }
00318             $this->LL_labels_cache[$this->lang][$input] = $this->getLLL($parts[1],$this->LL_files_cache[$parts[0]]);
00319          }
00320          return $hsc ? t3lib_div::deHSCentities(htmlspecialchars($this->LL_labels_cache[$this->lang][$input])) : $this->LL_labels_cache[$this->lang][$input]; // For the cached output charset conversion has already happend! So perform HSC right here.
00321       }
00322    }
00323 
00331    function loadSingleTableDescription($table)  {
00332       global $TCA_DESCR;
00333 
00334       if (is_array($TCA_DESCR[$table])
00335             && !isset($TCA_DESCR[$table]['columns'])
00336             && is_array($TCA_DESCR[$table]['refs']))   { // First the 'table' cannot already be loaded in [columns] and secondly there must be a references to locallang files available in [refs]
00337 
00338             // Init $TCA_DESCR for $table-key
00339          $TCA_DESCR[$table]['columns']=array();
00340 
00341             // Get local-lang for each file in $TCA_DESCR[$table]['refs'] as they are ordered.
00342          foreach ($TCA_DESCR[$table]['refs'] as $llfile) {
00343             $LOCAL_LANG = $this->includeLLFile($llfile,0,1);
00344 
00345                // Traverse all keys
00346             if (is_array($LOCAL_LANG['default']))  {
00347                foreach($LOCAL_LANG['default'] as $lkey => $lVal)  {
00348 
00349                      // exploding by '.':
00350                      // 0 => fieldname,
00351                      // 1 => type from (alttitle,description,details,syntax,image_descr,image,seeAlso),
00352                      // 2 => special instruction, see switch construct
00353                   $kParts = explode('.',$lkey);
00354 
00355                      // Detecting 'hidden' labels, converting to normal fieldname
00356                   if ($kParts[0]=='_') $kParts[0]='';
00357                   if (substr($kParts[0],0,1)=='_') { $kParts[0] = substr($kParts[0],1); }
00358 
00359                      // Add label:
00360                   switch((string)$kParts[2]) {
00361                      case '+':   // adding
00362                         $TCA_DESCR[$table]['columns'][$kParts[0]][$kParts[1]].= chr(10).$lVal;
00363                      break;
00364                      default: // Substituting:
00365                         $TCA_DESCR[$table]['columns'][$kParts[0]][$kParts[1]] = $lVal;
00366                      break;
00367                   }
00368                }
00369             }
00370          }
00371       }
00372    }
00373 
00383    function includeLLFile($fileRef,$setGlobal=1,$mergeLocalOntoDefault=0)  {
00384          // Configure for global flag:
00385       if ($setGlobal)   {
00386          global $LOCAL_LANG;
00387       }
00388 
00389          // Get default file:
00390       $llang = $this->readLLfile($fileRef);
00391 
00392       if (count($llang))   {
00393 
00394          $LOCAL_LANG = t3lib_div::array_merge_recursive_overrule($LOCAL_LANG,$llang);
00395 
00396             // Localized addition?
00397          $lFileRef = $this->localizedFileRef($fileRef);
00398          if ($lFileRef && (string)$LOCAL_LANG[$this->lang]=='EXT')   {
00399             $llang = $this->readLLfile($lFileRef);
00400             $LOCAL_LANG = t3lib_div::array_merge_recursive_overrule($LOCAL_LANG,$llang);
00401          }
00402 
00403             // Overriding file?
00404          if (isset($GLOBALS['TYPO3_CONF_VARS']['BE']['XLLfile'][$fileRef]))   {
00405             $ORarray = $this->readLLfile($GLOBALS['TYPO3_CONF_VARS']['BE']['XLLfile'][$fileRef]);
00406             $LOCAL_LANG = t3lib_div::array_merge_recursive_overrule($LOCAL_LANG,$ORarray);
00407          }
00408 
00409             // Merge local onto default:
00410          if ($mergeLocalOntoDefault && strcmp($this->lang,'default') && is_array($LOCAL_LANG[$this->lang]) && is_array($LOCAL_LANG['default'])) {
00411             $LOCAL_LANG['default'] = array_merge($LOCAL_LANG['default'],$LOCAL_LANG[$this->lang]); // array_merge can be used so far the keys are not numeric - which we assume they are not...
00412             unset($LOCAL_LANG[$this->lang]);
00413          }
00414       }
00415 
00416          // Return value if not global is set.
00417       if (!$setGlobal)  {
00418          return $LOCAL_LANG;
00419       }
00420    }
00421 
00428    function readLLfile($fileRef) {
00429       $file = t3lib_div::getFileAbsFileName($fileRef);
00430       if ($file)  {
00431          $baseFile = ereg_replace('\.(php|xml)$', '', $file);
00432 
00433          if (@is_file($baseFile.'.xml'))  {
00434             $LOCAL_LANG = $this->readLLXMLfile($baseFile.'.xml', $this->lang);
00435          } elseif (@is_file($baseFile.'.php'))  {
00436             include($baseFile.'.php');
00437          } else die('Filereference, "'.$file.'", not found!');
00438       }
00439       return is_array($LOCAL_LANG)?$LOCAL_LANG:array();
00440    }
00441 
00449    function readLLXMLfile($fileRef,$langKey) {
00450 
00451       if (@is_file($fileRef) && $langKey) {
00452 
00453             // Set charset:
00454          $origCharset = $this->csConvObj->parse_charset($this->csConvObj->charSetArray[$langKey] ? $this->csConvObj->charSetArray[$langKey] : 'iso-8859-1');
00455 
00456             // Cache file name:
00457          $hashSource = substr($fileRef,strlen(PATH_site)).'|'.date('d-m-Y H:i:s',filemtime($fileRef));
00458          $cacheFileName = PATH_site.'typo3temp/llxml/'.
00459                      #str_replace('_','',ereg_replace('^.*\/','',dirname($fileRef))).
00460                      #'_'.basename($fileRef).
00461                      substr(basename($fileRef),10,15).
00462                      '_'.t3lib_div::shortMD5($hashSource).'.'.$langKey.'.'.$origCharset.'.cache';
00463 
00464             // Check if cache file exists...
00465          if (!@is_file($cacheFileName))   {  // ... if it doesn't, create content and write it:
00466 
00467                // Read XML, parse it.
00468             $xmlString = t3lib_div::getUrl($fileRef);
00469             $xmlContent = t3lib_div::xml2array($xmlString);
00470 
00471                // Set default LOCAL_LANG array content:
00472             $LOCAL_LANG = array();
00473             $LOCAL_LANG['default'] = $xmlContent['data']['default'];
00474 
00475                // Specific language, convert from utf-8 to backend language charset:
00476                // NOTICE: Converting from utf-8 back to "native" language may be a temporary solution until we can totally discard "locallang.php" files altogether (and use utf-8 for everything). But doing this conversion is the quickest way to migrate now and the source is in utf-8 anyway which is the main point.
00477             if ($langKey!='default')   {
00478                $LOCAL_LANG[$langKey] = $xmlContent['data'][$langKey];
00479 
00480                   // Checking if charset should be converted.
00481                if (is_array($LOCAL_LANG[$langKey]) && $origCharset!='utf-8')  {
00482                   foreach($LOCAL_LANG[$langKey] as $labelKey => $labelValue)  {
00483                      $LOCAL_LANG[$langKey][$labelKey] = $this->csConvObj->utf8_decode($labelValue,$origCharset);
00484                   }
00485                }
00486             }
00487 
00488                // Cache the content now:
00489             $serContent = array('origFile'=>$hashSource, 'LOCAL_LANG'=>$LOCAL_LANG);
00490             $res = t3lib_div::writeFileToTypo3tempDir($cacheFileName, serialize($serContent));
00491             if ($res)   die('ERROR: '.$res);
00492          } else {
00493                // Get content from cache:
00494             $serContent = unserialize(t3lib_div::getUrl($cacheFileName));
00495             $LOCAL_LANG = $serContent['LOCAL_LANG'];
00496          }
00497 
00498             // Checking for EXTERNAL file for non-default language:
00499          if ($langKey!='default' && is_string($LOCAL_LANG[$langKey]) && strlen($LOCAL_LANG[$langKey]))   {
00500 
00501                // Look for localized file:
00502             $localized_file = t3lib_div::getFileAbsFileName($LOCAL_LANG[$langKey]);
00503             if ($localized_file && @is_file($localized_file))  {
00504 
00505                   // Cache file name:
00506                $hashSource = substr($localized_file,strlen(PATH_site)).'|'.date('d-m-Y H:i:s',filemtime($localized_file));
00507                $cacheFileName = PATH_site.'typo3temp/llxml/ext_'.
00508                            substr(basename($localized_file),10,15).
00509                            '_'.t3lib_div::shortMD5($hashSource).'.'.$langKey.'.'.$origCharset.'.cache';
00510 
00511                   // Check if cache file exists...
00512                if (!@is_file($cacheFileName))   {  // ... if it doesn't, create content and write it:
00513 
00514                      // Read and parse XML content:
00515                   $local_xmlString = t3lib_div::getUrl($localized_file);
00516                   $local_xmlContent = t3lib_div::xml2array($local_xmlString);
00517                   $LOCAL_LANG[$langKey] = is_array($local_xmlContent['data'][$langKey]) ? $local_xmlContent['data'][$langKey] : array();
00518 
00519                      // Checking if charset should be converted.
00520                   if (is_array($LOCAL_LANG[$langKey]) && $origCharset!='utf-8')  {
00521                      foreach($LOCAL_LANG[$langKey] as $labelKey => $labelValue)  {
00522                         $LOCAL_LANG[$langKey][$labelKey] = $this->csConvObj->utf8_decode($labelValue,$origCharset);
00523                      }
00524                   }
00525 
00526                      // Cache the content now:
00527                   $serContent = array('extlang'=>$langKey, 'origFile'=>$LOCAL_LANG[$langKey], 'EXT_DATA'=>$LOCAL_LANG[$langKey]);
00528                   $res = t3lib_div::writeFileToTypo3tempDir($cacheFileName, serialize($serContent));
00529                   if ($res)   die('ERROR: '.$res);
00530                } else {
00531                      // Get content from cache:
00532                   $serContent = unserialize(t3lib_div::getUrl($cacheFileName));
00533                   $LOCAL_LANG[$langKey] = $serContent['EXT_DATA'];
00534                }
00535             }
00536          }
00537 
00538          return $LOCAL_LANG;
00539       }
00540    }
00541 
00548    function localizedFileRef($fileRef) {
00549       if ($this->lang!='default' && substr($fileRef,-4)=='.php')  {
00550          return substr($fileRef,0,-4).'.'.$this->lang.'.php';
00551       }
00552    }
00553 }
00554 
00555 // Include extension to the template class?
00556 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/lang/lang.php']) {
00557    include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/lang/lang.php']);
00558 }
00559 ?>

Generated on Sun Oct 3 01:06:01 2004 for TYPO3core 3.7.0 dev by  doxygen 1.3.8-20040913