You are here

admin_language.module in Administration Language 6

Same filename and directory in other branches
  1. 7 admin_language.module

Makes sure all admin pages are displayed in the preferred language of the administrator.

File

admin_language.module
View source
<?php

/**
 * @file
 * Makes sure all admin pages are displayed in the preferred language of the
 * administrator.
 */
define('ADMIN_LANGUAGE_DEFAULT_PAGES', "admin\nadmin/*\nadmin_menu/*\nnode/add/*\nnode/*/edit\nnode/*/devel\nnode/*/translate");
define('ADMIN_LANGUAGE_ALL_PAGES', 0);
define('ADMIN_LANGUAGE_SOME_PAGES', 1);

/* --- HOOKS ---------------------------------------------------------------- */

/**
 * Implementation of hook_help().
 */
function admin_language_help($path, $arg) {
  switch ($path) {
    case 'admin/settings/language':
      return '<p>' . t('Use the <em>admin</em> column to select the default language for all administration pages. The language you select must be enabled. You can configure the !settings-url to control where the administration language is used.', array(
        '!settings-url' => l(t('administration language settings'), 'admin/settings/language/admin_language'),
      )) . '</p>';
      break;
  }
}

/**
 * Implementation of hook_perm().
 */
function admin_language_perm() {
  return array(
    'display admin pages in another language',
    'use all enabled languages',
  );
}

/**
 * Implementation of hook_menu().
 */
function admin_language_menu() {
  $items = array();
  $items['admin/settings/language/admin_language'] = array(
    'title' => 'Administration language',
    'description' => 'Select which parts of the site should use the selected administration language.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'admin_language_settings',
    ),
    'access arguments' => array(
      'administer site configuration',
    ),
    'weight' => 42,
    'type' => MENU_LOCAL_TASK,
  );
  return $items;
}

/**
 * Implementation of hook_translated_menu_link_alter().
 */
function admin_language_translated_menu_link_alter(&$item, $map) {

  // we only want to modify the administration menu
  if ($item['menu_name'] != 'admin_menu') {
    return;
  }
  if (variable_get('admin_language_translate_admin_menu', 0)) {
    global $language, $_admin_language;

    // save the current language and activate the administration language...
    $current_language = $language;
    $language = $_admin_language;

    // ...modify the menu item...
    _menu_item_localize($item, $map, TRUE);

    // ...and restore the previous language
    $language = $current_language;
  }
}

/**
 * Implementation of hook_init().
 */
function admin_language_init() {
  if (user_access('display admin pages in another language') && variable_get('language_count', 1) > 1) {
    global $_admin_language;
    $languages = language_list('enabled');
    $languages = $languages[1];
    $admin_language = variable_get('admin_language_default', 'en');
    $_admin_language = $languages[$admin_language];
    if (_admin_language_switch_language()) {
      global $user;
      if (isset($user->admin_language)) {
        switch ($user->admin_language) {
          case 'admin':

            // nothing to do, use default value of $admin_language
            break;
          case 'default':
            $default = language_default();
            $admin_language = $default->language;
            break;
          default:
            if (isset($languages[$user->admin_language])) {
              $admin_language = $user->admin_language;
            }
        }
      }
      global $language;
      $language = $languages[$admin_language];
    }
  }
}

/**
 * Implementation of hook_nodeapi().
 */
function admin_language_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
  switch ($op) {
    case 'presave':
      if (!user_access('use all enabled languages')) {
        if (variable_get('admin_language_force_default', 0)) {

          // force the use of the default site language
          $default = language_default();
          $node->language = $default->language;
        }
      }
      break;
    case 'insert':
    case 'update':
      if (variable_get('admin_language_force_neutral', 0)) {
        unset($node->language);
      }
      break;
  }
}

/**
 * Implementation of hook_form_alter().
 */
