Support Joomla!

Packages

Package: Joomla-Framework

License

Content on this site is copyright © 2005 - 2008 Open Source Matters Inc and can be used in accordance with the Joomla! Electronic Documentation License. Some parts of this website may be subject to other licenses.
Source code for file /joomla/language/language.php

Documentation is available at language.php

  1. <?php
  2. /**
  3. @version        $Id: language.php 13297 2009-10-24 01:29:37Z ian $
  4. @package        Joomla.Framework
  5. @subpackage    Language
  6. @copyright    Copyright (C) 2005 - 2008 Open Source Matters. All rights reserved.
  7. @license        GNU/GPL, see LICENSE.php
  8. *  Joomla! is free software. This version may have been modified pursuant
  9. *  to the GNU General Public License, and as distributed it includes or
  10. *  is derivative of works licensed under the GNU General Public License or
  11. *  other free or open source software licenses.
  12. *  See COPYRIGHT.php for copyright notices and details.
  13. */
  14.  
  15. // Check to ensure this file is within the rest of the framework
  16. defined('JPATH_BASE'or die();
  17.  
  18. /**
  19.  * Languages/translation handler class
  20.  *
  21.  * @package     Joomla.Framework
  22.  * @subpackage    Language
  23.  * @since        1.5
  24.  */
  25. class JLanguage extends JObject
  26. {
  27.     /**
  28.      * Debug language, If true, highlights if string isn't found
  29.      *
  30.      * @var        boolean 
  31.      * @access    protected
  32.      * @since    1.5
  33.      */
  34.     var $_debug     = false;
  35.  
  36.     /**
  37.      * The default language
  38.      *
  39.      * The default language is used when a language file in the requested language does not exist.
  40.      *
  41.      * @var        string 
  42.      * @access    protected
  43.      * @since    1.5
  44.      */
  45.     var $_default    = 'en-GB';
  46.  
  47.     /**
  48.      * An array of orphaned text
  49.      *
  50.      * @var        array 
  51.      * @access    protected
  52.      * @since    1.5
  53.      */
  54.     var $_orphans     = array();
  55.  
  56.     /**
  57.      * Array holding the language metadata
  58.      *
  59.      * @var        array 
  60.      * @access    protected
  61.      * @since    1.5
  62.      */
  63.     var $_metadata     = null;
  64.  
  65.     /**
  66.      * The language to load
  67.      *
  68.      * @var        string 
  69.      * @access    protected
  70.      * @since    1.5
  71.      */
  72.     var $_lang = null;
  73.  
  74.     /**
  75.      * List of language files that have been loaded
  76.      *
  77.      * @var        array of arrays
  78.      * @access    public
  79.      * @since    1.5
  80.      */
  81.     var $_paths    = array();
  82.  
  83.     /**
  84.      * Translations
  85.      *
  86.      * @var        array 
  87.      * @access    protected
  88.      * @since    1.5
  89.      */
  90.     var $_strings = null;
  91.  
  92.     /**
  93.      * An array of used text, used during debugging
  94.      *
  95.      * @var        array 
  96.      * @access    protected
  97.      * @since    1.5
  98.      */
  99.     var $_used        = array();
  100.  
  101.     /**
  102.     * Constructor activating the default information of the language
  103.     *
  104.     * @access    protected
  105.     */
  106.     function __construct($lang null)
  107.     {
  108.         $this->_strings = array ();
  109.  
  110.         if $lang == null {
  111.             $lang $this->_default;
  112.         }
  113.  
  114.         $this->setLanguage($lang);
  115.  
  116.         $this->load();
  117.     }
  118.  
  119.     /**
  120.      * Returns a reference to a language object
  121.      *
  122.      * This method must be invoked as:
  123.      *         <pre>  $browser = &JLanguage::getInstance([$lang);</pre>
  124.      *
  125.      * @access    public
  126.      * @param    string $lang  The language to use.
  127.      * @return    JLanguage  The Language object.
  128.      * @since    1.5
  129.      */
  130.     function getInstance($lang)
  131.     {
  132.         $instance new JLanguage($lang);
  133.         $reference $instance;
  134.         return $reference;
  135.     }
  136.  
  137.     /**
  138.     * Translate function, mimics the php gettext (alias _) function
  139.     *
  140.     * @access    public
  141.     * @param    string        $string     The string to translate
  142.     * @param    boolean    $jsSafe        Make the result javascript safe
  143.     * @return    string    The translation of the string
  144.     * @since    1.5
  145.     */
  146.     function _($string$jsSafe false)
  147.     {
  148.         //$key = str_replace( ' ', '_', strtoupper( trim( $string ) ) );echo '<br />'.$key;
  149.         $key strtoupper($string);
  150.         $key substr($key01== '_' substr($key1$key;
  151.  
  152.         if (isset ($this->_strings[$key]))
  153.         {
  154.             $string $this->_debug ? "&bull;".$this->_strings[$key]."&bull;" $this->_strings[$key];
  155.  
  156.             // Store debug information
  157.             if $this->_debug )
  158.             {
  159.                 $caller $this->_getCallerInfo();
  160.  
  161.                 if array_key_exists($key$this->_used ) ) {
  162.                     $this->_used[$keyarray();
  163.                 }
  164.  
  165.                 $this->_used[$key][$caller;
  166.             }
  167.  
  168.         }
  169.         else
  170.         {
  171.             if (defined($string))
  172.             {
  173.                 $string $this->_debug ? '!!'.constant($string).'!!' constant($string);
  174.  
  175.                 // Store debug information
  176.                 if $this->_debug )
  177.                 {
  178.                     $caller $this->_getCallerInfo();
  179.  
  180.                     if array_key_exists($key$this->_used ) ) {
  181.                         $this->_used[$keyarray();
  182.                     }
  183.  
  184.                     $this->_used[$key][$caller;
  185.                 }
  186.             }
  187.             else
  188.             {
  189.                 if ($this->_debug)
  190.                 {
  191.                     $caller    $this->_getCallerInfo();
  192.                     $caller['string'$string;
  193.  
  194.                     if array_key_exists($key$this->_orphans ) ) {
  195.                         $this->_orphans[$keyarray();
  196.                     }
  197.  
  198.                     $this->_orphans[$key][$caller;
  199.  
  200.                     $string '??'.$string.'??';
  201.                 }
  202.             }
  203.         }
  204.  
  205.         if ($jsSafe{
  206.             $string addslashes($string);
  207.         }
  208.  
  209.         return $string;
  210.     }
  211.  
  212.     /**
  213.      * Transliterate function
  214.      *
  215.      * This method processes a string and replaces all accented UTF-8 characters by unaccented
  216.      * ASCII-7 "equivalents"
  217.      *
  218.      * @access    public
  219.      * @param    string    $string     The string to transliterate
  220.      * @return    string    The transliteration of the string
  221.      * @since    1.5
  222.      */
  223.     function transliterate($string)
  224.     {
  225.         $string htmlentities(utf8_decode($string));
  226.         $string preg_replace(
  227.             array('/&szlig;/','/&(..)lig;/''/&([aouAOU])uml;/','/&(.)[^;]*;/'),
  228.             array('ss',"$1","$1".'e',"$1"),
  229.             $string);
  230.  
  231.         return $string;
  232.     }
  233.  
  234.     /**
  235.      * Check if a language exists
  236.      *
  237.      * This is a simple, quick check for the directory that should contain language files for the given user.
  238.      *
  239.      * @access    public
  240.      * @param    string $lang Language to check
  241.      * @param    string $basePath Optional path to check
  242.      * @return    boolean True if the language exists
  243.      * @since    1.5
  244.      */
  245.     function exists($lang$basePath JPATH_BASE)
  246.     {
  247.         static    $paths    array();
  248.  
  249.         // Return false if no language was specified
  250.                 if $lang {
  251.             return false;
  252.         }
  253.  
  254.         $path    $basePath.DS.'language'.DS.$lang;
  255.  
  256.         // Return previous check results if it exists
  257.                 if isset($paths[$path]) )
  258.         {
  259.             return $paths[$path];
  260.         }
  261.  
  262.         // Check if the language exists
  263.                 jimport('joomla.filesystem.folder');
  264.  
  265.         $paths[$path]    JFolder::exists($path);
  266.  
  267.         return $paths[$path];
  268.     }
  269.  
  270.     /**
  271.      * Loads a single language file and appends the results to the existing strings
  272.      *
  273.      * @access    public
  274.      * @param    string     $extension     The extension for which a language file should be loaded
  275.      * @param    string     $basePath      The basepath to use
  276.      * @param    string    $lang        The language to load, default null for the current language
  277.      * @param    boolean $reload        Flag that will force a language to be reloaded if set to true
  278.      * @return    boolean    True, if the file has successfully loaded.
  279.      * @since    1.5
  280.      */
  281.     function load$extension 'joomla'$basePath JPATH_BASE$lang null$reload false )
  282.     {
  283.         if $lang {
  284.             $lang $this->_lang;
  285.         }
  286.  
  287.         $path JLanguage::getLanguagePath$basePath$lang);
  288.  
  289.         if !strlen$extension ) ) {
  290.             $extension 'joomla';
  291.         }
  292.         $filename $extension == 'joomla' ?  $lang $lang '.' $extension ;
  293.         $filename $path.DS.$filename.'.ini';
  294.  
  295.         $result false;
  296.         if (isset$this->_paths[$extension][$filename&& $reload )
  297.         {
  298.             // Strings for this file have already been loaded
  299.             $result true;
  300.         }
  301.         else
  302.         {
  303.             // Load the language file
  304.             $result $this->_load$filename$extension );
  305.  
  306.             // Check if there was a problem with loading the file
  307.             if $result === false )
  308.             {
  309.                 // No strings, which probably means that the language file does not exist
  310.                 $path        JLanguage::getLanguagePath$basePath$this->_default);
  311.                 $filename    $extension == 'joomla' ?  $this->_default $this->_default '.' $extension ;
  312.                 $filename    $path.DS.$filename.'.ini';
  313.  
  314.                 $result $this->_load$filename$extensionfalse );
  315.             }
  316.  
  317.         }
  318.  
  319.         return $result;
  320.  
  321.     }
  322.     /**
  323.     * Loads a language file
  324.     *
  325.     * This method will not note the successful loading of a file - use load() instead
  326.     *
  327.     * @access    private
  328.     * @param    string The name of the file
  329.     * @param    string The name of the extension
  330.     * @return    boolean True if new strings have been added to the language
  331.     * @see        JLanguage::load()
  332.     * @since    1.5
  333.     */
  334.     function _load$filename$extension 'unknown'$overwrite true )
  335.     {
  336.         $result    false;
  337.  
  338.         if ($content @file_get_contents$filename ))
  339.         {
  340.  
  341.             //Take off BOM if present in the ini file
  342.             if $content[0== "\xEF" && $content[1== "\xBB" && $content[2== "\xBF" )
  343.             {
  344.                 $content substr$content);
  345.               }
  346.  
  347.             $registry    new JRegistry();
  348.             $registry->loadINI($content);
  349.             $newStrings    $registry->toArray);
  350.  
  351.             if is_array$newStrings) )
  352.             {
  353.                 $this->_strings $overwrite array_merge$this->_strings$newStringsarray_merge$newStrings$this->_strings);
  354.                 $result true;
  355.             }
  356.         }
  357.  
  358.         // Record the result of loading the extension's file.
  359.         if isset($this->_paths[$extension])) {
  360.             $this->_paths[$extensionarray();
  361.         }
  362.  
  363.         $this->_paths[$extension][$filename$result;
  364.  
  365.         return $result;
  366.     }
  367.  
  368.     /**
  369.      * Get a matadata language property
  370.      *
  371.      * @access    public
  372.      * @param    string $property    The name of the property
  373.      * @param    mixed  $default    The default value
  374.      * @return    mixed The value of the property
  375.      * @since    1.5
  376.      */
  377.     function get($property$default null)
  378.     {
  379.         if (isset ($this->_metadata[$property])) {
  380.             return $this->_metadata[$property];
  381.         }
  382.         return $default;
  383.     }
  384.  
  385.     /**
  386.      * Determine who called JLanguage or JText
  387.      *
  388.      * @access    private
  389.      * @return    array Caller information
  390.      * @since    1.5
  391.      */
  392.     function _getCallerInfo()
  393.     {
  394.             // Try to determine the source if none was provided
  395.         if (!function_exists('debug_backtrace')) {
  396.             return null;
  397.         }
  398.  
  399.         $backtrace    debug_backtrace();
  400.         $info        array();
  401.  
  402.         // Search through the backtrace to our caller
  403.         $continue true;
  404.         while ($continue && next($backtrace))
  405.         {
  406.             $step    current($backtrace);
  407.             $class    $step['class'];
  408.  
  409.             // We're looking for something outside of language.php
  410.             if ($class != 'JLanguage' && $class != 'JText'{
  411.                 $info['function']    $step['function'];
  412.                 $info['class']        $class;
  413.                 $info['step']        prev($backtrace);
  414.  
  415.                 // Determine the file and name of the file
  416.                 $info['file']        $step['file'];
  417.                 $info['line']        $step['line'];
  418.  
  419.                 $continue false;
  420.             }
  421.         }
  422.  
  423.         return $info;
  424.     }
  425.  
  426.     /**
  427.     * Getter for Name
  428.     *
  429.     * @access    public
  430.     * @return    string Official name element of the language
  431.     * @since    1.5
  432.     */
  433.     function getName({
  434.         return $this->_metadata['name'];
  435.     }
  436.  
  437.     /**
  438.      * Get a list of language files that have been loaded
  439.      *
  440.      * @access    public
  441.      * @param    string    $extension    An option extension name
  442.      * @return    array 
  443.      * @since    1.5
  444.      */
  445.     function getPaths($extension null)
  446.     {
  447.         if isset($extension) )
  448.         {
  449.             if isset($this->_paths[$extension]) )
  450.                 return $this->_paths[$extension];
  451.  
  452.             return null;
  453.         }
  454.         else
  455.         {
  456.             return $this->_paths;
  457.         }
  458.     }
  459.  
  460.     /**
  461.     * Getter for PDF Font Name
  462.     *
  463.     * @access    public
  464.     * @return    string name of pdf font to be used
  465.     * @since    1.5
  466.     */
  467.     function getPdfFontName({
  468.         return $this->_metadata['pdffontname'];
  469.     }
  470.  
  471.     /**
  472.     * Getter for Windows locale code page
  473.     *
  474.     * @access    public
  475.     * @return    string windows locale encoding
  476.     * @since    1.5
  477.     */
  478.     function getWinCP({
  479.         return $this->_metadata['wincodepage'];
  480.     }
  481.  
  482.     /**
  483.     * Getter for backward compatible language name
  484.     *
  485.     * @access    public
  486.     * @return    string backward compatible name
  487.     * @since    1.5
  488.     */
  489.     function getBackwardLang({
  490.         return $this->_metadata['backwardlang'];
  491.     }
  492.  
  493.     /**
  494.     * Get for the language tag (as defined in RFC 3066)
  495.     *
  496.     * @access    public
  497.     * @return    string The language tag
  498.     * @since    1.5
  499.     */
  500.     function getTag({
  501.         return $this->_metadata['tag'];
  502.     }
  503.  
  504.     /**
  505.     * Get locale property
  506.     *
  507.     * @access    public
  508.     * @return    string The locale property
  509.     * @since    1.5
  510.     */
  511.     function getLocale()
  512.     {
  513.         $locales explode(','$this->_metadata['locale']);
  514.  
  515.         for($i 0$i count($locales)$i++ {
  516.             $locale $locales[$i];
  517.             $locale trim($locale);
  518.             $locales[$i$locale;
  519.         }
  520.  
  521.         //return implode(',', $locales);
  522.         return $locales;
  523.     }
  524.  
  525.     /**
  526.     * Get the RTL property
  527.     *
  528.     * @access    public
  529.     * @return    boolean True is it an RTL language
  530.     * @since    1.5
  531.     */
  532.     function isRTL({
  533.         return $this->_metadata['rtl'];
  534.     }
  535.  
  536.     /**
  537.     * Set the Debug property
  538.     *
  539.     * @access    public
  540.     * @return    boolean Previous value
  541.     * @since    1.5
  542.     */
  543.     function setDebug($debug{
  544.         $previous    $this->_debug;
  545.         $this->_debug $debug;
  546.         return $previous;
  547.     }
  548.  
  549.     /**
  550.     * Get the Debug property
  551.     *
  552.     * @access    public
  553.     * @return    boolean True is in debug mode
  554.     * @since    1.5
  555.     */
  556.     function getDebug({
  557.         return $this->_debug;
  558.     }
  559.  
  560.     /**
  561.      * Get the default language code
  562.      *
  563.      * @access    public
  564.      * @return    string Language code
  565.      * @since    1.5
  566.      */
  567.     function getDefault({
  568.         return $this->_default;
  569.     }
  570.  
  571.     /**
  572.      * Set the default language code
  573.      *
  574.      * @access    public
  575.      * @return    string Previous value
  576.      * @since    1.5
  577.      */
  578.     function setDefault($lang{
  579.         $previous    $this->_default;
  580.         $this->_default    $lang;
  581.         return $previous;
  582.     }
  583.  
  584.     /**
  585.     * Get the list of orphaned strings if being tracked
  586.     *
  587.     * @access    public
  588.     * @return    array Orphaned text
  589.     * @since    1.5
  590.     */
  591.     function getOrphans({
  592.         return $this->_orphans;
  593.     }
  594.  
  595.     /**
  596.      * Get the list of used strings
  597.      *
  598.      * Used strings are those strings requested and found either as a string or a constant
  599.      *
  600.      * @access    public
  601.      * @return    array    Used strings
  602.      * @since    1.5
  603.      */
  604.     function getUsed({
  605.         return $this->_used;
  606.     }
  607.  
  608.     /**
  609.      * Determines is a key exists
  610.      *
  611.      * @access    public
  612.      * @param    key $key    The key to check
  613.      * @return    boolean True, if the key exists
  614.      * @since    1.5
  615.      */
  616.     function hasKey($key{
  617.         return isset ($this->_strings[strtoupper($key)]);
  618.     }
  619.  
  620.     /**
  621.      * Returns a associative array holding the metadata
  622.      *
  623.      * @access    public
  624.      * @param    string    The name of the language
  625.      * @return    mixed    If $lang exists return key/value pair with the language metadata,
  626.      *                   otherwise return NULL
  627.      * @since    1.5
  628.      */
  629.  
  630.     function getMetadata($lang)
  631.     {
  632.         $path JLanguage::getLanguagePath(JPATH_BASE$lang);
  633.         $file $lang.'.xml';
  634.  
  635.         $result null;
  636.         if(is_file($path.DS.$file)) {
  637.             $result JLanguage::_parseXMLLanguageFile($path.DS.$file);
  638.         }
  639.  
  640.         return $result;
  641.     }
  642.  
  643.     /**
  644.      * Returns a list of known languages for an area
  645.      *
  646.      * @access    public
  647.      * @param    string    $basePath     The basepath to use
  648.      * @return    array    key/value pair with the language file and real name
  649.      * @since    1.5
  650.      */
  651.     function getKnownLanguages($basePath JPATH_BASE)
  652.     {
  653.         $dir JLanguage::getLanguagePath($basePath);
  654.         $knownLanguages JLanguage::_parseLanguageFiles($dir);
  655.  
  656.         return $knownLanguages;
  657.     }
  658.  
  659.     /**
  660.      * Get the path to a language
  661.      *
  662.      * @access    public
  663.      * @param    string $basePath  The basepath to use
  664.      * @param    string $language    The language tag
  665.      * @return    string    language related path or null
  666.      * @since    1.5
  667.      */
  668.     function getLanguagePath($basePath JPATH_BASE$language null )
  669.     {
  670.         $dir $basePath.DS.'language';
  671.         if (!empty($language)) {
  672.             $dir .= DS.$language;
  673.         }
  674.         return $dir;
  675.     }
  676.  
  677.     /**
  678.      * Set the language attributes to the given language
  679.      *
  680.      * Once called, the language still needs to be loaded using JLanguage::load()
  681.      *
  682.      * @access    public
  683.      * @param    string    $lang    Language code
  684.      * @return    string    Previous value
  685.      * @since    1.5
  686.      */
  687.     function setLanguage($lang)
  688.     {
  689.         $previous            $this->_lang;
  690.         $this->_lang        $lang;
  691.         $this->_metadata    $this->getMetadata($this->_lang);
  692.  
  693.         //set locale based on the language tag
  694.         //TODO : add function to display locale setting in configuration
  695.         $locale setlocale(LC_TIME$this->getLocale());
  696.         return $previous;
  697.     }
  698.  
  699.     /**
  700.      * Searches for language directories within a certain base dir
  701.      *
  702.      * @access    public
  703.      * @param    string     $dir     directory of files
  704.      * @return    array    Array holding the found languages as filename => real name pairs
  705.      * @since    1.5
  706.      */
  707.     function _parseLanguageFiles($dir null)
  708.     {
  709.         jimport('joomla.filesystem.folder');
  710.  
  711.         $languages array ();
  712.  
  713.         $subdirs JFolder::folders($dir);
  714.         foreach ($subdirs as $path{
  715.             $langs JLanguage::_parseXMLLanguageFiles($dir.DS.$path);
  716.             $languages array_merge($languages$langs);
  717.         }
  718.  
  719.         return $languages;
  720.     }
  721.  
  722.     /**
  723.      * Parses XML files for language information
  724.      *
  725.      * @access    public
  726.      * @param    string    $dir     Directory of files
  727.      * @return    array    Array holding the found languages as filename => metadata array
  728.      * @since    1.5
  729.      */
  730.     function _parseXMLLanguageFiles($dir null)
  731.     {
  732.         if ($dir == null{
  733.             return null;
  734.         }
  735.  
  736.         $languages array ();
  737.         jimport('joomla.filesystem.folder');
  738.         $files JFolder::files($dir'^([-_A-Za-z]*)\.xml$');
  739.         foreach ($files as $file{
  740.             if ($content file_get_contents($dir.DS.$file)) {
  741.                 if ($metadata JLanguage::_parseXMLLanguageFile($dir.DS.$file)) {
  742.                     $lang str_replace('.xml'''$file);
  743.                     $languages[$lang$metadata;
  744.                 }
  745.             }
  746.         }
  747.         return $languages;
  748.     }
  749.  
  750.     /**
  751.      * Parse XML file for language information
  752.      *
  753.      * @access    public
  754.      * @param    string    $path     Path to the xml files
  755.      * @return    array    Array holding the found metadata as a key => value pair
  756.      * @since    1.5
  757.      */
  758.     function _parseXMLLanguageFile($path)
  759.     {
  760.         $xml JFactory::getXMLParser('Simple');
  761.  
  762.         // Load the file
  763.         if (!$xml || !$xml->loadFile($path)) {
  764.             return null;
  765.         }
  766.  
  767.         // Check that it's am metadata file
  768.         if (!$xml->document || $xml->document->name(!= 'metafile'{
  769.             return null;
  770.         }
  771.  
  772.         $metadata array ();
  773.  
  774.         //if ($xml->document->attributes('type') == 'language') {
  775.  
  776.             foreach ($xml->document->metadata[0]->children(as $child{
  777.                 $metadata[$child->name()$child->data();
  778.             }
  779.         //}
  780.         return $metadata;
  781.     }
  782. }

Documentation generated on Sat, 14 Nov 2009 11:15:25 +0000 by phpDocumentor 1.3.1