diff --git a/core/modules/language/language.admin.inc b/core/modules/language/language.admin.inc index b388986..8056fd1 100644 --- a/core/modules/language/language.admin.inc +++ b/core/modules/language/language.admin.inc @@ -807,3 +807,183 @@ function language_negotiation_configure_session_form($form, &$form_state) { return system_settings_form($form); } + +/** + * Builds the browser language negotiation method configuration form. + */ +function language_negotiation_configure_browser_form($form, &$form_state) { + $form = array(); + + $form['info'] = array( + '#type' => 'markup', + '#markup' => t("You can add custom mappings to map browser languages to Drupal languages."), + ); + + $form['mappings'] = array( + '#type' => 'container', + '#tree' => TRUE, + '#theme' => 'language_negotiation_configure_browser_form_table', + ); + + $mappings = language_get_mappings(); + foreach ($mappings as $browser_langcode => $drupal_langcode) { + $form['mappings'][$browser_langcode] = array( + 'browser_langcode' => array( + '#type' => 'textfield', + '#default_value' => $browser_langcode, + '#size' => 20, + ), + 'drupal_langcode' => array( + '#type' => 'textfield', + '#default_value' => $drupal_langcode, + '#size' => 20, + ), + ); + } + + // Add empty row + $form['mappings']['_new'] = array( + 'browser_langcode' => array( + '#type' => 'textfield', + '#default_value' => '', + '#size' => 20, + ), + 'drupal_langcode' => array( + '#type' => 'textfield', + '#default_value' => '', + '#size' => 20, + ), + ); + + $form_state['redirect'] = 'admin/config/regional/language/detection'; + + $form['actions']['#type'] = 'actions'; + $form['actions']['submit'] = array( + '#type' => 'submit', + '#value' => t('Save configuration'), + ); + + return $form; +} + +/** + * Theme browser configuration form as table. + */ +function theme_language_negotiation_configure_browser_form_table($variables) { + $form = $variables['form']; + $rows = array(); + $link_attributes = array( + 'attributes' => array( + 'class' => array('image-style-link'), + ), + ); + foreach (element_children($form, TRUE) as $key) { + $row = array(); + $row[] = drupal_render($form[$key]['browser_langcode']); + $row[] = drupal_render($form[$key]['drupal_langcode']); + + if ($key != '_new') { + $row[] = l(t('Delete'), 'admin/config/regional/language/detection/browser/delete/' . $key, $link_attributes); + } + else { + $row[] = ''; + } + $rows[] = array( + 'data' => $row, + ); + } + + $header = array( + t('Browser language code'), + t('Drupal language code'), + t('Operations'), + ); + + $output = theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => array('id' => 'lang-neg-browser'))); + + return $output; +} + +/** + * Browser language negotiation form validation. + */ +function language_negotiation_configure_browser_form_validate($form, &$form_state) { + $mappings = $form_state['values']['mappings']; + $unique_values = array(); + foreach ($mappings as $key => $data) { + if ($key == '_new') { + if (!empty($data['browser_langcode']) && !empty($data['drupal_langcode'])) { + // Make sure browser_langcode is unique + if (array_key_exists($data['browser_langcode'], $unique_values)) { + form_set_error('mappings][' . $key . '][browser_langcode', 'Browser language codes must be unique.'); + } + elseif (preg_match('/[^a-z\-]/', $data['browser_langcode'])) { + form_set_error('mappings][' . $key . '][browser_langcode', 'Browser language codes can only contain lowercase letters and a hyphen(-).'); + } + elseif (preg_match('/[^a-z\-]/', $data['drupal_langcode'])) { + form_set_error('mappings][' . $key . '][drupal_langcode', 'Drupal language codes can only contain lowercase letters and a hyphen(-).'); + } + $unique_values[$data['browser_langcode']] = $data['drupal_langcode']; + } + } + else { + if (!empty($data['browser_langcode']) && !empty($data['drupal_langcode'])) { + // Make sure browser_langcode is unique + if (array_key_exists($data['browser_langcode'], $unique_values)) { + form_set_error('mappings][' . $key . '][browser_langcode', 'Browser language codes must be unique.'); + } + elseif (preg_match('/[^a-z\-]/', $data['browser_langcode'])) { + form_set_error('mappings][' . $key . '][browser_langcode', 'Browser language codes can only contain lowercase letters and a hyphen(-).'); + } + elseif (preg_match('/[^a-z\-]/', $data['drupal_langcode'])) { + form_set_error('mappings][' . $key . '][drupal_langcode', 'Drupal language codes can only contain lowercase letters and a hyphen(-).'); + } + $unique_values[$data['browser_langcode']] = $data['drupal_langcode']; + } + else { + if (empty($data['browser_langcode'])) { + form_set_error('mappings][' . $key . '][browser_langcode', 'Browser language code cannot be blank.'); + } + if (empty($data['drupal_langcode'])) { + form_set_error('mappings][' . $key . '][drupal_langcode', 'Drupal language code cannot be blank.'); + } + } + } + } + $form_state['mappings'] = $unique_values; +} + +/** + * Browser language negotiation form submit. + */ +function language_negotiation_configure_browser_form_submit($form, &$form_state) { + $mappings = $form_state['mappings']; + if (!empty($mappings)) { + language_set_mappings($mappings); + } +} + +/** + * Delete a language mapping form. + */ +function language_negotiation_configure_browser_delete_form($form, &$form_state, $browser_langcode) { + $form_state['browser_langcode'] = $browser_langcode; + $question = t('Are you sure you want to delete %browser_langcode', array( + '%browser_langcode' => $browser_langcode, + )); + $path = 'admin/config/regional/language/detection/browser'; + return confirm_form($form, $question, $path, ''); +} + +/** + * Delete a language mapping submit. + */ +function language_negotiation_configure_browser_delete_form_submit($form, &$form_state) { + $browser_langcode = $form_state['browser_langcode']; + $mappings = language_get_mappings(); + if (array_key_exists($browser_langcode, $mappings)) { + unset($mappings[$browser_langcode]); + language_set_mappings($mappings); + } + $form_state['redirect'] = 'admin/config/regional/language/detection/browser'; +} diff --git a/core/modules/language/language.module b/core/modules/language/language.module index e7d3e2b..4e16ba7 100644 --- a/core/modules/language/language.module +++ b/core/modules/language/language.module @@ -116,6 +116,21 @@ function language_menu() { 'file' => 'language.admin.inc', 'type' => MENU_VISIBLE_IN_BREADCRUMB, ); + $items['admin/config/regional/language/detection/browser'] = array( + 'title' => 'Browser language detection configuration', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('language_negotiation_configure_browser_form'), + 'access arguments' => array('administer languages'), + 'file' => 'language.admin.inc', + 'type' => MENU_VISIBLE_IN_BREADCRUMB, + ); + $items['admin/config/regional/language/detection/browser/delete/%'] = array( + 'title' => 'Delete language mapping', + 'page arguments' => array('language_negotiation_configure_browser_delete_form', 7), + 'type' => MENU_CALLBACK, + 'access arguments' => array('administer languages'), + 'file' => 'language.admin.inc', + ); return $items; } @@ -154,6 +169,10 @@ function language_theme() { 'language_negotiation_configure_form' => array( 'render element' => 'form', ), + 'language_negotiation_configure_browser_form_table' => array( + 'render element' => 'form', + 'file' => 'language.admin.inc', + ), ); } @@ -391,6 +410,7 @@ function language_language_negotiation_info() { 'cache' => 0, 'name' => t('Browser'), 'description' => t("Language from the browser's language settings."), + 'config' => 'admin/config/regional/language/detection/browser', ); $negotiation_info[LANGUAGE_NEGOTIATION_INTERFACE] = array( @@ -598,8 +618,7 @@ function language_url_outbound_alter(&$path, &$options, $original_path) { } /** - * Returns default language mappings. - * @todo: How can this be overridden? + * Returns language mappings. */ function language_get_mappings() { $config = config('language.mappings'); @@ -607,4 +626,13 @@ function language_get_mappings() { return FALSE; } return $config->get(); +} + +/** + * Stores language mappings. + */ +function language_set_mappings($mappings) { + $config = config('language.mappings'); + $config->setData($mappings); + $config->save(); } \ No newline at end of file