function admin_language_form_alter(&$form, $form_state, $form_id) {
  if (isset($form['type']) && isset($form['#node']) && $form['type']['#value'] . '_node_form' == $form_id) {
    if (module_exists('translation') && variable_get('admin_language_hide_node', 0)) {
      if (isset($form['language'])) {

        // init #after_build if it doesn't exist
        if (!isset($form['#after_build'])) {
          $form['#after_build'] = array();
        }

        // add a callback for cleaning up the language select widget
        $form['#after_build'][] = 'admin_language_modify_language_element';
      }
    }
  }
}

/**
 * Implementation of hook_form_FORM_ID_alter().
 */
function admin_language_form_locale_languages_overview_form_alter(&$form, &$form_state) {

  // use the same options as the default language selector...
  $options = $form['enabled']['#options'];

  // ...but use a different default value for the admin language
  $form['admin_language'] = array(
    '#type' => 'radios',
    '#options' => $options,
    '#default_value' => variable_get('admin_language_default', 'en'),
  );

  // add class to enable tabledrag support
  foreach (element_children($form['weight']) as $index) {
    $form['weight'][$index]['#attributes']['class'] = 'language-order-weight';
  }

  // override the default theme function to render the extra field
  $form['#theme'] = 'admin_language_languages_overview_form';

  // add validate and submit handlers to handle the new field
  $form['#validate'][] = 'admin_language_languages_overview_form_validate';
  $form['#submit'][] = 'admin_language_languages_overview_form_submit';
}

/**
 * Implementation of hook_form_FORM_ID_alter().
 */
function admin_language_form_user_profile_form_alter(&$form, &$form_state) {
  if (variable_get('admin_language_hide_user', 0) && !user_access('use all enabled languages')) {
    $language = variable_get('admin_language_default', 'en');

    // remove the admin language from the available options
    unset($form['locale']['language']['#options'][$language]);

    // make sure that the default value is available on the form
    $default_value = $form['locale']['language']['#default_value'];
    if (!isset($form['locale']['language']['#options'][$default_value])) {
      $options = array_keys($form['locale']['language']['#options']);
      $form['locale']['language']['#default_value'] = array_shift($options);
    }

    // if that leaves us with only one language, we replace the select element
    // with a value element and hide the language fieldset
    if (count($form['locale']['language']['#options']) == 1) {
      $options = array_keys($form['locale']['language']['#options']);
      $default = array_shift($options);
      $form['locale']['language'] = array(
        '#type' => 'value',
        '#value' => $default,
      );
      $form['locale']['#access'] = FALSE;
    }
  }
}

/**
 * Implementation of hook_user().
 */
function admin_language_user($type, $edit, &$user, $category = NULL) {
  if (variable_get('language_count', 1) && ($type == 'register' && user_access('administer users') || $type == 'form' && $category == 'account' && user_access('display admin pages in another language'))) {
    $languages = language_list('enabled');
    $languages = $languages[1];
    $default = language_default();
    $admin_langcode = variable_get('admin_language', 'en');
    if (isset($languages[$admin_langcode])) {
      $lang = $languages[$admin_langcode];
      $admin_language_name = t($lang->name) . ($lang->native != t($lang->name) ? ' (' . $lang->native . ')' : '');
    }
    else {
      $admin_language_name = t('Not enabled');
    }
    $names = array(
      'admin' => t('Default administration language, currently !language', array(
        '!language' => $admin_language_name,
      )),
      'default' => t('Default site language, currently !language', array(
        '!language' => t($default->name) . ($default->native != t($default->name) ? ' (' . $default->native . ')' : ''),
      )),
    );
    if (user_access('use all enabled languages')) {
      foreach ($languages as $langcode => $item) {
        $name = t($item->name);
        $names[$langcode] = $name . ($item->native != $name ? ' (' . $item->native . ')' : '');
      }
    }
    $form['admin_language'] = array(
      '#type' => 'fieldset',
      '#title' => t('Administration language'),
    );
    $form['admin_language']['admin_language'] = array(
      '#type' => count($names) <= 5 ? 'radios' : 'select',
      '#title' => t('Default administration language'),
      '#default_value' => admin_language_preferred($user),
      '#options' => $names,
      '#description' => t('Select the default language to use for all administration pages. See the !settings-url for a list of affected pages.', array(
        '!settings-url' => l(t('administration language settings'), 'admin/settings/language/admin_language'),
      )),
    );
    return $form;
  }
}

