6.x-1.x branch
Internationalization (i18n) module.
This module extends multilingual support being the base module for the i18n package.
@author Jose A. Reyero, 2004
| Name | Description |
|---|---|
| i18n_array_variable_get | Utility. Get part of array variable. |
| i18n_array_variable_set | Utility. Set part of array variable. |
| i18n_boot | Implementation of hook_boot() |
| i18n_db_rewrite_sql | Implementation of hook_db_rewrite_sql(). |
| i18n_db_rewrite_where | Rewrites queries depending on rewriting mode. |
| i18n_default_language | Returns default language code. |
| i18n_elements | Implementation of hook_elements(). |
| i18n_exit | Implementation of hook_exit(). |
| i18n_form_alter | Implementation of hook_form_alter(); |
| i18n_form_alter_settings | Check for multilingual variables in form. |
| i18n_get_lang | This one expects to be called first from common.inc |
| i18n_help | Implementation of hook_help(). |
| i18n_init | Implementation of hook_init(). |
| i18n_language_list | Returns language lists. |
| i18n_language_property | Get language properties. |
| i18n_link_alter | Implementation of hook_link_alter(). |
| i18n_menu | Implementation of hook_menu(). |
| i18n_menu_alter | Implementation of hook_menu_alter(). |
| i18n_menu_edit_item_form_submit | Process menu and menu item add/edit form submissions. |
| i18n_nodeapi | Implementation of hook_nodeapi(). |
| i18n_node_get_lang | Get node language. |
| i18n_node_language_list | Get allowed languages for node. |
| i18n_perm | Implementation of hook_perm(). |
| i18n_preprocess_page | Implementation of hook_preprocess_page(). |
| i18n_selection_mode | Selection mode for content. |
| i18n_supported_languages | Get list of supported languages, native name. |
| i18n_textfield_process | Process callback for textfield elements. |
| i18n_theme | Implementation of hook_theme(). |
| i18n_translation_link_alter | Implementation of hook_alter_translation_link(). |
| i18n_user | Implementation of hook_user(). |
| i18n_variable | Get list of multilingual variables or check whether a variable is multilingual |
| i18n_variable_del | Unset a persistent multilingual variable. |
| i18n_variable_form_submit | Save multilingual variables and remove them from form. |
| i18n_variable_get | Get single multilingual variable |
| i18n_variable_init | Initialization of multilingual variables. |
| i18n_variable_set | Set a persistent language dependent variable. |
| _i18n_content_language_options | List of language support modes for content. |
| _i18n_get_context_lang | Get language from context. |
| _i18n_init | Initialize multilingual variables and use them for site_frontpage |
| _i18n_init_mode | Initialize selection mode |
| _i18n_is_bootstrap | Check whether we are in bootstrap mode. |
| _i18n_language_select | Helper function to create language selector. |
| _i18n_variable_exit | Save multilingual variables that may have been changed by other methods than settings pages. |
| _i18n_variable_init | Load language variables into array. |
| Name | Description |
|---|---|
| LANGUAGE_SUPPORT_EXTENDED | |
| LANGUAGE_SUPPORT_EXTENDED_NOT_DISPLAYED | |
| LANGUAGE_SUPPORT_NONE | |
| LANGUAGE_SUPPORT_NORMAL |
- <?php
-
- /**
- * @file
- * Internationalization (i18n) module.
- *
- * This module extends multilingual support being the base module for the i18n package.
- * - Multilingual variables
- * - Extended languages for nodes
- * - Extended language API
- *
- * @author Jose A. Reyero, 2004
- */
-
- // Some constants. Language support modes for content
- define('LANGUAGE_SUPPORT_NONE', 0);
- define('LANGUAGE_SUPPORT_NORMAL', 1);
- define('LANGUAGE_SUPPORT_EXTENDED', 2);
- define('LANGUAGE_SUPPORT_EXTENDED_NOT_DISPLAYED', 3);
-
- /**
- * Implementation of hook_boot()
- *
- * Initialize variables, that will be used to decide on site_frontpage
- */
- function i18n_boot() {
- drupal_bootstrap(DRUPAL_BOOTSTRAP_LANGUAGE);
- _i18n_init();
- }
-
- /**
- * Implementation of hook_init().
- *
- * Special fix for site_frontpage, that may have been used before the language variables are loaded.
- */
- function i18n_init() {
- // If not in bootstrap, variable init. Otherwise we are serving a cached page so we don't need anything else.
- if (!_i18n_is_bootstrap()) {
- _i18n_init(TRUE);
- _i18n_init_mode();
- }
- }
-
- /**
- * Initialize multilingual variables and use them for site_frontpage
- *
- * Special fix for site_frontpage, that may have been used before the language variables are loaded.
- */
- function _i18n_init($check_frontpage = FALSE) {
- static $done, $default_frontpage;
-
- // Prevent this function from running twice;
- if (!isset($done)) {
- $done = TRUE;
- $default_frontpage = variable_get('site_frontpage', 'node');
- i18n_variable_init();
- }
- // We do aditional frontpage check if this has run after first bootstrap phase.
- // But if this runs in hook_boot we should be ok
- if ($check_frontpage && $default_frontpage != variable_get('site_frontpage', 'node') && $_GET['q'] == drupal_get_normal_path($default_frontpage)) {
- $_GET['q'] = drupal_get_normal_path(variable_get('site_frontpage', 'node'));
- }
- }
-
- /**
- * Initialize selection mode
- */
- function _i18n_init_mode() {
- if (i18n_selection_mode() != 'off') {
- // Node language when loading specific nodes or creating translations.
- if (arg(0) == 'node' ) {
- // We shouldn't call menu_get_object() because it may end up calling i18n_selection_mode(), see #614548
- // Also we better don't do the full node loading here because there may be missing modules (init)
- if (is_numeric(arg(1)) && (arg(2) == 'edit') && ($lang = i18n_node_get_lang(arg(1)))) {
- i18n_selection_mode('node', $lang);
- }
- elseif (arg(1) == 'add' && !empty($_GET['translation']) && !empty($_GET['language'])) {
- i18n_selection_mode('translation', db_escape_string($_GET['language']));
- }
- }
- elseif (arg(0) == 'admin') {
- // There are some exceptions for admin pages.
- if (arg(1) == 'content' && user_access('administer all languages')) {
- // No restrictions for administration pages.
- i18n_selection_mode('off');
- }
- elseif (arg(1) == 'build' && (arg(2) == 'menu-customize' || arg(2) == 'menu')) {
- // All nodes available when editing custom menu items.
- i18n_selection_mode('off');
- }
- }
- }
- }
- /**
- * Implementation of hook_help().
- */
- function i18n_help($path = 'admin/help#i18n', $arg) {
- switch ($path) {
- case 'admin/help#i18n' :
- $output = '<p>'. t('This module improves support for multilingual content in Drupal sites:') .'</p>';
- $output .= '<ul>';
- $output .= '<li>'. t('Shows content depending on page language.') .'</li>';
- $output .= '<li>'. t('Handles multilingual variables.') .'</li>';
- $output .= '<li>'. t('Extended language option for chosen content types. For these content types transations will be allowed for all defined languages, not only for enabled ones.') .'</li>';
- $output .= '<li>'. t('Provides a block for language selection and two theme functions: <em>i18n_flags</em> and <em>i18n_links</em>.') .'</li>';
- $output .= '</ul>';
- $output .= '<p>'. t('This is the base module for several others adding different features:') .'</p>';
- $output .= '<ul>';
- $output .= '<li>'. t('Multilingual menu items.') .'</li>';
- $output .= '<li>'. t('Multilingual taxonomy adds a language field for taxonomy vocabularies and terms.') .'</li>';
- $output .= '</ul>';
- $output .= '<p>'. t('For more information, see the online handbook entry for <a href="@i18n">Internationalization module</a>.', array('@i18n' => 'http://drupal.org/node/133977')) .'</p>';
- return $output;
-
- case 'admin/settings/language/i18n':
- $output = '<ul>';
- $output .= '<li>'. t('To enable multilingual support for specific content types go to <a href="@configure_content_types">configure content types</a>.', array('@configure_content_types' => url('admin/content/types'))) .'</li>';
- $output .= '</ul>';
- return $output;
- }
- }
-
- /**
- * Implementation of hook_menu().
- */
- function i18n_menu() {
- $items['admin/settings/language/i18n'] = array(
- 'title' => 'Multilingual system',
- 'description' => 'Configure extended options for multilingual content and translations.',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('i18n_admin_settings'),
- 'access arguments' => array('administer site configuration'),
- 'file' => 'i18n.admin.inc',
- 'type' => MENU_LOCAL_TASK,
- 'weight' => 10,
- );
- $items['admin/settings/language/i18n/configure'] = array(
- 'title' => 'Options',
- 'description' => 'Configure extended options for multilingual content and translations.',
- //'page callback' => 'drupal_get_form',
- //'page arguments' => array('i18n_admin_settings'),
- //'access arguments' => array('administer site configuration'),
- 'file' => 'i18n.admin.inc',
- 'type' => MENU_DEFAULT_LOCAL_TASK,
- );
- $items['admin/settings/language/i18n/variables'] = array(
- 'title' => 'Variables',
- 'description' => 'Multilingual variables.',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('i18n_admin_variables_form'),
- 'access arguments' => array('administer site configuration'),
- 'file' => 'i18n.admin.inc',
- 'type' => MENU_LOCAL_TASK,
- );
- // Autocomplete callback for nodes
- $items['i18n/node/autocomplete'] = array(
- 'title' => 'Node title autocomplete',
- 'page callback' => 'i18n_node_autocomplete',
- 'access arguments' => array('access content'),
- 'type' => MENU_CALLBACK,
- 'file' => 'i18n.pages.inc',
- );
- return $items;
- }
-
- /**
- * Implementation of hook_menu_alter().
- *
- * Take over the node translation page.
- */
- function i18n_menu_alter(&$items) {
- $items['node/%node/translate']['page callback'] = 'i18n_translation_node_overview';
- $items['node/%node/translate']['file'] = 'i18n.pages.inc';
- $items['node/%node/translate']['module'] = 'i18n';
- }
-
- /**
- * Implementation of hook_nodeapi().
- */
- function i18n_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
- global $language;
-
- if (variable_get('language_content_type_' . $node->type, 0)) {
- // Set current language for new nodes if option enabled
- if ($op == 'prepare' && empty($node->nid) && empty($node->language) && variable_get('i18n_newnode_current_' . $node->type, 0)) {
- $node->language = $language->language;
- }
- }
- }
-
- /**
- * Implementation of hook_alter_translation_link().
- *
- * Handles links for extended language. The links will have current language.
- */
- function i18n_translation_link_alter(&$links, $path) {
- global $language;
-
- // Check for a node related path, and for its translations.
- if ((preg_match("!^node/([0-9]+)(/.+|)$!", $path, $matches)) && ($node = node_load((int)$matches[1])) && !empty($node->tnid)) {
- // make sure language support is set to LANGUAGE_SUPPORT_EXTENDED, so links
- // dont get added for LANGUAGE_SUPPORT_EXTENDED_NOT_DISPLAYED
- if (variable_get('i18n_node_'. $node->type, LANGUAGE_SUPPORT_NORMAL) == LANGUAGE_SUPPORT_EXTENDED) {
- $languages = language_list();
- $extended = array();
- foreach (translation_node_get_translations($node->tnid) as $langcode => $translation_node) {
- if (!isset($links[$langcode]) && isset($languages[$langcode])) {
- $extended[$langcode] = array(
- 'href' => 'node/'. $translation_node->nid . $matches[2],
- 'language' => $language,
- 'language_icon' => $languages[$langcode],
- 'title' => $languages[$langcode]->native,
- 'attributes' => array('class' => 'language-link'),
- );
- }
- }
- // This will run after languageicon module, so we add icon in case that one is enabled.
- if ($extended && function_exists('languageicons_translation_link_alter')) {
- languageicons_translation_link_alter($extended, $path);
- }
- $links = array_merge($links, $extended);
- }
- }
- }
-
- /**
- * Implementation of hook_link_alter().
- *
- * Handles links for extended languages. Sets current interface language.
- */
- function i18n_link_alter(&$links, $node) {
- global $language;
-
- $language_support = variable_get('i18n_node_'. $node->type, LANGUAGE_SUPPORT_NORMAL);
-
- // Hide node translation links.
- if (variable_get('i18n_hide_translation_links', 0) == 1) {
- foreach ($links as $module => $link) {
- if (strpos($module, 'node_translation') === 0) {
- unset($links[$module]);
- }
- }
- }
-
- if (!empty($node->tnid)) {
- foreach (array_keys(i18n_language_list('extended')) as $langcode) {
- $index = 'node_translation_'. $langcode;
- if (!empty($links[$index])) {
- if ($language_support != LANGUAGE_SUPPORT_EXTENDED && $links[$index]['language']->enabled == 0) {
- unset($links[$index]);
- }
- else {
- $links[$index]['language'] = $language;
- }
- }
- }
- }
- }
-
- /**
- * Implementation of hook_user().
- *
- * Switch to user's language after login.
- */
- function i18n_user($op, &$edit, &$account, $category = NULL) {
- if ($op == 'login' && $account->language) {
- i18n_get_lang($account->language);
- }
- }
-
- /**
- * Implementation of hook_elements().
- *
- * Add a process callback for textfields.
- */
- function i18n_elements() {
- $type = array();
- $type['textfield'] = array('#process' => array('i18n_textfield_process'));
- return $type;
- }
-
- /**
- * Process callback for textfield elements.
- *
- * When editing or translating a node, set Javascript to rewrite autocomplete
- * paths to use the node language prefix rather than the current content one.
- */
- function i18n_textfield_process($element) {
- global $language;
- static $sent = FALSE;
-
- // Ensure we send the Javascript only once.
- if (!$sent && isset($element['#autocomplete_path']) && !empty($element['#autocomplete_path']) && variable_get('language_negotiation', LANGUAGE_NEGOTIATION_NONE) != LANGUAGE_NEGOTIATION_NONE) {
- // Add a JS file for node forms.
- // Determine if we are either editing or translating an existing node.
- // We can't act on regular node creation because we don't have a specified
- // node language.
- $node_edit = $node = menu_get_object() && arg(2) == 'edit' && isset($node->language) && !empty($node->language);
- $node_translate = arg(0) == 'node' && arg(1) == 'add' && !empty($_GET['translation']) && !empty($_GET['language']);
- if ($node_edit || $node_translate) {
- $node_language = $node_edit ? $node->language : $_GET['language'];
- // Only needed if the node language is different from the interface one.
- if ($node_language != $language->language) {
- $languages = language_list();
- if (isset($languages[$node_language])) {
- drupal_add_js(drupal_get_path('module', 'i18n') . '/i18n.js');
- // Pass the interface and content language base paths.
- // Remove any trailing forward slash. Doing so prevents a mismatch
- // that occurs when a language has no prefix and hence gets a path
- // with a trailing forward slash.
- $interface = rtrim(url('', array('absolute' => TRUE)), '/');
- $content = rtrim(url('', array('absolute' => TRUE, 'language' => $languages[$node_language])), '/');
- $data = array('interface_path' => $interface, 'content_path' => $content);
- drupal_add_js(array('i18n' => $data), 'setting');
- }
- }
- }
- $sent = TRUE;
- }
- return $element;
- }
-
- /**
- * Simple i18n API
- */
-
- /**
- * Get language properties.
- *
- * @param $code
- * Language code.
- * @param $property
- * It may be 'name', 'native', 'ltr'...
- */
- function i18n_language_property($code, $property) {
- $languages = language_list();
- return isset($languages[$code]->$property) ? $languages[$code]->$property : NULL;
- }
-
- /**
- * Get node language.
- */
- function i18n_node_get_lang($nid, $default = '') {
- $lang = db_result(db_query('SELECT language FROM {node} WHERE nid = %d', $nid));
- return $lang ? $lang : $default ;
- }
-
- /**
- * Get allowed languages for node.
- *
- * This allows node types to define its own language list implementing hook 'language_list'.
- *
- * @param $node
- * Node to retrieve language list for.
- * @param $translate
- * Only languages available for translation. Filter out existing translations.
- */
- function i18n_node_language_list($node, $translate = FALSE) {
- // Check if the node module manages its own language list.
- $languages = node_invoke($node, 'language_list', $translate);
-
- if (!$languages) {
- if (variable_get('i18n_node_'. $node->type, 0) >= LANGUAGE_SUPPORT_EXTENDED) {
- $languages = locale_language_list('name', TRUE); // All defined languages
- }
- else {
- $languages = locale_language_list(); // All enabled languages
- }
- if ($translate && isset($node->tnid) && $node->tnid && ($translations = translation_node_get_translations($node->tnid))) {
- unset($translations[$node->language]);
- foreach (array_keys($translations) as $langcode) {
- unset($languages[$langcode]);
- }
- }
- // Language may be locked for this node type, restrict options to current one
- if (variable_get('i18n_lock_node_' . $node->type, 0) && !empty($node->language) && !empty($languages[$node->language])) {
- $languages = array($node->language => $languages[$node->language]);
- }
- // Check language required for this type (no language neutral)
- elseif (!variable_get('i18n_required_node_' . $node->type, 0)) {
- $languages = array('' => t('Language neutral')) + $languages;
- }
- }
-
- return $languages;
- }
-
- /**
- * Selection mode for content.
- *
- * Warning: when used with params they need to be escaped, as some values are thrown directly in queries.
- *
- * Allows several modes for query rewriting and to change them programatically.
- * off = No language conditions inserted.
- * simple = Only current language and no language.
- * mixed = Only current and default languages.
- * strict = Only current language.
- * default = Only default language.
- * user = User defined, in the module's settings page.
- * params = Gets the stored params.
- * reset = Returns to previous.
- * custom = add custom where clause, like "%alias.language = 'en'".
- */
- function i18n_selection_mode($mode = NULL, $params = NULL) {
- static $current_mode;
- static $current_value = '';
- static $store = array();
-
- // Initialization, first time this runs
- if (!isset($current_mode)) {
- $current_mode = variable_get('i18n_selection_mode', 'simple');
- }
-
- if (!$mode) {
- return $current_mode;
- }
- elseif ($mode == 'params') {
- return $current_value;
- }
- elseif ($mode == 'reset') {
- list($current_mode, $current_value) = array_pop($store);
- }
- else {
- array_push($store, array($current_mode, $current_value));
- $current_mode = $mode;
- $current_value = $params;
- }
- }
-
- /**
- * Implementation of hook_db_rewrite_sql().
- *
- * Rewrite node queries so language selection options are enforced.
- */
- function i18n_db_rewrite_sql($query, $primary_table, $primary_key, $args = array()) {
- // If mode is 'off' = no rewrite, we cannot return any empty 'where' string so check here.
- $mode = i18n_selection_mode();
- if ($mode == 'off') return;
-
- // Disable language conditions for views.
- if (array_key_exists('view', $args)) return;
-
- switch ($primary_table) {
- case 'n':
- case 'node':
- // No rewrite for queries with subselect ? (views count queries).
- // @ TO DO Actually these queries look un-rewrittable, check with other developers.
- if (preg_match("/FROM \(SELECT/", $query)) return;
- // No rewrite for translation module queries.
- if (preg_match("/.*FROM {node} $primary_table WHERE.*$primary_table\.tnid/", $query)) return;
- // When loading specific nodes, language conditions shouldn't apply.
- if (preg_match("/WHERE.*\s$primary_table.nid\s*=\s*(\d|%d)/", $query)) return;
- // If language conditions already there, get out.
- if (preg_match("/i18n/", $query)) return;
-
-
- // Mixed mode is a bit more complex, we need to join in one more table
- // and add some more conditions, but only if language is not default.
- if ($mode == 'mixed') {
- $result['where'] = i18n_db_rewrite_where($primary_table, 'node', 'simple');
- if (i18n_get_lang() != i18n_default_language()) {
- $result['join'] = "LEFT JOIN {node} i18n ON $primary_table.tnid > 0 AND $primary_table.tnid = i18n.tnid AND i18n.language = '". i18n_get_lang() ."'";
- // So we show also nodes that have default language.
- $result['where'] .= " OR $primary_table.language = '". i18n_default_language() ."' AND i18n.nid IS NULL";
- }
- }
- else {
- $result['where'] = i18n_db_rewrite_where($primary_table, 'node', $mode);
- }
- return $result;
- }
- }
-
- /**
- * Rewrites queries depending on rewriting mode.
- */
- function i18n_db_rewrite_where($alias, $type, $mode = NULL) {
- if (!$mode) {
- // Some exceptions for query rewrites.
- $mode = i18n_selection_mode();
- }
-
- // Get languages to simplify query building.
- $current = i18n_get_lang();
- $default = i18n_default_language();
-
- if ($mode == 'strict' && $type != 'node') {
- // Special case. Selection mode is 'strict' but this should be only for node queries.
- $mode = 'simple';
- }
- elseif ($mode == 'mixed' && $current == $default) {
- // If mode is mixed but current = default, is the same as 'simple'.
- $mode = 'simple';
- }
-
- switch ($mode) {
- case 'off':
- return '';
-
- case 'simple':
- return "$alias.language ='$current' OR $alias.language ='' OR $alias.language IS NULL" ;
-
- case 'mixed':
- return "$alias.language ='$current' OR $alias.language ='$default' OR $alias.language ='' OR $alias.language IS NULL" ;
-
- case 'strict':
- return "$alias.language ='$current'" ;
-
- case 'node':
- case 'translation':
- return "$alias.language ='". i18n_selection_mode('params') ."' OR $alias.language ='' OR $alias.language IS NULL" ;
-
- case 'default':
- return "$alias.language ='$default' OR $alias.language ='' OR $alias.language IS NULL" ;
-
- case 'custom':
- return str_replace('%alias', $alias, i18n_selection_mode('params'));
- }
- }
-
- /**
- * Implementation of hook_preprocess_page().
- *
- * Add the language code to the classes for the <body> tag. Unfortunately, some
- * themes will not respect the variable we're modifying to achieve this - in
- * particular, Garland and Minelli do not.
- */
- function i18n_preprocess_page(&$variables) {
- if (isset($variables['body_classes'])) {
- global $language;
- $variables['body_classes'] .= ' i18n-' . $language->language;
- }
- }
-
- /**
- * Implementation of hook_exit().
- */
- function i18n_exit() {
- _i18n_variable_exit();
- }
-
- /**
- * Implementation of hook_form_alter();
- *
- * This is the place to add language fields to all forms.
- */
- function i18n_form_alter(&$form, $form_state, $form_id) {
- global $language;
-
- switch ($form_id) {
- case 'node_type_form':
- $disabled = !variable_get('language_content_type_'. $form['#node_type']->type, 0);
- $form['i18n'] = array(
- '#type' => 'fieldset',
- '#title' => t('Multilanguage options'),
- '#collapsible' => TRUE,
- '#collapsed' => TRUE,
- '#description' => t('Extended multilingual options provided by Internationalization module.'),
- '#disabled' => $disabled,
- );
- // Add disabled message
- if ($disabled) {
- $form['i18n']['#description'] .= ' <em>' . t('These will be available only when you enable Multilingual support in Workflow settings above.') . '</em>';
- }
- // Some settings about node languages
- $form['i18n']['options'] = array(
- '#title' => t('Options for node language'),
- '#type' => 'fieldset',
- '#disabled' => $disabled,
- );
- $form['i18n']['options']['i18n_newnode_current'] = array(
- '#type' => 'checkbox',
- '#title' => t('Set current language as default for new content.'),
- '#default_value' => variable_get('i18n_newnode_current_' . $form['#node_type']->type, 0),
- '#disabled' => $disabled,
- );
- $form['i18n']['options']['i18n_required_node'] = array(
- '#type' => 'checkbox',
- '#title' => t('Require language (Do not allow Language Neutral).'),
- '#default_value' => variable_get('i18n_required_node_' . $form['#node_type']->type, 0),
- '#disabled' => $disabled,
- );
- $form['i18n']['options']['i18n_lock_node'] = array(
- '#type' => 'checkbox',
- '#title' => t('Lock language (Cannot be changed).'),
- '#default_value' => variable_get('i18n_lock_node_' . $form['#node_type']->type, 0),
- '#disabled' => $disabled,
- );
- // Add extended language support option to content type form.
- $form['i18n']['i18n_node'] = array(
- '#type' => 'radios',
- '#title' => t('Extended language support'),
- '#default_value' => variable_get('i18n_node_'. $form['#node_type']->type, LANGUAGE_SUPPORT_NORMAL),
- '#options' => _i18n_content_language_options(),
- '#description' => t('If enabled, all defined languages will be allowed for this content type in addition to only enabled ones. This is useful to have more languages for content than for the interface.'),
- '#disabled' => $disabled,
- );
- break;
-
- default:
- // Extensions for node edit forms
- if (isset($form['#id']) && $form['#id'] == 'node-form') {
- if (isset($form['#node']->type)) {
- if (variable_get('language_content_type_'. $form['#node']->type, 0)) {
- if (!empty($form['language']['#options'])) {
- $form['language']['#options'] = i18n_node_language_list($form['#node'], TRUE);
- }
- }
- elseif (!isset($form['#node']->nid)) {
- // Set language to empty for not multilingual nodes when creating
- $form['language'] = array('#type' => 'value', '#value' => '');
- }
- }
- }
-
- // Multilingual variables in settings form.
- if (isset($form['#theme']) && $form['#theme'] == 'system_settings_form' && $variables = i18n_variable()) {
- if ($i18n_variables = i18n_form_alter_settings($form, $variables)) {
- array_unshift($form['#submit'], 'i18n_variable_form_submit');
- $form['#i18n_variables'] = $i18n_variables;
- }
- }
- }
- }
-
- /**
- * Implementation of hook_perm().
- *
- * Permissions defined
- * - administer all languages
- * Disables language conditions for administration pages, so the user can view objects for all languages at the same time.
- * This applies for: menu items, taxonomy
- * - administer translations
- * Will allow to add/remove existing nodes to/from translation sets.
- */
- function i18n_perm() {
- return array('administer all languages', 'administer translations');
- }
-
- /**
- * Implementation of hook_theme().
- */
- function i18n_theme() {
- return array(
- 'i18n_node_select_translation' => array(
- 'arguments' => array('element' => NULL),
- 'file' => 'i18n.pages.inc',
- ),
- );
- }
-
- /**
- * Process menu and menu item add/edit form submissions.
- */
- function i18n_menu_edit_item_form_submit($form, &$form_state) {
- $mid = menu_edit_item_save($form_state['values']);
- db_query("UPDATE {menu} SET language = '%s' WHERE mid = %d", $form_state['values']['language'], $mid);
- return 'admin/build/menu';
- }
-
- /**
- * Check for multilingual variables in form.
- */
- function i18n_form_alter_settings(&$form, &$variables) {
- $result = array();
- foreach (element_children($form) as $field) {
- if (count(element_children($form[$field])) && empty($form[$field]['#tree'])) {
- $result += i18n_form_alter_settings($form[$field], $variables);
- }
- elseif (in_array($field, $variables)) {
- // Add form field class: i18n-variable
- $form[$field]['#attributes']['class'] = !empty($form[$field]['#attributes']['class']) ? $form[$field]['#attributes']['class'] . ' i18n-variable' : 'i18n-variable';
- $form[$field]['#description'] = !empty($form[$field]['#description']) ? $form[$field]['#description'] : '';
- $form[$field]['#description'] .= ' <strong>'. t('This is a multilingual variable.') .'</strong>';
- // Addd field => name to result
- $result[$field] = !empty($form[$field]['#title']) ? $form[$field]['#title'] : $field;
- }
- }
- return $result;
- }
-
- /**
- * Save multilingual variables and remove them from form.
- */
- function i18n_variable_form_submit($form, &$form_state) {
- $op = isset($form_state['values']['op']) ? $form_state['values']['op'] : '';
- $variables = i18n_variable();
- $language = i18n_get_lang();
- $is_default = $language == language_default('language');
- foreach ($form_state['values'] as $key => $value) {
- if (i18n_variable($key)) {
- if ($op == t('Reset to defaults')) {
- i18n_variable_del($key, $language);
- }
- else {
- if (is_array($value) && isset($form_state['values']['array_filter'])) {
- $value = array_keys(array_filter($value));
- }
- i18n_variable_set($key, $value, $language);
- }
- // If current is default language, we allow global (without language) variables to be set too
- if (!$is_default) {
- unset($form_state['values'][$key]);
- }
- }
- }
- // The form will go now through system_settings_form_submit()
- }
-
- /**
- * Initialization of multilingual variables.
- *
- * @param $langcode
- * Language to retrieve variables. Defaults to current language.
- */
- function i18n_variable_init($langcode = NULL) {
- global $conf;
-
- $langcode = $langcode ? $langcode : i18n_get_lang();
- if ($variables = _i18n_variable_init($langcode)) {
- $conf = array_merge($conf, $variables);
- }
- }
-
- /**
- * Get language from context.
- */
- function _i18n_get_context_lang() {
- // Node language when loading specific nodes or creating translations.
- if (arg(0) == 'node' ) {
- if (($node = menu_get_object('node')) && $node->language) {
- return $node->language;
- }
- elseif (arg(1) == 'add' && !empty($_GET['translation']) && !empty($_GET['language'])) {
- return $_GET['language'];
- }
- }
- }
-
- /**
- * Helper function to create language selector.
- */
- function _i18n_language_select($value ='', $description ='', $weight = -20, $languages = NULL) {
- $languages = $languages ? $languages : locale_language_list();
- return array(
- '#type' => 'select',
- '#title' => t('Language'),
- '#default_value' => $value,
- '#options' => array_merge(array('' => ''), $languages),
- '#description' => $description,
- '#weight' => $weight,
- );
- }
-
- /**
- * Load language variables into array.
- */
- function _i18n_variable_init($langcode) {
- global $i18n_conf;
-
- if (!isset($i18n_conf[$langcode])) {
- $cacheid = 'variables:'. $langcode;
- if ($cached = cache_get($cacheid)) {
- $i18n_conf[$langcode] = $cached->data;
- }
- else {
- $result = db_query("SELECT * FROM {i18n_variable} WHERE language = '%s'", $langcode);
- $i18n_conf[$langcode] = array();
- while ($variable = db_fetch_object($result)) {
- $i18n_conf[$langcode][$variable->name] = unserialize($variable->value);
- }
- cache_set($cacheid, $i18n_conf[$langcode]);
- }
- }
-
- return $i18n_conf[$langcode];
- }
-
- /**
- * Save multilingual variables that may have been changed by other methods than settings pages.
- */
- function _i18n_variable_exit() {
- global $conf, $i18n_conf;
-
- $langcode = i18n_get_lang();
- if (isset($i18n_conf[$langcode])) {
- $refresh = FALSE;
- // Rewritten because array_diff_assoc may fail with array variables.
- foreach (i18n_variable() as $name) {
- if (isset($conf[$name]) && isset($i18n_conf[$langcode][$name]) && $conf[$name] != $i18n_conf[$langcode][$name]) {
- $refresh = TRUE;
- $i18n_conf[$langcode][$name] = $conf[$name];
- db_query("DELETE FROM {i18n_variable} WHERE name='%s' AND language='%s'", $name, $langcode);
- db_query("INSERT INTO {i18n_variable} (language, name, value) VALUES('%s', '%s', '%s')", $langcode, $name, serialize($conf[$name]));
- }
- }
- if ($refresh) {
- cache_set('variables:'. $langcode, $i18n_conf[$langcode]);
- }
- }
- }
-
- /**
- * Check whether we are in bootstrap mode.
- */
- function _i18n_is_bootstrap() {
- return !function_exists('drupal_get_headers');
- }
-
- /**
- * Drupal 6, backwards compatibility layer.
- *
- * @ TO DO Fully upgrade all the modules and remove
- */
-
- /**
- * This one expects to be called first from common.inc
- */
- function i18n_get_lang() {
- global $language;
- return $language->language;
- }
-
- /**
- * @defgroup i18n_api Extended language API
- * @{
- * This is an extended language API to be used by modules in i18n package.
- */
-
- /**
- * Returns language lists.
- */
- function i18n_language_list($type = 'enabled', $field = 'name') {
- switch ($type) {
- case 'enabled':
- return locale_language_list($field);
-
- case 'extended':
- $enabled = locale_language_list($field);
- $defined = locale_language_list($field, TRUE);
- return array_diff_assoc($defined, $enabled);
- }
- }
-
- /**
- * Returns default language code.
- */
- function i18n_default_language() {
- return language_default('language');
- }
-
- /**
- * Get list of supported languages, native name.
- *
- * @param $all
- * TRUE to get all defined languages.
- */
- function i18n_supported_languages($all = FALSE) {
- return locale_language_list('native', $all);
- }
-
- /**
- * Get list of multilingual variables or check whether a variable is multilingual
- */
- function i18n_variable($name = NULL) {
- $variables = variable_get('i18n_variables', array());
- return $name ? in_array($name, $variables) : $variables;
- }
-
- /**
- * Set a persistent language dependent variable.
- *
- * @param $name
- * The name of the variable to set.
- * @param $value
- * The value to set. This can be any PHP data type; these functions take care
- * of serialization as necessary.
- * @param $langcode
- * Language code.
- */
- function i18n_variable_set($name, $value, $langcode) {
- global $conf, $i18n_conf;
-
- $serialized_value = serialize($value);
- db_query("UPDATE {i18n_variable} SET value = '%s' WHERE name = '%s' AND language = '%s'", $serialized_value, $name, $langcode);
- if (!db_affected_rows()) {
- @db_query("INSERT INTO {i18n_variable} (name, language, value) VALUES ('%s', '%s', '%s')", $name, $langcode, $serialized_value);
- }
- cache_clear_all('variables:'. $langcode, 'cache');
- $i18n_conf[$langcode][$name] = $value;
- if ($langcode == i18n_get_lang()) {
- $conf[$name] = $value;
- }
- }
-
- /**
- * Get single multilingual variable
- */
- function i18n_variable_get($name, $langcode, $default = NULL) {
- if ($variables = _i18n_variable_init($langcode)) {
- return isset($variables[$name]) ? $variables[$name] : $default;
- }
- else {
- return $default;
- }
- }
-
- /**
- * Unset a persistent multilingual variable.
- *
- * @param $name
- * The name of the variable to undefine.
- * @param $langcode
- * Optional language code. If not set it will delete the variable for all languages.
- */
- function i18n_variable_del($name, $langcode = NULL) {
- global $conf, $i18n_conf;
-
- if ($langcode) {
- db_query("DELETE FROM {i18n_variable} WHERE name = '%s' AND language='%s'", $name, $langcode);
- cache_clear_all('variables:'. $langcode, 'cache');
- unset($i18n_conf[$langcode][$name]);
- // If current language, unset also global conf
- if ($langcode == i18n_get_lang()) {
- unset($conf[$name]);
- }
- }
- else {
- db_query("DELETE FROM {i18n_variable} WHERE name = '%s'", $name);
- if (db_affected_rows()) {
- cache_clear_all('variables:', 'cache', TRUE);
- if (is_array($i18n_conf)) {
- foreach (array_keys($i18n_conf) as $lang) {
- unset($i18n_conf[$lang][$name]);
- }
- }
- }
- }
- }
-
- /**
- * Utility. Get part of array variable.
- */
- function i18n_array_variable_get($name, $element, $default = NULL) {
- if (($values = variable_get($name, array())) && isset($values[$element])) {
- return $values[$element];
- }
- else {
- return $default;
- }
- }
-
- /**
- * Utility. Set part of array variable.
- */
- function i18n_array_variable_set($name, $element, $value) {
- $values = variable_get($name, array());
- $values[$element] = $value;
- variable_set($name, $values);
- }
-
- /**
- * @} End of "defgroup i18n_api".
- */
-
- /**
- * List of language support modes for content.
- */
- function _i18n_content_language_options() {
- return array(
- LANGUAGE_SUPPORT_NORMAL => t('Normal - All enabled languages will be allowed.'),
- LANGUAGE_SUPPORT_EXTENDED => t('Extended - All defined languages will be allowed.'),
- LANGUAGE_SUPPORT_EXTENDED_NOT_DISPLAYED => t('Extended, but not displayed - All defined languages will be allowed for input, but not displayed in links.'),
- );
- }
-