diff --git a/core/modules/language/lib/Drupal/language/Tests/LanguageUILanguageNegotiationTest.php b/core/modules/language/lib/Drupal/language/Tests/LanguageUILanguageNegotiationTest.php
index 555c198..403761b 100644
--- a/core/modules/language/lib/Drupal/language/Tests/LanguageUILanguageNegotiationTest.php
+++ b/core/modules/language/lib/Drupal/language/Tests/LanguageUILanguageNegotiationTest.php
@@ -122,25 +122,25 @@ function testUILanguageNegotiation() {
'string' => $default_string,
'langcode' => $langcode_browser_fallback,
);
- $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
+ $this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
$textarea = current($this->xpath('//textarea'));
$lid = (string) $textarea[0]['name'];
$edit = array(
$lid => $language_browser_fallback_string,
);
- $this->drupalPost('admin/config/regional/translate/translate', $edit, t('Save translations'));
+ $this->drupalPost('admin/config/regional/translate', $edit, t('Save translations'));
$search = array(
'string' => $default_string,
'langcode' => $langcode,
);
- $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
+ $this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
$textarea = current($this->xpath('//textarea'));
$lid = (string) $textarea[0]['name'];
$edit = array(
$lid => $language_string,
);
- $this->drupalPost('admin/config/regional/translate/translate', $edit, t('Save translations'));
+ $this->drupalPost('admin/config/regional/translate', $edit, t('Save translations'));
// Configure URL language rewrite.
variable_set('language_negotiation_url_type', Language::TYPE_INTERFACE);
diff --git a/core/modules/locale/lib/Drupal/locale/Controller/LocaleController.php b/core/modules/locale/lib/Drupal/locale/Controller/LocaleController.php
new file mode 100644
index 0000000..746e761
--- /dev/null
+++ b/core/modules/locale/lib/Drupal/locale/Controller/LocaleController.php
@@ -0,0 +1,53 @@
+get('keyvalue')->get('state'));
+ }
+
+ /**
+ * Constructs a LocaleController object.
+ */
+ public function __construct(KeyValueStoreInterface $state) {
+ $this->state = $state;
+ }
+
+ /**
+ * Page callback: Shows the string search screen.
+ *
+ * @see locale_menu()
+ */
+ public function translatePage() {
+ return array(
+ 'filter' => drupal_get_form(new TranslateFilterForm($this->state)),
+ 'form' => drupal_get_form(new TranslateEditForm($this->state)),
+ );
+ }
+
+}
diff --git a/core/modules/locale/lib/Drupal/locale/Form/TranslateEditForm.php b/core/modules/locale/lib/Drupal/locale/Form/TranslateEditForm.php
new file mode 100644
index 0000000..0069886
--- /dev/null
+++ b/core/modules/locale/lib/Drupal/locale/Form/TranslateEditForm.php
@@ -0,0 +1,240 @@
+state = $state;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getFormID() {
+ return 'locale_translate_edit_form';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildForm(array $form, array &$form_state, NodeInterface $node = NULL) {
+ $filter_values = $this->translateFilterValues();
+ $langcode = $filter_values['langcode'];
+
+ drupal_static_reset('language_list');
+ $languages = language_list();
+
+ $langname = isset($langcode) ? $languages[$langcode]->name : "- None -";
+
+ $path = drupal_get_path('module', 'locale');
+ $form['#attached']['css'] = array(
+ $path . '/css/locale.admin.css',
+ );
+ $form['#attached']['library'][] = array('locale', 'drupal.locale.admin');
+
+ $form['langcode'] = array(
+ '#type' => 'value',
+ '#value' => $filter_values['langcode'],
+ );
+
+ $form['strings'] = array(
+ '#type' => 'item',
+ '#tree' => TRUE,
+ '#language' => $langname,
+ '#theme' => 'locale_translate_edit_form_strings',
+ );
+
+ if (isset($langcode)) {
+ $strings = $this->translateFilterLoadStrings();
+
+ $plural_formulas = $this->state->get('locale.translation.plurals') ?: array();
+
+ foreach ($strings as $string) {
+ // Cast into source string, will do for our purposes.
+ $source = new SourceString($string);
+ // Split source to work with plural values.
+ $source_array = $source->getPlurals();
+ $translation_array = $string->getPlurals();
+ if (count($source_array) == 1) {
+ // Add original string value and mark as non-plural.
+ $form['strings'][$string->lid]['plural'] = array(
+ '#type' => 'value',
+ '#value' => 0,
+ );
+ $form['strings'][$string->lid]['original'] = array(
+ '#type' => 'item',
+ '#title' => t('Source string'),
+ '#title_display' => 'invisible',
+ '#markup' => check_plain($source_array[0]),
+ );
+ }
+ else {
+ // Add original string value and mark as plural.
+ $form['strings'][$string->lid]['plural'] = array(
+ '#type' => 'value',
+ '#value' => 1,
+ );
+ $form['strings'][$string->lid]['original_singular'] = array(
+ '#type' => 'item',
+ '#title' => t('Singular form'),
+ '#markup' => check_plain($source_array[0]),
+ );
+ $form['strings'][$string->lid]['original_plural'] = array(
+ '#type' => 'item',
+ '#title' => t('Plural form'),
+ '#markup' => check_plain($source_array[1]),
+ );
+ }
+ if (!empty($string->context)) {
+ $form['strings'][$string->lid]['context'] = array(
+ '#type' => 'value',
+ '#value' => check_plain($string->context),
+ );
+ }
+ // Approximate the number of rows to use in the default textarea.
+ $rows = min(ceil(str_word_count($source_array[0]) / 12), 10);
+ if (empty($form['strings'][$string->lid]['plural']['#value'])) {
+ $form['strings'][$string->lid]['translations'][0] = array(
+ '#type' => 'textarea',
+ '#title' => t('Translated string'),
+ '#title_display' => 'invisible',
+ '#rows' => $rows,
+ '#default_value' => $translation_array[0],
+ );
+ }
+ else {
+ // Dealing with plural strings.
+ if (isset($plural_formulas[$langcode]['plurals']) && $plural_formulas[$langcode]['plurals'] > 2) {
+ // Add a textarea for each plural variant.
+ for ($i = 0; $i < $plural_formulas[$langcode]['plurals']; $i++) {
+ $form['strings'][$string->lid]['translations'][$i] = array(
+ '#type' => 'textarea',
+ '#title' => ($i == 0 ? t('Singular form') : format_plural($i, 'First plural form', '@count. plural form')),
+ '#rows' => $rows,
+ '#default_value' => isset($translation_array[$i]) ? $translation_array[$i] : '',
+ );
+ }
+ }
+ else {
+ // Fallback for unknown number of plurals.
+ $form['strings'][$string->lid]['translations'][0] = array(
+ '#type' => 'textarea',
+ '#title' => t('Singular form'),
+ '#rows' => $rows,
+ '#default_value' => $translation_array[0],
+ );
+ $form['strings'][$string->lid]['translations'][1] = array(
+ '#type' => 'textarea',
+ '#title' => t('Plural form'),
+ '#rows' => $rows,
+ '#default_value' => isset($translation_array[1]) ? $translation_array[1] : '',
+ );
+ }
+ }
+ }
+ if (count(element_children($form['strings']))) {
+ $form['actions'] = array('#type' => 'actions');
+ $form['actions']['submit'] = array(
+ '#type' => 'submit',
+ '#value' => t('Save translations'));
+ }
+ }
+ return $form;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validateForm(array &$form, array &$form_state) {
+ $langcode = $form_state['values']['langcode'];
+ foreach ($form_state['values']['strings'] as $lid => $translations) {
+ foreach ($translations['translations'] as $key => $value) {
+ if (!locale_string_is_safe($value)) {
+ form_set_error("strings][$lid][translations][$key", t('The submitted string contains disallowed HTML: %string', array('%string' => $value)));
+ form_set_error("translations][$langcode][$key", t('The submitted string contains disallowed HTML: %string', array('%string' => $value)));
+ watchdog('locale', 'Attempted submission of a translation string with disallowed HTML: %string', array('%string' => $value), WATCHDOG_WARNING);
+ }
+ }
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function submitForm(array &$form, array &$form_state) {
+ $langcode = $form_state['values']['langcode'];
+ $updated = array();
+
+ // Preload all translations for strings in the form.
+ $lids = array_keys($form_state['values']['strings']);
+ $existing_translation_objects = array();
+ foreach (\Drupal::service('locale.storage')->getTranslations(array('lid' => $lids, 'language' => $langcode, 'translated' => TRUE)) as $existing_translation_object) {
+ $existing_translation_objects[$existing_translation_object->lid] = $existing_translation_object;
+ }
+
+ foreach ($form_state['values']['strings'] as $lid => $new_translation) {
+ $existing_translation = isset($existing_translation_objects[$lid]);
+
+ // Plural translations are saved in a delimited string. To be able to
+ // compare the new strings with the existing strings a string in the same format is created.
+ $new_translation_string_delimited = implode(LOCALE_PLURAL_DELIMITER, $new_translation['translations']);
+
+ // Generate an imploded string without delimiter, to be able to run
+ // empty() on it.
+ $new_translation_string = implode('', $new_translation['translations']);
+
+ $is_changed = FALSE;
+
+ if ($existing_translation && $existing_translation_objects[$lid]->translation != $new_translation_string_delimited) {
+ // If there is an existing translation in the DB and the new translation
+ // is not the same as the existing one.
+ $is_changed = TRUE;
+ }
+ elseif (!$existing_translation && !empty($new_translation_string)) {
+ // Newly entered translation.
+ $is_changed = TRUE;
+ }
+
+ if ($is_changed) {
+ // Only update or insert if we have a value to use.
+ $target = isset($existing_translation_objects[$lid]) ? $existing_translation_objects[$lid] : \Drupal::service('locale.storage')->createTranslation(array('lid' => $lid, 'language' => $langcode));
+ $target->setPlurals($new_translation['translations'])
+ ->setCustomized()
+ ->save();
+ $updated[] = $target->getId();
+ }
+ if (empty($new_translation_string) && isset($existing_translation_objects[$lid])) {
+ // Empty new translation entered: remove existing entry from database.
+ $existing_translation_objects[$lid]->delete();
+ $updated[] = $lid;
+ }
+ }
+
+ drupal_set_message(t('The strings have been saved.'));
+
+ // Keep the user on the current pager page.
+ if (isset($_GET['page'])) {
+ $form_state['redirect'] = array('admin/config/regional/translate', array('query' => array('page' => $_GET['page'])));
+ }
+
+ if ($updated) {
+ // Clear cache and force refresh of JavaScript translations.
+ _locale_refresh_translations(array($langcode), $updated);
+ _locale_refresh_configuration(array($langcode), $updated);
+ }
+ }
+}
diff --git a/core/modules/locale/lib/Drupal/locale/Form/TranslateFilterForm.php b/core/modules/locale/lib/Drupal/locale/Form/TranslateFilterForm.php
new file mode 100644
index 0000000..c055abb
--- /dev/null
+++ b/core/modules/locale/lib/Drupal/locale/Form/TranslateFilterForm.php
@@ -0,0 +1,110 @@
+translateFilters();
+ $filter_values = $this->translateFilterValues();
+
+ $form['#attached']['css'] = array(
+ drupal_get_path('module', 'locale') . '/locale.admin.css',
+ );
+
+ $form['filters'] = array(
+ '#type' => 'details',
+ '#title' => t('Filter translatable strings'),
+ '#collapsed' => FALSE,
+ );
+ foreach ($filters as $key => $filter) {
+ // Special case for 'string' filter.
+ if ($key == 'string') {
+ $form['filters']['status']['string'] = array(
+ '#type' => 'search',
+ '#title' => $filter['title'],
+ '#description' => $filter['description'],
+ '#default_value' => $filter_values[$key],
+ );
+ }
+ else {
+ $empty_option = isset($filter['options'][$filter['default']]) ? $filter['options'][$filter['default']] : '- None -';
+ $form['filters']['status'][$key] = array(
+ '#title' => $filter['title'],
+ '#type' => 'select',
+ '#empty_value' => $filter['default'],
+ '#empty_option' => $empty_option,
+ '#size' => 0,
+ '#options' => $filter['options'],
+ '#default_value' => $filter_values[$key],
+ );
+ if (isset($filter['states'])) {
+ $form['filters']['status'][$key]['#states'] = $filter['states'];
+ }
+ }
+ }
+
+ $form['filters']['actions'] = array(
+ '#type' => 'actions',
+ '#attributes' => array('class' => array('container-inline')),
+ );
+ $form['filters']['actions']['submit'] = array(
+ '#type' => 'submit',
+ '#value' => t('Filter'),
+ );
+ if (!empty($_SESSION['locale_translate_filter'])) {
+ $form['filters']['actions']['reset'] = array(
+ '#type' => 'submit',
+ '#value' => t('Reset'),
+ );
+ }
+
+ return $form;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validateForm(array &$form, array &$form_state) {
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function submitForm(array &$form, array &$form_state) {
+ $op = $form_state['values']['op'];
+ $filters = $this->translateFilters();
+ switch ($op) {
+ case t('Filter'):
+ foreach ($filters as $name => $filter) {
+ if (isset($form_state['values'][$name])) {
+ $_SESSION['locale_translate_filter'][$name] = $form_state['values'][$name];
+ }
+ }
+ break;
+
+ case t('Reset'):
+ $_SESSION['locale_translate_filter'] = array();
+ break;
+ }
+
+ $form_state['redirect'] = 'admin/config/regional/translate';
+ }
+}
diff --git a/core/modules/locale/lib/Drupal/locale/Form/TranslateFormBase.php b/core/modules/locale/lib/Drupal/locale/Form/TranslateFormBase.php
new file mode 100644
index 0000000..13e5a6f
--- /dev/null
+++ b/core/modules/locale/lib/Drupal/locale/Form/TranslateFormBase.php
@@ -0,0 +1,151 @@
+translateFilterValues($request);
+
+ // Language is sanitized to be one of the possible options in
+ // translateFilterValues().
+ $conditions = array('language' => $filter_values['langcode']);
+ $options = array('pager limit' => 30, 'translated' => TRUE, 'untranslated' => TRUE);
+
+ // Add translation status conditions and options.
+ switch ($filter_values['translation']) {
+ case 'translated':
+ $conditions['translated'] = TRUE;
+ if ($filter_values['customized'] != 'all') {
+ $conditions['customized'] = $filter_values['customized'];
+ }
+ break;
+
+ case 'untranslated':
+ $conditions['translated'] = FALSE;
+ break;
+
+ }
+
+ if (!empty($filter_values['string'])) {
+ $options['filters']['source'] = $filter_values['string'];
+ if ($options['translated']) {
+ $options['filters']['translation'] = $filter_values['string'];
+ }
+ }
+
+ return \Drupal::service('locale.storage')->getTranslations($conditions, $options);
+ }
+
+ /**
+ * Build array out of search criteria specified in request variables.
+ */
+ function translateFilterValues(Request $request) {
+ // @todo vlikin: Need be decoupled.
+ $request = \Drupal::request();
+
+ $filter_values = &drupal_static(__FUNCTION__);
+ if (!isset($filter_values)) {
+ $filter_values = array();
+ $filters = $this->translateFilters();
+ foreach ($filters as $key => $filter) {
+ $filter_values[$key] = $filter['default'];
+ // Let the filter defaults be overwritten by parameters in the URL.
+ if ($request->query->has($key)) {
+ // Only allow this value if it was among the options, or
+ // if there were no fixed options to filter for.
+ $value = $request->query->get($key);
+ if (!isset($filter['options']) || isset($filter['options'][$value])) {
+ $filter_values[$key] = $value;
+ }
+ }
+ elseif (isset($_SESSION['locale_translate_filter'][$key])) {
+ // Only allow this value if it was among the options, or
+ // if there were no fixed options to filter for.
+ if (!isset($filter['options']) || isset($filter['options'][$_SESSION['locale_translate_filter'][$key]])) {
+ $filter_values[$key] = $_SESSION['locale_translate_filter'][$key];
+ }
+ }
+ }
+ }
+ return $filter_values;
+ }
+
+ /**
+ * List locale translation filters that can be applied.
+ */
+ function translateFilters() {
+ $filters = array();
+
+ // Get all languages, except English.
+ drupal_static_reset('language_list');
+ $languages = language_list();
+ $language_options = array();
+ foreach ($languages as $langcode => $language) {
+ if ($langcode != 'en' || locale_translate_english()) {
+ $language_options[$langcode] = $language->name;
+ }
+ }
+
+ // Pick the current interface language code for the filter.
+ $default_langcode = language(Language::TYPE_INTERFACE)->id;
+ if (!isset($language_options[$default_langcode])) {
+ $available_langcodes = array_keys($language_options);
+ $default_langcode = array_shift($available_langcodes);
+ }
+
+ $filters['string'] = array(
+ 'title' => t('String contains'),
+ 'description' => t('Leave blank to show all strings. The search is case sensitive.'),
+ 'default' => '',
+ );
+
+ $filters['langcode'] = array(
+ 'title' => t('Translation language'),
+ 'options' => $language_options,
+ 'default' => $default_langcode,
+ );
+
+ $filters['translation'] = array(
+ 'title' => t('Search in'),
+ 'options' => array(
+ 'all' => t('Both translated and untranslated strings'),
+ 'translated' => t('Only translated strings'),
+ 'untranslated' => t('Only untranslated strings'),
+ ),
+ 'default' => 'all',
+ );
+
+ $filters['customized'] = array(
+ 'title' => t('Translation type'),
+ 'options' => array(
+ 'all' => t('All'),
+ LOCALE_NOT_CUSTOMIZED => t('Non-customized translation'),
+ LOCALE_CUSTOMIZED => t('Customized translation'),
+ ),
+ 'states' => array(
+ 'visible' => array(
+ ':input[name=translation]' => array('value' => 'translated'),
+ ),
+ ),
+ 'default' => 'all',
+ );
+
+ return $filters;
+ }
+}
diff --git a/core/modules/locale/lib/Drupal/locale/Tests/LocaleConfigTranslationTest.php b/core/modules/locale/lib/Drupal/locale/Tests/LocaleConfigTranslationTest.php
index 414cde0..f0ffe79 100644
--- a/core/modules/locale/lib/Drupal/locale/Tests/LocaleConfigTranslationTest.php
+++ b/core/modules/locale/lib/Drupal/locale/Tests/LocaleConfigTranslationTest.php
@@ -69,14 +69,14 @@ function testConfigTranslation() {
'langcode' => $langcode,
'translation' => 'all',
);
- $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
+ $this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
$textareas = $this->xpath('//textarea');
$textarea = current($textareas);
$lid = (string) $textarea[0]['name'];
$edit = array(
$lid => $site_name,
);
- $this->drupalPost('admin/config/regional/translate/translate', $edit, t('Save translations'));
+ $this->drupalPost('admin/config/regional/translate', $edit, t('Save translations'));
$wrapper = $this->container->get('locale.config.typed')->get('system.site');
@@ -115,13 +115,13 @@ function testConfigTranslation() {
'langcode' => $langcode,
'translation' => 'all',
);
- $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
+ $this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
$textarea = current($this->xpath('//textarea'));
$lid = (string) $textarea[0]['name'];
$edit = array(
$lid => $image_style_label,
);
- $this->drupalPost('admin/config/regional/translate/translate', $edit, t('Save translations'));
+ $this->drupalPost('admin/config/regional/translate', $edit, t('Save translations'));
// Check the right single translation has been created.
$translations = $this->storage->getTranslations(array('language' => $langcode, 'type' => 'configuration', 'name' => 'image.style.medium'));
diff --git a/core/modules/locale/lib/Drupal/locale/Tests/LocaleImportFunctionalTest.php b/core/modules/locale/lib/Drupal/locale/Tests/LocaleImportFunctionalTest.php
index fcc74d0..d95e735 100644
--- a/core/modules/locale/lib/Drupal/locale/Tests/LocaleImportFunctionalTest.php
+++ b/core/modules/locale/lib/Drupal/locale/Tests/LocaleImportFunctionalTest.php
@@ -111,7 +111,7 @@ function testStandalonePoFile() {
'langcode' => 'fr',
'translation' => 'translated',
);
- $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
+ $this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
$this->assertText(t('No strings available.'), t('String not overwritten by imported string.'));
// This import should not have changed number of plural forms.
@@ -169,7 +169,7 @@ function testStandalonePoFile() {
'langcode' => 'fr',
'translation' => 'translated',
);
- $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
+ $this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
$this->assertText(t('No strings available.'), t('Customized string not overwritten by imported string.'));
// Try importing a .po file with overriding strings, and ensure existing
@@ -188,7 +188,7 @@ function testStandalonePoFile() {
'langcode' => 'fr',
'translation' => 'translated',
);
- $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
+ $this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
$this->assertNoText(t('No strings available.'), t('Customized string overwritten by imported string.'));
}
@@ -233,7 +233,7 @@ function testEmptyMsgstr() {
'langcode' => $langcode,
'translation' => 'untranslated',
);
- $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
+ $this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
$this->assertText($str, t('Search found the string as untranslated.'));
}
@@ -287,7 +287,7 @@ function testConfigPoFile() {
'langcode' => $langcode,
'translation' => 'all',
);
- $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
+ $this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
$this->assertText($config_string[1], format_string('Translation of @string found.', array('@string' => $config_string[0])));
}
diff --git a/core/modules/locale/lib/Drupal/locale/Tests/LocalePluralFormatTest.php b/core/modules/locale/lib/Drupal/locale/Tests/LocalePluralFormatTest.php
index 0ef62a9..0a2b468 100644
--- a/core/modules/locale/lib/Drupal/locale/Tests/LocalePluralFormatTest.php
+++ b/core/modules/locale/lib/Drupal/locale/Tests/LocalePluralFormatTest.php
@@ -204,7 +204,7 @@ function testPluralEditExport() {
$search = array(
'langcode' => 'fr',
);
- $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
+ $this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
// Plural values for the langcode fr.
$this->assertText('@count heure');
$this->assertText('@count heures');
@@ -227,7 +227,7 @@ function testPluralEditExport() {
'string' => '1 day',
'langcode' => 'fr',
);
- $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
+ $this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
// Save complete translations for the string in langcode fr.
$edit = array(
@@ -241,7 +241,7 @@ function testPluralEditExport() {
'string' => '1 day',
'langcode' => 'hr',
);
- $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
+ $this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
$edit = array(
"strings[$lid][translations][0]" => '@count dan',
diff --git a/core/modules/locale/lib/Drupal/locale/Tests/LocaleTranslationUiTest.php b/core/modules/locale/lib/Drupal/locale/Tests/LocaleTranslationUiTest.php
index 63ef579..ebc2dba 100644
--- a/core/modules/locale/lib/Drupal/locale/Tests/LocaleTranslationUiTest.php
+++ b/core/modules/locale/lib/Drupal/locale/Tests/LocaleTranslationUiTest.php
@@ -38,7 +38,7 @@ function testEnglishTranslation() {
$this->drupalLogin($admin_user);
$this->drupalPost('admin/config/regional/language/edit/en', array('locale_translate_english' => TRUE), t('Save language'));
- $this->assertLinkByHref('/admin/config/regional/translate/translate?langcode=en', 0, t('Enabled interface translation to English.'));
+ $this->assertLinkByHref('/admin/config/regional/translate?langcode=en', 0, t('Enabled interface translation to English.'));
}
/**
@@ -86,7 +86,7 @@ function testStringTranslation() {
'langcode' => $langcode,
'translation' => 'untranslated',
);
- $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
+ $this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
$this->assertText($name, t('Search found the string as untranslated.'));
// Assume this is the only result, given the random name.
@@ -104,7 +104,7 @@ function testStringTranslation() {
$this->drupalPost('admin/config/regional/language/edit/en', array('locale_translate_english' => TRUE), t('Save language'));
$this->drupalLogout();
$this->drupalLogin($translate_user);
- $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
+ $this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
$this->assertText($name, t('Search found the string as untranslated.'));
// Assume this is the only result, given the random name.
@@ -113,15 +113,15 @@ function testStringTranslation() {
$edit = array(
$lid => $translation,
);
- $this->drupalPost('admin/config/regional/translate/translate', $edit, t('Save translations'));
+ $this->drupalPost('admin/config/regional/translate', $edit, t('Save translations'));
$this->assertText(t('The strings have been saved.'), t('The strings have been saved.'));
- $this->assertEqual($this->getUrl(), url('admin/config/regional/translate/translate', array('absolute' => TRUE)), t('Correct page redirection.'));
+ $this->assertEqual($this->getUrl(), url('admin/config/regional/translate', array('absolute' => TRUE)), t('Correct page redirection.'));
$search = array(
'string' => $name,
'langcode' => $langcode,
'translation' => 'translated',
);
- $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
+ $this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
$this->assertRaw($translation, t('Non-English translation properly saved.'));
@@ -130,19 +130,19 @@ function testStringTranslation() {
'langcode' => 'en',
'translation' => 'untranslated',
);
- $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
+ $this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
$textarea = current($this->xpath('//textarea'));
$lid = (string) $textarea[0]['name'];
$edit = array(
$lid => $translation_to_en,
);
- $this->drupalPost('admin/config/regional/translate/translate', $edit, t('Save translations'));
+ $this->drupalPost('admin/config/regional/translate', $edit, t('Save translations'));
$search = array(
'string' => $name,
'langcode' => 'en',
'translation' => 'translated',
);
- $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
+ $this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
$this->assertRaw($translation_to_en, t('English translation properly saved.'));
// Reset the tag cache on the tester side in order to pick up the call to
@@ -163,7 +163,7 @@ function testStringTranslation() {
'langcode' => 'en',
'translation' => 'untranslated',
);
- $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
+ $this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
$this->assertText(t('No strings available.'), t('String is translated.'));
$this->drupalLogout();
@@ -189,14 +189,14 @@ function testStringTranslation() {
'langcode' => 'en',
'translation' => 'translated',
);
- $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
+ $this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
// Assume this is the only result, given the random name.
$textarea = current($this->xpath('//textarea'));
$lid = (string) $textarea[0]['name'];
$edit = array(
$lid => '',
);
- $this->drupalPost('admin/config/regional/translate/translate', $edit, t('Save translations'));
+ $this->drupalPost('admin/config/regional/translate', $edit, t('Save translations'));
$this->assertRaw($name, t('The strings have been saved.'));
$this->drupalLogin($translate_user);
$search = array(
@@ -204,7 +204,7 @@ function testStringTranslation() {
'langcode' => 'en',
'translation' => 'untranslated',
);
- $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
+ $this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
$this->assertNoText(t('No strings available.'), t('The translation has been removed'));
}
@@ -247,14 +247,14 @@ function testJavaScriptTranslation() {
'langcode' => $langcode,
'translation' => 'all',
);
- $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
+ $this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
$textarea = current($this->xpath('//textarea'));
$lid = (string) $textarea[0]['name'];
$edit = array(
$lid => $this->randomName(),
);
- $this->drupalPost('admin/config/regional/translate/translate', $edit, t('Save translations'));
+ $this->drupalPost('admin/config/regional/translate', $edit, t('Save translations'));
// Trigger JavaScript translation parsing and building.
_locale_rebuild_js($langcode);
@@ -310,7 +310,7 @@ function testStringValidation() {
'langcode' => $langcode,
'translation' => 'all',
);
- $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
+ $this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
// Find the edit path.
$textarea = current($this->xpath('//textarea'));
@@ -319,7 +319,7 @@ function testStringValidation() {
$edit = array(
$lid => $translation,
);
- $this->drupalPost('admin/config/regional/translate/translate', $edit, t('Save translations'));
+ $this->drupalPost('admin/config/regional/translate', $edit, t('Save translations'));
// Check for a form error on the textarea.
$form_class = $this->xpath('//form[@id="locale-translate-edit-form"]//textarea/@class');
$this->assertNotIdentical(FALSE, strpos($form_class[0], 'error'), t('The string was rejected as unsafe.'));
@@ -379,7 +379,7 @@ function testStringSearch() {
'langcode' => $langcode,
'translation' => 'all',
);
- $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
+ $this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
// assertText() seems to remove the input field where $name always could be
// found, so this is not a false assert. See how assertNoText succeeds
// later.
@@ -392,7 +392,7 @@ function testStringSearch() {
'langcode' => $langcode,
'translation' => 'translated',
);
- $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
+ $this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
$this->assertText(t('No strings available.'), t("Search didn't find the string."));
// Ensure untranslated string appears if searching on 'only untranslated
@@ -402,7 +402,7 @@ function testStringSearch() {
'langcode' => $langcode,
'translation' => 'untranslated',
);
- $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
+ $this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
$this->assertNoText(t('No strings available.'), t('Search found the string.'));
// Add translation.
@@ -413,7 +413,7 @@ function testStringSearch() {
$edit = array(
$lid => $translation,
);
- $this->drupalPost('admin/config/regional/translate/translate', $edit, t('Save translations'));
+ $this->drupalPost('admin/config/regional/translate', $edit, t('Save translations'));
// Ensure translated string does appear if searching on 'only
// translated strings'.
@@ -422,7 +422,7 @@ function testStringSearch() {
'langcode' => $langcode,
'translation' => 'translated',
);
- $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
+ $this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
$this->assertNoText(t('No strings available.'), t('Search found the translation.'));
// Ensure translated source string doesn't appear if searching on 'only
@@ -432,7 +432,7 @@ function testStringSearch() {
'langcode' => $langcode,
'translation' => 'untranslated',
);
- $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
+ $this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
$this->assertText(t('No strings available.'), t("Search didn't find the source string."));
// Ensure translated string doesn't appear if searching on 'only
@@ -442,7 +442,7 @@ function testStringSearch() {
'langcode' => $langcode,
'translation' => 'untranslated',
);
- $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
+ $this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
$this->assertText(t('No strings available.'), t("Search didn't find the translation."));
// Ensure translated string does appear if searching on the custom language.
@@ -451,7 +451,7 @@ function testStringSearch() {
'langcode' => $langcode,
'translation' => 'all',
);
- $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
+ $this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
$this->assertNoText(t('No strings available.'), t('Search found the translation.'));
// Ensure translated string doesn't appear if searching in System (English).
@@ -460,7 +460,7 @@ function testStringSearch() {
'langcode' => 'yy',
'translation' => 'all',
);
- $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
+ $this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
$this->assertText(t('No strings available.'), t("Search didn't find the translation."));
// Search for a string that isn't in the system.
@@ -470,7 +470,7 @@ function testStringSearch() {
'langcode' => $langcode,
'translation' => 'all',
);
- $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
+ $this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
$this->assertText(t('No strings available.'), t("Search didn't find the invalid string."));
}
@@ -507,7 +507,7 @@ function testUICustomizedStrings(){
'translation' => 'translated',
'customized' => '0',
);
- $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
+ $this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
$source = $this->assertText($translation->getString(), 'Translation is found in search result.');
@@ -517,7 +517,7 @@ function testUICustomizedStrings(){
$edit = array(
$lid => $translation->getString(),
);
- $this->drupalPost('admin/config/regional/translate/translate', $edit, t('Save translations'));
+ $this->drupalPost('admin/config/regional/translate', $edit, t('Save translations'));
// Ensure unchanged translation string does appear if searching non-customized translation.
$search = array(
@@ -526,7 +526,7 @@ function testUICustomizedStrings(){
'translation' => 'translated',
'customized' => '0',
);
- $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
+ $this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
$source = $this->assertText($string->getString(), 'Translation is not marked as customized.');
// Submit the translations with a new translation.
@@ -535,7 +535,7 @@ function testUICustomizedStrings(){
$edit = array(
$lid => $this->randomName(100),
);
- $this->drupalPost('admin/config/regional/translate/translate', $edit, t('Save translations'));
+ $this->drupalPost('admin/config/regional/translate', $edit, t('Save translations'));
// Ensure changed translation string does appear if searching customized translation.
$search = array(
@@ -544,7 +544,7 @@ function testUICustomizedStrings(){
'translation' => 'translated',
'customized' => '1',
);
- $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
+ $this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
$this->assertText($string->getString(), "Translation is marked as customized.");
}
}
diff --git a/core/modules/locale/lib/Drupal/locale/Tests/LocaleUninstallTest.php b/core/modules/locale/lib/Drupal/locale/Tests/LocaleUninstallTest.php
index 961a5dd..8157308 100644
--- a/core/modules/locale/lib/Drupal/locale/Tests/LocaleUninstallTest.php
+++ b/core/modules/locale/lib/Drupal/locale/Tests/LocaleUninstallTest.php
@@ -77,7 +77,7 @@ function testUninstallProcess() {
// Build the JavaScript translation file for French.
$user = $this->drupalCreateUser(array('translate interface', 'access administration pages'));
$this->drupalLogin($user);
- $this->drupalGet('admin/config/regional/translate/translate');
+ $this->drupalGet('admin/config/regional/translate');
// Get any of the javascript strings to translate.
$js_strings = $this->container->get('locale.storage')->getStrings(array('type' => 'javascript'));
$string = reset($js_strings);
diff --git a/core/modules/locale/lib/Drupal/locale/Tests/LocaleUpdateTest.php b/core/modules/locale/lib/Drupal/locale/Tests/LocaleUpdateTest.php
index 44bfabe..1749963 100644
--- a/core/modules/locale/lib/Drupal/locale/Tests/LocaleUpdateTest.php
+++ b/core/modules/locale/lib/Drupal/locale/Tests/LocaleUpdateTest.php
@@ -452,7 +452,7 @@ function testEnableCustomLanguage() {
'langcode' => $langcode,
'translation' => 'translated',
);
- $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
+ $this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
$this->assertNoText(t('No strings available.'), t('String successfully imported.'));
// Ensure the multiline string was imported.
@@ -461,7 +461,7 @@ function testEnableCustomLanguage() {
'langcode' => $langcode,
'translation' => 'all',
);
- $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
+ $this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
$this->assertText('Multiline translation string to make sure that import works with it.', t('String successfully imported.'));
// Ensure 'Allowed HTML source string' was imported but the translation for
@@ -472,7 +472,7 @@ function testEnableCustomLanguage() {
'langcode' => $langcode,
'translation' => 'all',
);
- $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
+ $this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
$this->assertText('Allowed HTML source string', t('String successfully imported.'));
$this->assertNoText('Another allowed HTML source string', t('String with disallowed translation not imported.'));
}
diff --git a/core/modules/locale/locale.module b/core/modules/locale/locale.module
index 8d6ff20..c90fbb2 100644
--- a/core/modules/locale/locale.module
+++ b/core/modules/locale/locale.module
@@ -173,9 +173,7 @@ function locale_menu() {
$items['admin/config/regional/translate'] = array(
'title' => 'User interface translation',
'description' => 'Translate the built-in user interface.',
- 'page callback' => 'locale_translate_page',
- 'access arguments' => array('translate interface'),
- 'file' => 'locale.pages.inc',
+ 'route_name' => 'locale_translate_page',
'weight' => -5,
);
$items['admin/config/regional/translate/translate'] = array(
@@ -751,7 +749,7 @@ function locale_form_language_admin_overview_form_alter(&$form, &$form_state) {
'@total' => $total_strings,
'@ratio' => $stats[$langcode]['ratio'],
)),
- 'admin/config/regional/translate/translate',
+ 'admin/config/regional/translate',
array('query' => array('langcode' => $langcode))
),
);
diff --git a/core/modules/locale/locale.pages.inc b/core/modules/locale/locale.pages.inc
index 6326905..f2adfcd 100644
--- a/core/modules/locale/locale.pages.inc
+++ b/core/modules/locale/locale.pages.inc
@@ -12,463 +12,6 @@
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
- * Page callback: Shows the string search screen.
- *
- * @see locale_menu()
- */
-function locale_translate_page() {
- return array(
- 'filter' => drupal_get_form('locale_translate_filter_form'),
- 'form' => drupal_get_form('locale_translate_edit_form'),
- );
-}
-
-/**
- * Builds a string search query and returns an array of string objects.
- *
- * @return array
- * Array of Drupal\locale\TranslationString objects.
- */
-function locale_translate_filter_load_strings() {
- $filter_values = locale_translate_filter_values();
-
- // Language is sanitized to be one of the possible options in
- // locale_translate_filter_values().
- $conditions = array('language' => $filter_values['langcode']);
- $options = array('pager limit' => 30, 'translated' => TRUE, 'untranslated' => TRUE);
-
- // Add translation status conditions and options.
- switch ($filter_values['translation']) {
- case 'translated':
- $conditions['translated'] = TRUE;
- if ($filter_values['customized'] != 'all') {
- $conditions['customized'] = $filter_values['customized'];
- }
- break;
-
- case 'untranslated':
- $conditions['translated'] = FALSE;
- break;
-
- }
-
- if (!empty($filter_values['string'])) {
- $options['filters']['source'] = $filter_values['string'];
- if ($options['translated']) {
- $options['filters']['translation'] = $filter_values['string'];
- }
- }
-
- return Drupal::service('locale.storage')->getTranslations($conditions, $options);
-}
-
-/**
- * Build array out of search criteria specified in request variables.
- */
-function locale_translate_filter_values() {
- $filter_values = &drupal_static(__FUNCTION__);
- if (!isset($filter_values)) {
- $filter_values = array();
- $filters = locale_translate_filters();
- foreach ($filters as $key => $filter) {
- $filter_values[$key] = $filter['default'];
- // Let the filter defaults be overwritten by parameters in the URL.
- if (isset($_GET[$key])) {
- // Only allow this value if it was among the options, or
- // if there were no fixed options to filter for.
- if (!isset($filter['options']) || isset($filter['options'][$_GET[$key]])) {
- $filter_values[$key] = $_GET[$key];
- }
- }
- elseif (isset($_SESSION['locale_translate_filter'][$key])) {
- // Only allow this value if it was among the options, or
- // if there were no fixed options to filter for.
- if (!isset($filter['options']) || isset($filter['options'][$_SESSION['locale_translate_filter'][$key]])) {
- $filter_values[$key] = $_SESSION['locale_translate_filter'][$key];
- }
- }
- }
- }
- return $filter_values;
-}
-
-/**
- * List locale translation filters that can be applied.
- */
-function locale_translate_filters() {
- $filters = array();
-
- // Get all languages, except English.
- drupal_static_reset('language_list');
- $languages = language_list();
- $language_options = array();
- foreach ($languages as $langcode => $language) {
- if ($langcode != 'en' || locale_translate_english()) {
- $language_options[$langcode] = $language->name;
- }
- }
-
- // Pick the current interface language code for the filter.
- $default_langcode = language(Language::TYPE_INTERFACE)->id;
- if (!isset($language_options[$default_langcode])) {
- $available_langcodes = array_keys($language_options);
- $default_langcode = array_shift($available_langcodes);
- }
-
- $filters['string'] = array(
- 'title' => t('String contains'),
- 'description' => t('Leave blank to show all strings. The search is case sensitive.'),
- 'default' => '',
- );
-
- $filters['langcode'] = array(
- 'title' => t('Translation language'),
- 'options' => $language_options,
- 'default' => $default_langcode,
- );
-
- $filters['translation'] = array(
- 'title' => t('Search in'),
- 'options' => array(
- 'all' => t('Both translated and untranslated strings'),
- 'translated' => t('Only translated strings'),
- 'untranslated' => t('Only untranslated strings'),
- ),
- 'default' => 'all',
- );
-
- $filters['customized'] = array(
- 'title' => t('Translation type'),
- 'options' => array(
- 'all' => t('All'),
- LOCALE_NOT_CUSTOMIZED => t('Non-customized translation'),
- LOCALE_CUSTOMIZED => t('Customized translation'),
- ),
- 'states' => array(
- 'visible' => array(
- ':input[name=translation]' => array('value' => 'translated'),
- ),
- ),
- 'default' => 'all',
- );
-
- return $filters;
-}
-
-/**
- * Return form for locale translation filters.
- *
- * @ingroup forms
- */
-function locale_translate_filter_form($form, &$form_state) {
- $filters = locale_translate_filters();
- $filter_values = locale_translate_filter_values();
-
- $form['#attached']['css'] = array(
- drupal_get_path('module', 'locale') . '/css/locale.admin.css',
- );
-
- $form['filters'] = array(
- '#type' => 'details',
- '#title' => t('Filter translatable strings'),
- '#collapsed' => FALSE,
- );
- foreach ($filters as $key => $filter) {
- // Special case for 'string' filter.
- if ($key == 'string') {
- $form['filters']['status']['string'] = array(
- '#type' => 'search',
- '#title' => $filter['title'],
- '#description' => $filter['description'],
- '#default_value' => $filter_values[$key],
- );
- }
- else {
- $empty_option = isset($filter['options'][$filter['default']]) ? $filter['options'][$filter['default']] : '- None -';
- $form['filters']['status'][$key] = array(
- '#title' => $filter['title'],
- '#type' => 'select',
- '#empty_value' => $filter['default'],
- '#empty_option' => $empty_option,
- '#size' => 0,
- '#options' => $filter['options'],
- '#default_value' => $filter_values[$key],
- );
- if (isset($filter['states'])) {
- $form['filters']['status'][$key]['#states'] = $filter['states'];
- }
- }
- }
-
- $form['filters']['actions'] = array(
- '#type' => 'actions',
- '#attributes' => array('class' => array('container-inline')),
- );
- $form['filters']['actions']['submit'] = array(
- '#type' => 'submit',
- '#value' => t('Filter'),
- );
- if (!empty($_SESSION['locale_translate_filter'])) {
- $form['filters']['actions']['reset'] = array(
- '#type' => 'submit',
- '#value' => t('Reset'),
- );
- }
-
- return $form;
-}
-
-/**
- * Process result from locale translation filter form.
- */
-function locale_translate_filter_form_submit($form, &$form_state) {
- $op = $form_state['values']['op'];
- $filters = locale_translate_filters();
- switch ($op) {
- case t('Filter'):
- foreach ($filters as $name => $filter) {
- if (isset($form_state['values'][$name])) {
- $_SESSION['locale_translate_filter'][$name] = $form_state['values'][$name];
- }
- }
- break;
-
- case t('Reset'):
- $_SESSION['locale_translate_filter'] = array();
- break;
-
- }
-
- $form_state['redirect'] = 'admin/config/regional/translate/translate';
-}
-
-/**
- * Form constructor for the string editing form.
- *
- * @see locale_menu()
- * @see locale_translate_edit_form_validate()
- * @see locale_translate_edit_form_submit()
- *
- * @ingroup forms
- */
-function locale_translate_edit_form($form, &$form_state) {
- $filter_values = locale_translate_filter_values();
- $langcode = $filter_values['langcode'];
-
- drupal_static_reset('language_list');
- $languages = language_list();
-
- $langname = isset($langcode) ? $languages[$langcode]->name : "- None -";
-
- $path = drupal_get_path('module', 'locale');
- $form['#attached']['css'] = array(
- $path . '/css/locale.admin.css',
- );
- $form['#attached']['library'][] = array('locale', 'drupal.locale.admin');
-
- $form['langcode'] = array(
- '#type' => 'value',
- '#value' => $filter_values['langcode'],
- );
-
- $form['strings'] = array(
- '#type' => 'item',
- '#tree' => TRUE,
- '#language' => $langname,
- '#theme' => 'locale_translate_edit_form_strings',
- );
-
- if (isset($langcode)) {
- $strings = locale_translate_filter_load_strings();
-
- $plural_formulas = Drupal::state()->get('locale.translation.plurals') ?: array();
-
- foreach ($strings as $string) {
- // Cast into source string, will do for our purposes.
- $source = new SourceString($string);
- // Split source to work with plural values.
- $source_array = $source->getPlurals();
- $translation_array = $string->getPlurals();
- if (count($source_array) == 1) {
- // Add original string value and mark as non-plural.
- $form['strings'][$string->lid]['plural'] = array(
- '#type' => 'value',
- '#value' => 0,
- );
- $form['strings'][$string->lid]['original'] = array(
- '#type' => 'item',
- '#title' => t('Source string (@language)', array('@language' => t('Built-in English'))),
- '#title_display' => 'invisible',
- '#markup' => '' . check_plain($source_array[0]) . '',
- );
- }
- else {
- // Add original string value and mark as plural.
- $form['strings'][$string->lid]['plural'] = array(
- '#type' => 'value',
- '#value' => 1,
- );
- $form['strings'][$string->lid]['original_singular'] = array(
- '#type' => 'item',
- '#title' => t('Singular form'),
- '#markup' => '' . check_plain($source_array[0]) . '',
- '#prefix' => '' . t('Source string (@language)', array('@language' => t('Built-in English'))) . '',
- );
- $form['strings'][$string->lid]['original_plural'] = array(
- '#type' => 'item',
- '#title' => t('Plural form'),
- '#markup' => '' . check_plain($source_array[1]) . '',
- );
- }
- if (!empty($string->context)) {
- $form['strings'][$string->lid]['context'] = array(
- '#type' => 'value',
- '#value' => '' . check_plain($string->context) . '',
- );
- }
- // Approximate the number of rows to use in the default textarea.
- $rows = min(ceil(str_word_count($source_array[0]) / 12), 10);
- if (empty($form['strings'][$string->lid]['plural']['#value'])) {
- $form['strings'][$string->lid]['translations'][0] = array(
- '#type' => 'textarea',
- '#title' => t('Translated string (@language)', array('@language' => $langname)),
- '#title_display' => 'invisible',
- '#rows' => $rows,
- '#default_value' => $translation_array[0],
- '#attributes' => array('lang' => $langcode),
- );
- }
- else {
- // Dealing with plural strings.
- if (isset($plural_formulas[$langcode]['plurals']) && $plural_formulas[$langcode]['plurals'] > 2) {
- // Add a textarea for each plural variant.
- for ($i = 0; $i < $plural_formulas[$langcode]['plurals']; $i++) {
- $form['strings'][$string->lid]['translations'][$i] = array(
- '#type' => 'textarea',
- '#title' => ($i == 0 ? t('Singular form') : format_plural($i, 'First plural form', '@count. plural form')),
- '#rows' => $rows,
- '#default_value' => isset($translation_array[$i]) ? $translation_array[$i] : '',
- '#attributes' => array('lang' => $langcode),
- '#prefix' => $i == 0 ? ('' . t('Translated string (@language)', array('@language' => $langname)) . '') : '',
- );
- }
- }
- else {
- // Fallback for unknown number of plurals.
- $form['strings'][$string->lid]['translations'][0] = array(
- '#type' => 'textarea',
- '#title' => t('Singular form'),
- '#rows' => $rows,
- '#default_value' => $translation_array[0],
- '#attributes' => array('lang' => $langcode),
- '#prefix' => '' . t('Translated string (@language)', array('@language' => $langname)) . '',
- );
- $form['strings'][$string->lid]['translations'][1] = array(
- '#type' => 'textarea',
- '#title' => t('Plural form'),
- '#rows' => $rows,
- '#default_value' => isset($translation_array[1]) ? $translation_array[1] : '',
- '#attributes' => array('lang' => $langcode),
- );
- }
- }
- }
- if (count(element_children($form['strings']))) {
- $form['actions'] = array('#type' => 'actions');
- $form['actions']['submit'] = array('#type' => 'submit', '#value' => t('Save translations'));
- }
- }
- return $form;
-}
-
-/**
- * Form validation handler for locale_translate_edit_form().
- *
- * @see locale_translate_edit_form_submit()
- */
-function locale_translate_edit_form_validate($form, &$form_state) {
- $langcode = $form_state['values']['langcode'];
- foreach ($form_state['values']['strings'] as $lid => $translations) {
- foreach ($translations['translations'] as $key => $value) {
- if (!locale_string_is_safe($value)) {
- form_set_error("strings][$lid][translations][$key", t('The submitted string contains disallowed HTML: %string', array('%string' => $value)));
- form_set_error("translations][$langcode][$key", t('The submitted string contains disallowed HTML: %string', array('%string' => $value)));
- watchdog('locale', 'Attempted submission of a translation string with disallowed HTML: %string', array('%string' => $value), WATCHDOG_WARNING);
- }
- }
- }
-}
-
-/**
- * Form submission handler for locale_translate_edit_form().
- *
- * @see locale_translate_edit_form_validate()
- */
-function locale_translate_edit_form_submit($form, &$form_state) {
- $langcode = $form_state['values']['langcode'];
- $updated = array();
-
- // Preload all translations for strings in the form.
- $lids = array_keys($form_state['values']['strings']);
- $existing_translation_objects = array();
- foreach (Drupal::service('locale.storage')->getTranslations(array('lid' => $lids, 'language' => $langcode, 'translated' => TRUE)) as $existing_translation_object) {
- $existing_translation_objects[$existing_translation_object->lid] = $existing_translation_object;
- }
-
- foreach ($form_state['values']['strings'] as $lid => $new_translation) {
- $existing_translation = isset($existing_translation_objects[$lid]);
-
- // Plural translations are saved in a delimited string. To be able to
- // compare the new strings with the existing strings a string in the same format is created.
- $new_translation_string_delimited = implode(LOCALE_PLURAL_DELIMITER, $new_translation['translations']);
-
- // Generate an imploded string without delimiter, to be able to run
- // empty() on it.
- $new_translation_string = implode('', $new_translation['translations']);
-
- $is_changed = FALSE;
-
- if ($existing_translation && $existing_translation_objects[$lid]->translation != $new_translation_string_delimited) {
- // If there is an existing translation in the DB and the new translation
- // is not the same as the existing one.
- $is_changed = TRUE;
- }
- elseif (!$existing_translation && !empty($new_translation_string)) {
- // Newly entered translation.
- $is_changed = TRUE;
- }
-
- if ($is_changed) {
- // Only update or insert if we have a value to use.
- $target = isset($existing_translation_objects[$lid]) ? $existing_translation_objects[$lid] : Drupal::service('locale.storage')->createTranslation(array('lid' => $lid, 'language' => $langcode));
- $target->setPlurals($new_translation['translations'])
- ->setCustomized()
- ->save();
- $updated[] = $target->getId();
- }
- if (empty($new_translation_string) && isset($existing_translation_objects[$lid])) {
- // Empty new translation entered: remove existing entry from database.
- $existing_translation_objects[$lid]->delete();
- $updated[] = $lid;
- }
- }
-
- drupal_set_message(t('The strings have been saved.'));
-
- // Keep the user on the current pager page.
- if (isset($_GET['page'])) {
- $form_state['redirect'] = array('admin/config/regional/translate', array('query' => array('page' => $_GET['page'])));
- }
-
- if ($updated) {
- // Clear cache and refresh configuration and JavaScript translations.
- _locale_refresh_translations(array($langcode), $updated);
- _locale_refresh_configuration(array($langcode), $updated);
- }
-
-}
-
-/**
* Page callback: Checks for translation updates and displays the translations status.
*
* Manually checks the translation status without the use of cron.
diff --git a/core/modules/locale/locale.routing.yml b/core/modules/locale/locale.routing.yml
index a2a5820..f5df75c 100644
--- a/core/modules/locale/locale.routing.yml
+++ b/core/modules/locale/locale.routing.yml
@@ -4,3 +4,10 @@ locale_settings:
_form: 'Drupal\locale\Form\LocaleSettingsForm'
requirements:
_permission: 'translate interface'
+
+locale_translate_page:
+ pattern: '/admin/config/regional/translate'
+ defaults:
+ _content: 'Drupal\locale\Controller\LocaleController::translatePage'
+ requirements:
+ _permission: 'translate interface'
diff --git a/core/modules/toolbar/lib/Drupal/toolbar/Tests/ToolbarMenuTranslationTest.php b/core/modules/toolbar/lib/Drupal/toolbar/Tests/ToolbarMenuTranslationTest.php
index 02c01d4..949d565 100644
--- a/core/modules/toolbar/lib/Drupal/toolbar/Tests/ToolbarMenuTranslationTest.php
+++ b/core/modules/toolbar/lib/Drupal/toolbar/Tests/ToolbarMenuTranslationTest.php
@@ -59,7 +59,7 @@ function testToolbarClasses() {
'langcode' => $langcode,
'translation' => 'untranslated',
);
- $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
+ $this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
// Make sure will be able to translate the menu item.
$this->assertNoText('No strings available.', 'Search found the menu item as untranslated.');
@@ -74,7 +74,7 @@ function testToolbarClasses() {
$edit = array(
$lid => $menu_item_translated,
);
- $this->drupalPost('admin/config/regional/translate/translate', $edit, t('Save translations'));
+ $this->drupalPost('admin/config/regional/translate', $edit, t('Save translations'));
// Search for the translated menu item.
$search = array(
@@ -82,7 +82,7 @@ function testToolbarClasses() {
'langcode' => $langcode,
'translation' => 'translated',
);
- $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
+ $this->drupalPost('admin/config/regional/translate', $search, t('Filter'));
// Make sure the menu item string was translated.
$this->assertText($menu_item_translated, 'Search found the menu item as translated: ' . $menu_item_translated . '.');