/**
 * Implementation of hook_block().
 */
function admin_language_block($op = 'list', $delta = 0) {
  if ($op == 'list') {
    $block[0]['info'] = t('Language switcher (without administration language)');
    $block[0]['cache'] = BLOCK_NO_CACHE;
    return $block;
  }
  elseif ($op == 'view' && variable_get('language_count', 1) > 1 && variable_get('language_negotiation', LANGUAGE_NEGOTIATION_NONE) != LANGUAGE_NEGOTIATION_NONE) {
    $path = drupal_is_front_page() ? '<front>' : $_GET['q'];
    $languages = language_list('enabled');
    $admin_language = variable_get('admin_language_default', 'en');
    $links = array();
    foreach ($languages[1] as $language) {
      if ($language->language != $admin_language) {
        $links[$language->language] = array(
          'href' => $path,
          'title' => $language->native,
          'language' => $language,
          'attributes' => array(
            'class' => 'language-link',
          ),
        );
      }
    }

    // modify links to point at translated versions when available.
    // same behavior as translation_translation_link_alter() but we don't
    // remove links when a translation is unavailable.
    if (module_exists('translation')) {
      if ($paths = translation_path_get_translations($path)) {
        $node = node_load(arg(1));
        $translations = translation_node_get_translations($node->tnid);
        foreach ($links as $langcode => $link) {
          if (isset($paths[$langcode]) && $translations[$langcode]->status) {

            // Translation in a different node.
            $links[$langcode]['href'] = $paths[$langcode];
          }
        }
      }
    }
    $block['subject'] = t('Languages');
    $block['content'] = theme('links', $links, array());
    return $block;
  }
}

/**
 * Implementation of hook_theme().
 */
function admin_language_theme() {
  return array(
    'admin_language_languages_overview_form' => array(
      'arguments' => array(
        'form' => array(),
      ),
    ),
  );
}

/* --- FORMS ---------------------------------------------------------------- */

/**
 * Settings form.
 */
