Documentation TYPO3 par Ameos |
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 ?>