Skip to content
i18n.module 9.64 KiB
Newer Older
<?php
// $Id$
/**
 * Internationalization (i18n) module
 *
 * @author Jose A. Reyero, 2004
Jose Antonio Reyero del Prado's avatar
Jose Antonio Reyero del Prado committed
 * Module initialization
 * 
 * Get language from path if exists and Initialize i18n system
 * May do a redirect from home page for not to get wrong versions in cache
  global $i18n_langpath;
  // Some functions only to be included when module is enabled

  $path = _i18n_get_original_path();
  $i18n_langpath = i18n_get_lang_prefix($path);
  $lang = _i18n_get_lang();
  if ($path == '') { // Main page
    // Check for update script
    if (isset($_GET['op'])) {
      return ;
    }
    if( variable_get('cache',0) && $lang != i18n_default_language() ) {
      // Redirect to main page in $lang
      _i18n_goto($lang);
    } elseif (variable_get('i18n_frontpage',0)){
      $_GET['q'] = i18n_frontpage();
    } 
  } 
  elseif ($lang == $path) { // When path is only language code
    $_GET['q'] =  variable_get('i18n_frontpage',0) ? i18n_frontpage() : variable_get('site_frontpage','node'); 
  elseif ($i18n_langpath) {
    //search alias with and without lang and remove lang
    $_GET['q'] = i18n_get_normal_path($path);
  } 
Jose Antonio Reyero del Prado's avatar
Jose Antonio Reyero del Prado committed
  // Multi table, for backwards compatibility and experimentation
  if (variable_get('i18n_multi' , 0)) {
    _i18n_set_db_prefix(_i18n_get_lang());
  // If not in bootstrap, include hooks
    include 'modules/i18n/i18n.inc';
    i18n_variable_init();    
Jose Antonio Reyero del Prado's avatar
Jose Antonio Reyero del Prado committed
/**
 *  Common module functions
 */

/**
 * Implementation of hook_help().
 */