function admin_language_settings() {
  $form = array();
  $options = array(
    ADMIN_LANGUAGE_ALL_PAGES => t('Use administration language on every page except the listed pages.'),
    ADMIN_LANGUAGE_SOME_PAGES => t('Use administration language on only the listed pages.'),
  );
  $description = t("Enter one page per line as Drupal paths. The '*' character is a wildcard. Example paths are %admin for the admin dashboard and %admin-wildcard for all administration pages. %front is the front page.", array(
    '%admin' => 'admin',
    '%admin-wildcard' => 'admin/*',
    '%front' => '<front>',
  ));
  $form['admin_language']['admin_language_visibility'] = array(
    '#type' => 'radios',
    '#title' => t('Use administration language on specific pages'),
    '#options' => $options,
    '#default_value' => variable_get('admin_language_visibility', ADMIN_LANGUAGE_SOME_PAGES),
  );
  $form['admin_language']['admin_language_pages'] = array(
    '#type' => 'textarea',
    '#title' => t('Pages'),
    '#default_value' => variable_get('admin_language_pages', ADMIN_LANGUAGE_DEFAULT_PAGES),
    '#description' => $description,
  );
  $form['admin_language_hide_user'] = array(
    '#type' => 'radios',
    '#title' => t('Hide administration language on user form'),
    '#description' => t('Select this option if you want to exclude the admin language from the language selection widget on the user edit form.'),
    '#options' => array(
      t('Disabled'),
      t('Enabled'),
    ),
    '#default_value' => variable_get('admin_language_hide_user', 0),
  );
  $form['admin_language_hide_node'] = array(
    '#type' => 'radios',
    '#title' => t('Hide administration language on node form'),
    '#description' => t('Select this option if you want to exclude the admin language from the language selection widget on the node edit form.'),
    '#options' => array(
      t('Disabled'),
      t('Enabled'),
    ),
    '#default_value' => variable_get('admin_language_hide_node', 0),
  );
  $form['admin_language_force_default'] = array(
    '#type' => 'radios',
    '#title' => t('Force use of default language'),
    '#description' => t('Select this option if you want to force the use of the default language on the node edit form. This setting overrides the <em>Hide admin language on user form</em> setting.'),
    '#options' => array(
      t('Disabled'),
      t('Enabled'),
    ),
    '#default_value' => variable_get('admin_language_force_default', 0),
  );
  $form['admin_language_force_neutral'] = array(
    '#type' => 'radios',
    '#title' => t('Force language neutral aliases'),
    '#description' => t('Select this option if you want to force the use of language neutral URL aliases. In some cases (i.e. if you only use an administration language and a site language) this can help make aliases more consistent.'),
    '#options' => array(
      t('Disabled'),
      t('Enabled'),
    ),
    '#default_value' => variable_get('admin_language_force_neutral', 0),
  );
  if (module_exists('admin_menu')) {
    $form['admin_language_translate_admin_menu'] = array(
      '#type' => 'radios',
      '#title' => t('Use administration language in the administration menu'),
      '#description' => t('Select this option if you want to display the administration menu using the administration language on all pages.'),
      '#options' => array(
        t('Disabled'),
        t('Enabled'),
      ),
      '#default_value' => variable_get('admin_language_translate_admin_menu', 0),
    );
  }
  return system_settings_form($form);
}

/**
 * Validation handler for the augmented language overview form.
 */
function admin_language_languages_overview_form_validate($form, &$form_state) {
  $admin_language = $form_state['values']['admin_language'];
  $enabled = $form_state['values']['enabled'][$admin_language];
  $default = language_default();
  if ($admin_language != $default->language && !$enabled) {
    form_set_error('', t('Only enabled languages can be chosen as the admin language.'));
  }
}

/**
 * Submit handler for the augmented language overview form.
 */
function admin_language_languages_overview_form_submit($form, &$form_state) {
  $admin_language = $form_state['values']['admin_language'];
  variable_set('admin_language_default', $admin_language);
}

/**
 * #after_build callback which modifies the language select widget on the node
 * add/edit form.
 */
function admin_language_modify_language_element($form, &$form_state) {
  if (!user_access('use all enabled languages')) {

    // remove the administration language from the list of available languages
    if (isset($form['language']['#options']) && count($form['language']['#options']) > 2) {
      $language = variable_get('admin_language_default', 'en');
      unset($form['language']['#options'][$language]);
    }

    // hide the language selector if we're forcing a default language
    if (isset($form['language']) && variable_get('admin_language_force_default', 0)) {
      $form['language']['#access'] = FALSE;
    }
  }
  return $form;
}

/* --- THEME ---------------------------------------------------------------- */

/**
 * Theme the language overview form.
 *
 * This is just theme_locale_languages_overview_form() with support for the
 * admin language radio buttons.
 */
