b2evolution

Multilingual multiuser multiblog engine

b2evolution Technical Documentation (0.9.x) [ class tree: evocore ] [ index: evocore ] [ all elements ]

Source for file _functions_locale.php

Documentation is available at _functions_locale.php

  1. <?php
  2. /**
  3.  * Handling of locales and i18n
  4.  *s
  5.  * b2evolution - {@link http://b2evolution.net/}
  6.  * Released under GNU GPL License - {@link http://b2evolution.net/about/license.html}
  7.  * @copyright (c)2003-2005 by Francois PLANQUE - {@link http://fplanque.net/}
  8.  *
  9.  * @package evocore
  10.  */
  11. if!defined('DB_USER') ) die'Please, do not access this page directly.' );
  12.  
  13.  
  14. /**
  15.  * TRANSLATE!
  16.  *
  17.  * Translate a text to the desired locale (b2evo localization only)
  18.  * or to the current locale
  19.  *
  20.  * {@internal T_(-)}}
  21.  *
  22.  * @param string String to translate, '' to get language file info (as in gettext spec)
  23.  * @param string locale to translate to, '' to use current locale (basic gettext does only support '')
  24.  */
  25. if( ($use_l10n == 1&& function_exists('_') )
  26. // We are going to use GETTEXT
  27.  
  28.     function T_$string$req_locale '' )
  29.     {
  30.         global $current_messages;
  31.  
  32.         ifempty$req_locale || $req_locale == $current_messages )
  33.         // We have not asked for a different locale than the currently active one:
  34.             return _($string);
  35.         }
  36.         // We have asked for a funky locale... we'll get english instead:
  37.         return $string;
  38.     }
  39.  
  40. }
  41. elseif$use_l10n == )
  42. // We are going to use b2evo localization:
  43.  
  44.     /**
  45.      * @ignore
  46.      */
  47.     function T_$string$req_locale '' )
  48.     {
  49.         global $trans$current_locale$locales;
  50.  
  51.         // By default we use the current locale:
  52.         ifempty($req_locale) ) $req_locale $current_locale;
  53.  
  54.         ifempty($req_locale) )
  55.             return $string;  // don't translate if we have no locale
  56.  
  57.         $messages $locales[$req_locale]['messages'];
  58.  
  59.         // replace special characters that to msgid-equivalents
  60.         $search str_replacearray("\n""\r""\t")array('\n''''\t')$string );
  61.  
  62.         // echo "Translating ", $search, " to $messages<br />";
  63.  
  64.         if!isset($trans$messages ) )
  65.         // Translations for current locale have not yet been loaded:
  66.             // echo 'LOADING', dirname(__FILE__). '/../locales/'. $messages. '/_global.php';
  67.             @include_once dirname(__FILE__)'/../locales/'$messages'/_global.php';
  68.             if!isset($trans$messages ) )
  69.             // Still not loaded... file doesn't exist, memorize that no translation are available
  70.                 // echo 'file not found!';
  71.                 $trans$messages array();
  72.             }
  73.         }
  74.  
  75.         ifisset$trans$messages ]$search ) )
  76.         // If the string has been translated:
  77.             return $trans$messages ]$search ];
  78.         }
  79.  
  80.         // echo "Not found!";
  81.  
  82.         // Return the English string:
  83.         return $string;
  84.     }
  85.  
  86. }
  87. else
  88. // We are not localizing at all:
  89.  
  90.     /**
  91.      * @ignore
  92.      */
  93.     function T_$string$req_locale '' )
  94.     {
  95.         return $string;
  96.     }
  97.  
  98. }
  99.  
  100.  
  101. /**
  102.  * NT_(-)
  103.  *
  104.  * No Translation
  105.  * Nevertheless, the string will be extracted by the gettext tools
  106.  */
  107. function NT_$string )
  108. {
  109.     return $string;
  110. }
  111.  
  112.  
  113. /**
  114.  * Temporarily switch to another locale
  115.  *
  116.  * Calls can be nested.
  117.  *
  118.  * {@internal locale_temp_switch(-)}}
  119.  *
  120.  * @param string locale to activate
  121.  */
  122. function locale_temp_switch$locale )
  123. {
  124.     global $saved_locale$current_locale;
  125.     if!isset$saved_locale ) ) $saved_locale array();
  126.     array_push$saved_locale$current_locale );
  127.     locale_activate$locale );
  128. }
  129.  
  130.  
  131. /**
  132.  * Restore the locale in use before the switch
  133.  *
  134.  * {@internal locale_restore_previous(-)}}
  135.  */
  136. {
  137.     global $saved_locale;
  138.     $locale array_pop$saved_locale );
  139.     locale_activate$locale );
  140. }
  141.  
  142.  
  143. /**
  144.  * locale_activate(-)
  145.  *
  146.  * returns true if locale has been changed
  147.  *
  148.  * @param string locale to activate
  149.  */
  150. function locale_activate$locale )
  151. {
  152.     global $use_l10n$locales$current_locale$current_messages$current_charset$weekday$month;
  153.  
  154.     if$locale == $current_locale || empty$locale ) )
  155.     {
  156.         return false;
  157.     }
  158.  
  159.     // Memorize new locale:
  160.     $current_locale $locale;
  161.     // Memorize new charset:
  162.     $current_charset $locales$locale ]'charset' ];
  163.     $current_messages $locales$locale ]'messages' ];
  164.  
  165.     // Activate translations in gettext:
  166.     if( ($use_l10n == 1&& function_exists'bindtextdomain' ) )
  167.     // Only if we are using GETTEXT ( if not, look into T_(-) ...)
  168.         # Activate the locale->language in gettext:
  169.  
  170.         // Note: default of safe_mode_allowed_env_vars is "PHP_ ",
  171.         // so you need to add "LC_" by editing php.ini.
  172.         putenv('LC_ALL='.$current_messages);
  173.  
  174.         // Specify location of translation tables and bind to domain
  175.         bindtextdomain'messages'dirname(__FILE__).'/../locales' );
  176.         textdomain('messages');
  177.  
  178.         # Activate the charset for conversions in gettext:
  179.         iffunction_exists'bind_textdomain_codeset' ) )
  180.         // Only if this gettext supports code conversions
  181.             bind_textdomain_codeset'messages'$current_charset );
  182.         }
  183.     }
  184.  
  185.     # Set locale for default language:
  186.     # This will influence the way numbers are displayed, etc.
  187.     // We are not using this right now, the default 'C' locale seems just fine
  188.     // setlocale( LC_ALL, $locale );
  189.  
  190.     # Use this to check locale: (not relevant)
  191.     // echo setlocale( LC_ALL, 0 );
  192.  
  193.     return true;
  194. }
  195.  
  196.  
  197. /**
  198.  * locale_by_lang(-)
  199.  *
  200.  * Find first locale matching lang
  201.  */
  202. function locale_by_lang$lang$fallback_to_default true )
  203. {
  204.     global $locales$default_locale;
  205.  
  206.     foreach$locales as $locale => $locale_params )
  207.     {
  208.         ifsubstr$locale,== $lang )
  209.         // found first matching locale
  210.             return $locale;
  211.         }
  212.     }
  213.  
  214.     // Not found...
  215.     if$fallback_to_default )
  216.         return $default_locale;
  217.     else
  218.         return $lang;
  219. }
  220.  
  221.  
  222. /**
  223.  * Displays/Returns the current locale. (for backward compatibility)
  224.  *
  225.  * {@internal locale_lang(-)}}
  226.  *
  227.  * @param boolean true (default) if we want it to be outputted
  228.  * @return string current locale, if $disp = false
  229.  */
  230. function locale_lang$disp true )
  231. {
  232.     global $current_locale;
  233.  
  234.     if$disp )
  235.         echo $current_locale;
  236.     else
  237.         return $current_locale;
  238. }
  239.  
  240.  
  241. /**
  242.  * Returns the charset of the current locale
  243.  *
  244.  * {@internal locale_charset(-)}}
  245.  */
  246. function locale_charset$disp true )
  247. {
  248.     global $current_charset;
  249.  
  250.     if$disp )
  251.         echo $current_charset;
  252.     else
  253.         return $current_charset;
  254. }
  255.  
  256.  
  257. /**
  258.  * Returns the current locale's default date format
  259.  *
  260.  * {@internal locale_datefmt(-)}}
  261.  */
  262. function locale_datefmt()
  263. {
  264.     global $locales$current_locale;
  265.  
  266.     return $locales[$current_locale]['datefmt'];
  267. }
  268.  
  269.  
  270. /**
  271.  * Returns the current locale's default time format
  272.  *
  273.  * {@internal locale_timefmt(-)}}
  274.  */
  275. function locale_timefmt()
  276. {
  277.     global $locales$current_locale;
  278.  
  279.     return $locales[$current_locale]['timefmt'];
  280. }
  281.  
  282.  
  283. /**
  284.  * Template function: Display locale flag
  285.  *
  286.  * {@internal locale_flag(-)}}
  287.  *
  288.  * @param string locale to use, '' for current
  289.  * @param string collection name (subdir of img/flags)
  290.  * @param string name of class for IMG tag
  291.  * @param string deprecated HTML align attribute
  292.  * @param boolean to echo or not
  293.  * @param mixed use absolute url (===true) or path to flags directory
  294.  */
  295. function locale_flag$locale ''$collection 'w16px'$class 'flag'$align ''$disp true$absoluteurl true )
  296. {
  297.     global $locales$current_locale$core_dirout$img_subdir$img_url;
  298.  
  299.     ifempty($locale) ) $locale $current_locale;
  300.  
  301.     // extract flag name:
  302.     $country strtolower(substr$locale3));
  303.  
  304.     ifis_file(dirname(__FILE__).'/'.$core_dirout.'/'.$img_subdir.'/flags/'.$collection.'/'.$country.'.gif') )
  305.     // File does not exist
  306.         $country 'default';
  307.     }
  308.  
  309.     if$absoluteurl !== true )
  310.     {
  311.         $iurl $absoluteurl;
  312.     }
  313.     else
  314.     {
  315.         $iurl $img_url.'/flags';
  316.     }
  317.  
  318.     $r '<img src="'.$iurl.'/'.$collection.'/'.$country.'.gif" alt="' .
  319.                 (isset($locales[$locale]['name']$locales[$locale]['name'$locale.
  320.                 '"';
  321.     if!empty$class ) ) $r .= ' class="'.$class.'"';
  322.     if!empty$align ) ) $r .= ' align="'.$align.'"';
  323.     $r .= ' /> ';
  324.  
  325.     if$disp )
  326.         echo $r;   // echo it
  327.     else
  328.         return $r// return it
  329.  
  330. }
  331.  
  332.  
  333. /*
  334.  * locale_options(-)
  335.  *
  336.  *    Outputs a <option> set with default locale selected
  337.  *
  338.  * was: lang_options(-)
  339.  *
  340.  */
  341. function locale_options$default '' )
  342. {
  343.     global $locales$default_locale;
  344.  
  345.     ifempty$default ) ) $default $default_locale;
  346.  
  347.  
  348.     foreach$locales as $this_localekey => $this_locale )
  349.         if$this_locale['enabled'|| $this_localekey == $default )
  350.         {
  351.             echo '<option value="'$this_localekey'"';
  352.             if$this_localekey == $default echo ' selected="selected"';
  353.             echo '>'T_($this_locale['name'])'</option>';
  354.         }
  355.  
  356. }
  357.  
  358.  
  359. /**
  360.  * Detect language from HTTP_ACCEPT_LANGUAGE
  361.  *
  362.  * First matched full locale code in HTTP_ACCEPT_LANGUAGE will win
  363.  * Otherwise, first locale in table matching a lang code will win
  364.  *
  365.  * {@internal locale_from_httpaccept(-)}}
  366.  *
  367.  * @return locale made out of HTTP_ACCEPT_LANGUAGE or $default_locale, if no match
  368.  */
  369. {
  370.     global $locales$default_locale;
  371.     ifisset($_SERVER['HTTP_ACCEPT_LANGUAGE']) )
  372.     {
  373.         // echo $_SERVER['HTTP_ACCEPT_LANGUAGE'];
  374.         $accept strtolower$_SERVER['HTTP_ACCEPT_LANGUAGE');
  375.         // pre_dump($accept, 'http_accept_language');
  376.         $selected_locale '';
  377.         $selected_match_pos 10000;
  378.         $selected_full_match false;
  379.  
  380.         foreach$locales as $localekey => $locale )
  381.         // Check each locale
  382.             if$locale['enabled')
  383.             // We only want to use activated locales
  384.                 continue;
  385.             }
  386.             // echo '<br />searching ', $localekey, ' in HTTP_ACCEPT_LANGUAGE ';
  387.             if( ($pos strpos$acceptstrtolower($localekey) )) !== false )
  388.             // We found full locale
  389.                 if!$selected_full_match || ($pos <= $selected_match_pos) )
  390.                 // This is a better choice than what we had before OR EQUIVALENT but with exact locale
  391.                     // echo $localekey.' @ '.$pos.' is better than '.
  392.                     //        $selected_locale.' @ '.$selected_match_pos.'<br />';
  393.                     $selected_locale $localekey;
  394.                     $selected_match_pos $pos;
  395.                     $selected_full_match true;
  396.                 }
  397.                 // else echo $localekey.' @ '.$pos.' is not better than '.
  398.                 //                    $selected_locale.' @ '.$selected_match_pos.'<br />';
  399.             }
  400.  
  401.             if!$selected_full_match && ($pos strpos$acceptsubstr($localekey02) )) !== false )
  402.             // We have no exact match yet but found lang code match
  403.                 if$pos $selected_match_pos )
  404.                 // This is a better choice than what we had before
  405.                     // echo $localekey.' @ '.$pos.' is better than '.
  406.                     //        $selected_locale.' @ '.$selected_match_pos.'<br />';
  407.                     $selected_locale $localekey;
  408.                     $selected_match_pos $pos;
  409.                 }
  410.                 // else echo $localekey.' @ '.$pos.' is not better than '.
  411.                 //                    $selected_locale.' @ '.$selected_match_pos.'<br />';
  412.             }
  413.         }
  414.  
  415.         if!empty($selected_locale) )
  416.         {
  417.             return $selected_locale;
  418.         }
  419.     }
  420.     return $default_locale;
  421. }
  422.  
  423.  
  424. /**
  425.  * user sort function to sort locales by priority
  426.  *
  427.  * 1 is highest priority.
  428.  *
  429.  */
  430. function locale_priosort$a$b )
  431. {
  432.     return $a['priority'$b['priority'];
  433. }
  434.  
  435.  
  436. /**
  437.  * load locales from DB into $locales array. Also sets $default_locale.
  438.  *
  439.  */
  440. {
  441.     global $DB$locales$default_locale$Settings;
  442.  
  443.     $usedprios array();  // remember which priorities are used already.
  444.     $priocounter 0;
  445.     $query 'SELECT
  446.                         loc_locale, loc_charset, loc_datefmt, loc_timefmt, loc_name,
  447.                         loc_messages, loc_priority, loc_enabled
  448.                         FROM T_locales ORDER BY loc_priority';
  449.     $rows $DB->get_results$queryARRAY_A );
  450.  
  451.     ifcount$rows ) ) foreach$rows as $row )
  452.     // Loop through loaded locales:
  453.  
  454.         if$row['loc_priority'== $priocounter )
  455.         // priority conflict (the same)
  456.             $priocounter++;
  457.         }
  458.         else
  459.         {
  460.             $priocounter $row['loc_priority'];
  461.         }
  462.  
  463.         //remember that we used this
  464.         $usedprios[$priocounter;
  465.  
  466.         $locales$row['loc_locale'] ] array(
  467.                                                                             'charset'  => $row'loc_charset' ],
  468.                                                                             'datefmt'  => $row'loc_datefmt' ],
  469.                                                                             'timefmt'  => $row'loc_timefmt' ],
  470.                                                                             'name'     => $row'loc_name' ],
  471.                                                                             'messages' => $row'loc_messages' ],
  472.                                                                             'priority' => $priocounter,
  473.                                                                             'enabled'  => $row'loc_enabled' ],
  474.                                                                             'fromdb'   => 1
  475.                                                                         );
  476.     }
  477.  
  478.     // set default priorities, if nothing was set in DB.
  479.     // Missing "priority gaps" will get filled here.
  480.     ifcount($rows!= count($locales) )
  481.     // we have locales from conf file that need a priority
  482.         $priocounter 1;
  483.         foreach$locales as $lkey => $lval )
  484.         // Loop through memory locales:
  485.             if!isset($lval['priority']) )
  486.             // Found one that has no assigned priority
  487.                 whilein_array$priocounter$usedprios ) )
  488.                 {
  489.                     $priocounter++;
  490.                 }
  491.                 // Priocounter has max value
  492.                 $locales[$lkey]['priority'$priocounter;
  493.                 $usedprios[$priocounter;
  494.             }
  495.         }
  496.     }
  497.  
  498.     // sort by priority
  499.     uasort$locales'locale_priosort' );
  500.  
  501.     // overwrite default_locale from DB settings - if enabled.
  502.     // Checks also if previous $default_locale is enabled. Defaults to en-EU, even if not enabled.
  503.     $locale_fromdb $Settings->get('default_locale');
  504.  
  505.     if$locale_fromdb  )
  506.     {
  507.         /*
  508.         if( $locales[$locale_fromdb]['enabled'] )
  509.             $default_locale = $locale_fromdb;
  510.         elseif( !$locales[$default_locale]['enabled'] )
  511.             $default_locale = 'en-EU';
  512.         */
  513.         $default_locale $locale_fromdb;
  514.     }
  515. }
  516.  
  517.  
  518. /**
  519.  * write $locales array to DB table
  520.  *
  521.  * @author blueyed
  522.  */
  523. function locale_updateDB()
  524. {
  525.     global $locales$DB;
  526.  
  527.     $templocales $locales;
  528.  
  529.     $lnr 0;
  530.     foreach$_POST as $pkey => $pval ifpreg_match('/loc_(\d+)_(.*)/'$pkey$matches) )
  531.     {
  532.         $lfield $matches[2];
  533.  
  534.         if$matches[1!= $lnr )
  535.         // we have a new locale
  536.             $lnr $matches[1];
  537.             $plocale $pval;
  538.  
  539.             // checkboxes default to 0
  540.             $templocales$plocale ]['enabled'0;
  541.         }
  542.         elseif$lnr != )  // be sure to have catched a locale before
  543.         {
  544.             $templocales$plocale ][$lfieldremove_magic_quotes$pval );
  545.         }
  546.  
  547.     }
  548.  
  549.     $locales $templocales;
  550.  
  551.     $query "REPLACE INTO T_locales ( loc_locale, loc_charset, loc_datefmt, loc_timefmt, loc_name, loc_messages, loc_priority, loc_enabled ) VALUES ";
  552.     foreach$locales as $localekey => $lval )
  553.     {
  554.         ifempty($lval['messages']) )
  555.         // if not explicit messages file is given we'll translate the locale
  556.             $lval['messages'strtr($localekey'-''_');
  557.         }
  558.         $query .= "(
  559.         '$localekey',
  560.         '{$lval['charset']}',
  561.         '{$lval['datefmt']}',
  562.         '{$lval['timefmt']}',
  563.         '{$lval['name']}',
  564.         '{$lval['messages']}',
  565.         '{$lval['priority']}',
  566.         '{$lval['enabled']}'
  567.         ), ";
  568.     }
  569.     $query substr($query0-2);
  570.     $q $DB->query($query);
  571.  
  572.     return (bool)$q;
  573. }
  574. ?>

Documentation generated on Tue, 20 May 2008 01:54:58 +0200 by phpDocumentor 1.4.2