Jose Antonio Reyero del Prado's avatar
Jose Antonio Reyero del Prado committed
function i18n_help($section = 'admin/help#i18n' ) {
  switch ($section) {
Jose Antonio Reyero del Prado's avatar
Jose Antonio Reyero del Prado committed
    case 'admin/help#i18n' :
      $output = t('
        <p>This module provides support for internationalization of Drupal sites:</p>
        <ul>
        <li>Translation of the user interface for anonymous users (combined with locale)</li>
        <li>Multi-language for content. Adds a language field for nodes and taxonomy vocabularies and terms</li>
Jose Antonio Reyero del Prado's avatar
Jose Antonio Reyero del Prado committed
        <li>Basic translation management</li>
        <li>Browser language detection</li>
        <li>Keeps the language setting accross consecutive requests using URL rewriting</li>
        <li>Provides a block for language selection and two theme functions: <i>i18n_flags</i> and <i>i18n_links</i></li>
        <li>Support for long locale names</li>
        </ul>
        <p><small>Module developed by Jose A. Reyero, <a href="http://www.reyero.net">www.reyero.net</a></small></p>' );
Jose Antonio Reyero del Prado's avatar
Jose Antonio Reyero del Prado committed
  case 'admin/modules#description' :
    $output = t('Enables multilingual content. <b>Requires locale module for interface translation</b>' );
    break;
  }
  return $output;
}

/**
 * Implementation of hook_settings().
 */
Jose Antonio Reyero del Prado's avatar
Jose Antonio Reyero del Prado committed
function i18n_settings() {
  global $db_prefix_i18n;
  // Basic settings
  $config_languages = is_array($i18n_languages) ? implode(', ',$i18n_languages) : 'Not defined';
  $output .= form_radios(t('Supported languages'), 'i18n_supported_langs' , variable_get('i18n_supported_langs', 'locale'), 
    array(
      'locale' => t('Defined by the locale module'),
      'i18n'  => t('Defined in the configuration file (%config_languages)', array('%config_languages' => $config_languages))
Jose Antonio Reyero del Prado's avatar
Jose Antonio Reyero del Prado committed
    ), t('Where to get the list of supported languages from' ));
  $output .= form_radios(t('Browser language detection'), 'i18n_browser', variable_get('i18n_browser', 0), array(t('Disabled'), t('Enabled' )));
  $output .= form_select(t('Front page'), 'i18n_frontpage', variable_get('i18n_frontpage', 0), array(t('Default'), t('Language dependent')), t(" If 'language dependent' is selected, default front page will be prepended with language code, i.e. 'en/node'"));
  /*
  $output .= form_textfield(t('Language icons html tag'), 'i18n_flags', variable_get('i18n_flags', '<img class="i18n-flag" src="modules/i18n/flags/*.png" width="16" height="12" alt="Language Flag" />'), 70, 180, 
    t('HTML tag for flags. Asterisk \'*\' is a placeholder for language code. It should be something like &lt;img class="i18n-flag" src="modules/i18n/flags/*.png" width="16" height="12"/&gt'));
  */
  $output .= form_textfield(t('Language icons path'), 'i18n_flags_path', variable_get('i18n_flags_path', 'modules/i18n/flags/*.png'), 70, 180, 
    t('Path for language icons, relative to Drupal installation. \'*\' is a placeholder for language code.'));
  $output .= form_textfield(t('Language icons sixe'), 'i18n_flags_size', variable_get('i18n_flags_size', '16x12'), 10, 10, 
    t('Image size for language icons, in the form "width x height".'));
  
Jose Antonio Reyero del Prado's avatar
Jose Antonio Reyero del Prado committed
  $output .= t('<h2>Multilingual content</h2>' );
  foreach (node_list() as $node) {
    $subform.=form_checkbox(t($node), 'i18n_node_'.$node, 1, variable_get('i18n_node_'.$node, 0));
  }   
  $output .= form_group(t('Nodes' ), $subform, t('Select node types to be translated.' ));
  
  $output .= t('<h2>Advanced Features</h2>' );
  $output .= t('<p>These are intended only for advanced users. Some changes to the database are required. Please, do read the INSTALL.txt and README.txt files before enabling these options</p>' );
Jose Antonio Reyero del Prado's avatar
Jose Antonio Reyero del Prado committed

  // Advanced features
  // Language dependent tables
Jose Antonio Reyero del Prado's avatar
Jose Antonio Reyero del Prado committed
  if (is_array($db_prefix_i18n)) {
    $multi=true;
Jose Antonio Reyero del Prado's avatar
Jose Antonio Reyero del Prado committed
    $text = '<strong>'.t('Current language dependent tables are: '). implode(', ', array_keys($db_prefix_i18n)).'</strong>' ;
  }  else {
Jose Antonio Reyero del Prado's avatar
Jose Antonio Reyero del Prado committed
    $text = t("Check the module's SETUP.txt file.");
Jose Antonio Reyero del Prado's avatar
Jose Antonio Reyero del Prado committed
  $output .= form_radios(t('Language dependent tables'), 'i18n_multi', variable_get('i18n_multi', 0), array(t('Disabled'), t('Enabled')), t('If enabled, different tables for each language will be used. They must be defined in the configuration file.') . ' ' . $text);
  return $output;
}

/**
 * i18n api
 */
Jose Antonio Reyero del Prado's avatar
Jose Antonio Reyero del Prado committed
 * Get list of supported languages
Jose Antonio Reyero del Prado's avatar
Jose Antonio Reyero del Prado committed
function i18n_supported_languages() {
Jose Antonio Reyero del Prado's avatar
Jose Antonio Reyero del Prado committed
  static $languages;
  if ($languages) {
    return $languages;
  elseif (variable_get('i18n_supported_langs', 'locale') == 'locale') {
    $languages = _i18n_locale_supported_languages();
Jose Antonio Reyero del Prado's avatar
Jose Antonio Reyero del Prado committed
    return $languages;
  } 
  elseif (is_array($i18n_languages)) {
    return $languages = $i18n_languages;
  } 
Jose Antonio Reyero del Prado's avatar
Jose Antonio Reyero del Prado committed
    return array();
/**
 * Returns default language
 */
function i18n_default_language(){
  return key(i18n_supported_languages());
}

// Get language from browser settings, but only if it is in the $i18n_languages array
Jose Antonio Reyero del Prado's avatar
Jose Antonio Reyero del Prado committed
function i18n_get_browser_lang() {
  $languages = i18n_supported_languages();
Jose Antonio Reyero del Prado's avatar
Jose Antonio Reyero del Prado committed
  $accept=explode(',',array_shift( explode(";",$_SERVER["HTTP_ACCEPT_LANGUAGE"])));
  foreach ($accept as $lang) {
    if ( !empty($lang) && array_key_exists($lang,$languages)) {
Jose Antonio Reyero del Prado's avatar
Jose Antonio Reyero del Prado committed
      return $lang;
    }
Jose Antonio Reyero del Prado's avatar
Jose Antonio Reyero del Prado committed
 * Get language code from path.
 * @param $path
 * @param $trim true to remove language code from $path
function i18n_get_lang_prefix(&$path, $trim = false) {
  $maybelang = array_shift(explode('/',$path));
  $languages = i18n_supported_languages();
  if(array_key_exists($maybelang, $languages)){
    if($trim) {
      $path = trim(substr($path, strlen($maybelang)),'/');
    }
    return $maybelang;
  }
  /*
Jose Antonio Reyero del Prado's avatar
Jose Antonio Reyero del Prado committed
  if (preg_match("/^\w\w($|\/.*)/", $path)) {
    return substr($path, 0, 2);
Jose Antonio Reyero del Prado's avatar
Jose Antonio Reyero del Prado committed
 * Language dependent front page
Jose Antonio Reyero del Prado's avatar
Jose Antonio Reyero del Prado committed
function i18n_frontpage() {
  $path = _i18n_get_lang().'/'.variable_get('site_frontpage','node');
Jose Antonio Reyero del Prado's avatar
Jose Antonio Reyero del Prado committed
  return i18n_get_normal_path($path);
Jose Antonio Reyero del Prado's avatar
Jose Antonio Reyero del Prado committed
 * This function is similar to drupal_get_normal_path, but language-aware
 * Also removes language from path
 */
function i18n_get_normal_path($path) {
  // First, check alias with lang, then without
  if ($path != ($alias = drupal_lookup_path('alias', $path))) {
    return $alias;
  } elseif(i18n_get_lang_prefix($path, TRUE)){
    $alias = drupal_lookup_path('alias', $path);
    if( $alias && $path != $alias) {
      return $alias;
    }
Jose Antonio Reyero del Prado's avatar
Jose Antonio Reyero del Prado committed
  } 
  // We only get here when no alias is defined, with or without lang
  return $path;
/**
 *	Gets language, checking in order:
 *
 *	1. Path language
 *	2. User language
 *	3. Browser language
 *	4. Default language
 */

function _i18n_get_lang() {
  global $user, $i18n_langpath;
  static $i18n_lang;
  
  //see if the language is already set.
  if ($i18n_lang) {
    return $i18n_lang;
  }

  $languages = i18n_supported_languages();
   
  if ($i18n_langpath && array_key_exists($i18n_langpath,$languages)) {
    $i18n_lang = $i18n_langpath;
  }
  elseif ($user->uid && $user->language && array_key_exists($user->language,$languages)) {
    $i18n_lang = $user->language;
  }
  elseif (variable_get("i18n_browser",0) && $lang=i18n_get_browser_lang()) {
    $i18n_lang=$lang;
  }
  else {
    $i18n_lang=key($languages);
  }
  
  return $i18n_lang;
}

/**
 * Check whether we are in bootstrap mode
 */  
function _i18n_is_bootstrap(){
  return !function_exists('drupal_get_headers');
}    

/**
 * Sets db_prefix to given language
 */
function _i18n_set_db_prefix($lang) {
  global $db_prefix, $db_prefix_i18n;
  if (is_array($db_prefix_i18n)) {
    $db_prefix = array_merge($db_prefix, str_replace('**', $lang, $db_prefix_i18n));
  }
}

/**
 * To get the original path. 
 * Cannot use $_GET["q"] cause it may have been already changed
 */
function _i18n_get_original_path() {
  return isset($_REQUEST["q"]) ? trim($_REQUEST["q"],"/") : '';
}


/**
 * Returns list of enabled languages from locale module
 *
 * * Some code borrowed from locale module
 */
function _i18n_locale_supported_languages() {
  $enabled = array();
  $result = db_query('SELECT locale, name FROM {locales_meta} WHERE enabled = 1 ORDER BY isdefault DESC, name ASC');
  while ($row = db_fetch_object($result)) {
    $enabled[$row->locale] = $row->name;
  }
  return $enabled;
}
/**
 * Emulates drupal_goto, it may not be loaded yet
 */
function _i18n_goto($lang){
  if(!function_exists('drupal_goto')){
    require_once './includes/common.inc';    
  }
  drupal_goto($lang);
}