function theme_admin_language_languages_overview_form($form) {
  $default = language_default();
  foreach ($form['name'] as $key => $element) {
    if (is_array($element) && element_child($key)) {
      if ($key == $default->language) {
        $form['enabled'][$key]['#attributes']['disabled'] = 'disabled';
      }
      $rows[] = array(
        'data' => array(
          array(
            'data' => drupal_render($form['enabled'][$key]),
            'align' => 'center',
          ),
          check_plain($key),
          '<strong>' . drupal_render($form['name'][$key]) . '</strong>',
          drupal_render($form['native'][$key]),
          drupal_render($form['direction'][$key]),
          drupal_render($form['site_default'][$key]),
          drupal_render($form['admin_language'][$key]),
          drupal_render($form['weight'][$key]),
          l(t('edit'), 'admin/settings/language/edit/' . $key) . ($key != 'en' && $key != $default->language ? ' ' . l(t('delete'), 'admin/settings/language/delete/' . $key) : ''),
        ),
        'class' => 'draggable',
      );
    }
  }
  $header = array(
    array(
      'data' => t('Enabled'),
    ),
    array(
      'data' => t('Code'),
    ),
    array(
      'data' => t('English name'),
    ),
    array(
      'data' => t('Native name'),
    ),
    array(
      'data' => t('Direction'),
    ),
    array(
      'data' => t('Default'),
    ),
    array(
      'data' => t('Admin'),
    ),
    array(
      'data' => t('Weight'),
    ),
    array(
      'data' => t('Operations'),
    ),
  );
  $output = theme('table', $header, $rows, array(
    'id' => 'language-order',
  ));
  $output .= drupal_render($form);
  drupal_add_tabledrag('language-order', 'order', 'sibling', 'language-order-weight');
  return $output;
}

/* --- UTILITY -------------------------------------------------------------- */

/**
 * Determine the preferred language of the given user.
 */
function admin_language_preferred($account) {
  $language_list = drupal_map_assoc(array(
    'admin',
    'default',
  ));
  $language_list += language_list();
  if (isset($account->admin_language) && isset($language_list[$account->admin_language])) {
    return $account->admin_language;
  }
  else {
    return 'admin';
  }
}

/**
 * Determine whether the language needs to be switched on the current path.
 *
 * @return boolean
 *   TRUE to switch to the selected administration language or FALSE to use the
 *   default language.
 */
function _admin_language_switch_language() {
  $switch = FALSE;
  $visibility = variable_get('admin_language_visibility', ADMIN_LANGUAGE_SOME_PAGES);
  $pages = variable_get('admin_language_pages', ADMIN_LANGUAGE_DEFAULT_PAGES);
  if ($pages) {
    $path = drupal_get_path_alias($_GET['q']);
    $switch = drupal_match_path($path, $pages);
    if ($path != $_GET['q']) {
      $switch = $switch || drupal_match_path($_GET['q'], $pages);
    }
    $switch = !($visibility xor $switch);
  }
  else {
    $switch = TRUE;
    $switch = ($visibility xor $switch);
  }
  return $switch;
}

Functions

Namesort descending Description
admin_language_block Implementation of hook_block().
admin_language_form_alter Implementation of hook_form_alter().
admin_language_form_locale_languages_overview_form_alter Implementation of hook_form_FORM_ID_alter().
admin_language_form_user_profile_form_alter Implementation of hook_form_FORM_ID_alter().
admin_language_help Implementation of hook_help().
admin_language_init Implementation of hook_init().
admin_language_languages_overview_form_submit Submit handler for the augmented language overview form.
admin_language_languages_overview_form_validate Validation handler for the augmented language overview form.
admin_language_menu Implementation of hook_menu().
admin_language_modify_language_element #after_build callback which modifies the language select widget on the node add/edit form.
admin_language_nodeapi Implementation of hook_nodeapi().
admin_language_perm Implementation of hook_perm().
admin_language_preferred Determine the preferred language of the given user.
admin_language_settings Settings form.
admin_language_theme Implementation of hook_theme().
admin_language_translated_menu_link_alter Implementation of hook_translated_menu_link_alter().
admin_language_user Implementation of hook_user().
theme_admin_language_languages_overview_form Theme the language overview form.
_admin_language_switch_language Determine whether the language needs to be switched on the current path.

Constants

Namesort descending Description
ADMIN_LANGUAGE_ALL_PAGES
ADMIN_LANGUAGE_DEFAULT_PAGES @file Makes sure all admin pages are displayed in the preferred language of the administrator.
ADMIN_LANGUAGE_SOME_PAGES