diff --git a/core/modules/content_translation/content_translation.install b/core/modules/content_translation/content_translation.install index a8d4c49..b25d0b0 100644 --- a/core/modules/content_translation/content_translation.install +++ b/core/modules/content_translation/content_translation.install @@ -5,8 +5,7 @@ * Installation functions for Content Translation module. */ -use Drupal\Core\Language\LanguageInterface; -use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationUrl; +use Drupal\content_translation\Plugin\LanguageNegotiation\ContentTranslationFormLanguage; /** * Implements hook_install(). @@ -15,6 +14,11 @@ function content_translation_install() { // Assign a fairly low weight to ensure our implementation of // hook_module_implements_alter() is run among the last ones. module_set_weight('content_translation', 10); + + // Initialize the Content Translation form language type configuration. + /** @var \Drupal\language\LanguageNegotiatorInterface $negotiator */ + $negotiator = \Drupal::service('language_negotiator'); + $negotiator->updateConfiguration([ContentTranslationFormLanguage::TYPE]); } /** diff --git a/core/modules/content_translation/content_translation.module b/core/modules/content_translation/content_translation.module index 2e13417..abc417d 100644 --- a/core/modules/content_translation/content_translation.module +++ b/core/modules/content_translation/content_translation.module @@ -77,6 +77,7 @@ function content_translation_module_implements_alter(&$implementations, $hook) { function content_translation_language_types_info() { return [ ContentTranslationFormLanguage::TYPE => array( + 'name' => t('Content Translation form language'), 'fixed' => [ContentTranslationFormLanguage::METHOD_ID], 'locked' => TRUE, ), @@ -325,19 +326,27 @@ function content_translation_form_alter(array &$form, FormStateInterface $form_s /** * Implements hook_entity_prepare_form(). - * - * Load an entity form in specific language as requested by URL query option. */ function content_translation_entity_prepare_form(EntityInterface $entity, $operation, FormStateInterface $form_state) { - if ($entity instanceof ContentEntityInterface && count($entity->getTranslationLanguages()) > 1) { - $langcode = \Drupal::languageManager()->getCurrentLanguage(ContentTranslationFormLanguage::TYPE)->getId(); - if ($langcode && $entity->language()->getId() != $langcode && $entity->hasTranslation($langcode)) { - /** @var \Drupal\Core\Entity\EntityFormInterface $form_object*/ - $form_object = $form_state->getFormObject(); - $translation = $entity->getTranslation($langcode); - $form_object->setEntity($translation); - $form_state->set('langcode', $langcode); - } + // If the Content Translation form language differs from the current form + // language and we are editing an entity translation, we need to update the + // form language to match the specified value. + $langcode = NULL; + $prepare_translation = + $entity instanceof ContentEntityInterface && + count($entity->getTranslationLanguages()) > 1 && + !$form_state->get(['content_translation', 'source']) && + !$form_state->get(['content_translation', 'translation_form']) && + ($langcode = \Drupal::languageManager()->getCurrentLanguage(ContentTranslationFormLanguage::TYPE)->getId()) && + $entity->language()->getId() != $langcode + && $entity->hasTranslation($langcode); + + if ($prepare_translation) { + /** @var \Drupal\Core\Entity\EntityFormInterface $form_object*/ + $form_object = $form_state->getFormObject(); + $translation = $entity->getTranslation($langcode); + $form_object->setEntity($translation); + $form_state->set('langcode', $langcode); } } diff --git a/core/modules/content_translation/src/Plugin/LanguageNegotiation/ContentTranslationFormLanguage.php b/core/modules/content_translation/src/Plugin/LanguageNegotiation/ContentTranslationFormLanguage.php index ea0444e..4e77d96 100644 --- a/core/modules/content_translation/src/Plugin/LanguageNegotiation/ContentTranslationFormLanguage.php +++ b/core/modules/content_translation/src/Plugin/LanguageNegotiation/ContentTranslationFormLanguage.php @@ -43,8 +43,8 @@ class ContentTranslationFormLanguage extends LanguageNegotiationMethodBase { * {@inheritdoc} */ public function getLangcode(Request $request = NULL) { - $content_translation_target = $request->get(static::QUERY_PARAMETER); - return $content_translation_target ?: $this->languageManager->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)->getId(); + $langcode = $request->get(static::QUERY_PARAMETER); + return $langcode ?: $this->languageManager->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)->getId(); } } diff --git a/core/modules/content_translation/src/Tests/ContentTranslationUITestBase.php b/core/modules/content_translation/src/Tests/ContentTranslationUITestBase.php index d0fc4f6..41809bb 100644 --- a/core/modules/content_translation/src/Tests/ContentTranslationUITestBase.php +++ b/core/modules/content_translation/src/Tests/ContentTranslationUITestBase.php @@ -7,6 +7,7 @@ namespace Drupal\content_translation\Tests; +use Drupal\content_translation\Plugin\LanguageNegotiation\ContentTranslationFormLanguage; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Language\Language; use Drupal\Core\Language\LanguageInterface; @@ -133,16 +134,19 @@ protected function doTestBasicTranslation() { */ protected function doTestTranslationOverview() { $entity = entity_load($this->entityTypeId, $this->entityId, TRUE); - $this->drupalGet($entity->urlInfo('drupal:content-translation-overview')); + $translate_url = $entity->urlInfo('drupal:content-translation-overview'); + $this->drupalGet($translate_url); + $translate_url->setAbsolute(FALSE); foreach ($this->langcodes as $langcode) { if ($entity->hasTranslation($langcode)) { $language = new Language(array('id' => $langcode)); - $view_path = $entity->url('canonical', array('language' => $language)); - $elements = $this->xpath('//table//a[@href=:href]', array(':href' => $view_path)); + $view_url = $entity->url('canonical', ['language' => $language]); + $elements = $this->xpath('//table//a[@href=:href]', array(':href' => $view_url)); $this->assertEqual((string) $elements[0], $entity->getTranslation($langcode)->label(), format_string('Label correctly shown for %language translation.', array('%language' => $langcode))); - $edit_path = $entity->url('edit-form', array('language' => $language)); - $elements = $this->xpath('//table//ul[@class="dropbutton"]/li/a[@href=:href]', array(':href' => $edit_path)); + $query = [ContentTranslationFormLanguage::QUERY_PARAMETER => $langcode, 'destination' => $translate_url->toString()]; + $edit_url = $entity->url('edit-form', ['query' => $query]); + $elements = $this->xpath('//table//ul[@class="dropbutton"]/li/a[@href=:href]', array(':href' => $edit_url)); $this->assertEqual((string) $elements[0], t('Edit'), format_string('Edit link correct for %language translation.', array('%language' => $langcode))); } } diff --git a/core/modules/content_translation/src/Tests/ContentTranslationWorkflowsTest.php b/core/modules/content_translation/src/Tests/ContentTranslationWorkflowsTest.php index 62daf75..ec95891 100644 --- a/core/modules/content_translation/src/Tests/ContentTranslationWorkflowsTest.php +++ b/core/modules/content_translation/src/Tests/ContentTranslationWorkflowsTest.php @@ -7,6 +7,7 @@ namespace Drupal\content_translation\Tests; +use Drupal\content_translation\Plugin\LanguageNegotiation\ContentTranslationFormLanguage; use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Url; use Drupal\user\UserInterface; @@ -150,7 +151,6 @@ protected function assertWorkflows(UserInterface $user, $expected_status) { $langcode = $this->langcodes[2]; $options['language'] = $languages[$langcode]; $edit_translation_url = Url::fromRoute('content_translation.translation_edit_' . $this->entityTypeId, [$this->entityTypeId => $this->entity->id(), 'language' => $langcode], $options); - $options = ['language' => $languages[$langcode], 'absolute' => TRUE]; if ($expected_status['edit_translation'] == 200) { $this->drupalGet($translations_url); $editor = $expected_status['edit'] == 200; @@ -160,8 +160,12 @@ protected function assertWorkflows(UserInterface $user, $expected_status) { // An editor should be pointed to the entity form in multilingual mode. // We need a new expected edit path with a new language. - $expected_edit_path = $this->entity->url('edit-form', $options); - $this->assertUrl($expected_edit_path, [], 'The translation overview points to the edit form for editors when editing translations.'); + $translate_url = $this->entity->urlInfo('drupal:content-translation-overview', ['language' => $languages[$this->langcodes[1]]]); + $translate_url->setAbsolute(FALSE); + $query = [ContentTranslationFormLanguage::QUERY_PARAMETER => $langcode, 'destination' => $translate_url->toString()]; + $options = ['query' => $query]; + $expected_edit_url = $this->entity->url('edit-form', $options); + $this->assertUrl($expected_edit_url, [], 'The translation overview points to the edit form for editors when editing translations.'); } else { $this->clickLink('Edit');