diff -u b/core/modules/content_translation/content_translation.module b/core/modules/content_translation/content_translation.module --- b/core/modules/content_translation/content_translation.module +++ b/core/modules/content_translation/content_translation.module @@ -14,7 +14,6 @@ use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\StringTranslation\TranslatableString; -use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationContentLanguage; /** * Implements hook_help(). @@ -140,7 +139,11 @@ if ($entity_type->hasLinkTemplate('canonical')) { // Provide default route names for the translation paths. if (!$entity_type->hasLinkTemplate('drupal:content-translation-overview')) { - $entity_type->setLinkTemplate('drupal:content-translation-overview', $entity_type->getLinkTemplate('canonical') . '/translations'); + $translations_path = $entity_type->getLinkTemplate('canonical') . '/translations'; + $entity_type->setLinkTemplate('drupal:content-translation-overview', $translations_path); + $entity_type->setLinkTemplate('drupal:content-translation-add', $translations_path . '/add/{source}/{target}'); + $entity_type->setLinkTemplate('drupal:content-translation-edit', $translations_path . '/edit/{language}'); + $entity_type->setLinkTemplate('drupal:content-translation-delete', $translations_path . '/delete/{language}'); } // @todo Remove this as soon as menu access checks rely on the // controller. See https://www.drupal.org/node/2155787. @@ -583,22 +585,0 @@ - -/** - * Implements hook_menu_local_tasks_alter(). - * - * Marks the local tasks urls to be overwritten by LanguageNegotiationContentLanguage. - * - * @param $data - * @param $route_name - */ -function content_translation_menu_local_tasks_alter(&$data, $route_name) { - if (\Drupal::request()->get(LanguageNegotiationContentLanguage::QUERY_PARAMETER)) { - foreach ($data as &$tabs) { - foreach ($tabs as &$tab) { - foreach ($tab as $local_task_route_name => &$local_task_tab) { - /** @var \Drupal\Core\Url $url*/ - $url = $local_task_tab['#link']['url']; - $url->setOption(LanguageNegotiationContentLanguage::OVERWRITE_OPTION, TRUE); - } - } - } - } -} \ No newline at end of file diff -u b/core/modules/content_translation/src/Controller/ContentTranslationController.php b/core/modules/content_translation/src/Controller/ContentTranslationController.php --- b/core/modules/content_translation/src/Controller/ContentTranslationController.php +++ b/core/modules/content_translation/src/Controller/ContentTranslationController.php @@ -14,7 +14,6 @@ use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Url; -use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationContentLanguage; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -128,7 +127,7 @@ $langcode = $language->getId(); $add_url = new Url( - 'content_translation.translation_add_' . $entity_type_id, + "entity.$entity_type_id.content_translation_add", array( 'source' => $original, 'target' => $language->getId(), @@ -136,12 +135,10 @@ ), array( 'language' => $language, - LanguageNegotiationContentLanguage::OVERWRITE_OPTION => FALSE, - 'query' => ['content_language' => $langcode], ) ); $edit_url = new Url( - 'content_translation.translation_edit_' . $entity_type_id, + "entity.$entity_type_id.content_translation_edit", array( 'language' => $language->getId(), $entity_type_id => $entity->id(), @@ -151,7 +148,7 @@ ) ); $delete_url = new Url( - 'content_translation.translation_delete_' . $entity_type_id, + "entity.$entity_type_id.content_translation_delete", array( 'language' => $language->getId(), $entity_type_id => $entity->id(), @@ -178,11 +175,6 @@ $link = isset($links->links[$langcode]['url']) ? $links->links[$langcode] : array('url' => $entity->urlInfo()); if (!empty($link['url'])) { $link['url']->setOption('language', $language); - - // Turn off content language propagation and set it explicitly. - $link['url']->setOption(LanguageNegotiationContentLanguage::OVERWRITE_OPTION, FALSE); - $link['url']->setOption('query', ['content_language' => $langcode]); - $row_title = $this->l($label, $link['url']); } @@ -206,10 +198,6 @@ $links['edit']['url'] = $edit_url; } - // Turn off content language propagation and set it explicitly. - $links['edit']['url']->setOption(LanguageNegotiationContentLanguage::OVERWRITE_OPTION, FALSE); - $links['edit']['url']->setOption('query', ['content_language' => $langcode]); - if (isset($links['edit'])) { $links['edit']['title'] = $this->t('Edit'); } @@ -246,10 +234,6 @@ 'url' => $delete_url, ); } - - // Turn off content language propagation and set it explicitly. - $links['delete']['url']->setOption(LanguageNegotiationContentLanguage::OVERWRITE_OPTION, FALSE); - $links['delete']['url']->setOption('query', ['content_language' => $langcode]); } } else { diff -u b/core/modules/content_translation/src/Tests/ContentTranslationUITestBase.php b/core/modules/content_translation/src/Tests/ContentTranslationUITestBase.php --- b/core/modules/content_translation/src/Tests/ContentTranslationUITestBase.php +++ b/core/modules/content_translation/src/Tests/ContentTranslationUITestBase.php @@ -14,7 +14,6 @@ use Drupal\Core\Url; use Drupal\language\Entity\ConfigurableLanguage; use Drupal\Component\Utility\SafeMarkup; -use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationContentLanguage; use Drupal\system\Tests\Cache\AssertPageCacheContextsAndTagsTrait; /** @@ -65,7 +64,6 @@ $this->doTestPublishedStatus(); $this->doTestAuthoringInfo(); $this->doTestTranslationEdit(); - $this->doTestFormLanguageSwitch(); $this->doTestTranslationChanged(); $this->doTestTranslationDeletion(); } @@ -108,7 +106,8 @@ $language = ConfigurableLanguage::load($langcode); $values[$langcode] = $this->getNewEntityValues($langcode); - $add_url = Url::fromRoute('content_translation.translation_add_' . $entity->getEntityTypeId(), [ + $entity_type_id = $entity->getEntityTypeId(); + $add_url = Url::fromRoute("entity.$entity_type_id.content_translation_add", [ $entity->getEntityTypeId() => $entity->id(), 'source' => $default_langcode, 'target' => $langcode @@ -168,7 +167,8 @@ $language = ConfigurableLanguage::load($langcode); $source_langcode = 'it'; $edit = array('source_langcode[source]' => $source_langcode); - $add_url = Url::fromRoute('content_translation.translation_add_' . $entity->getEntityTypeId(), [ + $entity_type_id = $entity->getEntityTypeId(); + $add_url = Url::fromRoute("entity.$entity_type_id.content_translation_add", [ $entity->getEntityTypeId() => $entity->id(), 'source' => $default_langcode, 'target' => $langcode @@ -181,7 +181,8 @@ // Add another translation and mark the other ones as outdated. $values[$langcode] = $this->getNewEntityValues($langcode); $edit = $this->getEditValues($values, $langcode) + array('content_translation[retranslate]' => TRUE); - $add_url = Url::fromRoute('content_translation.translation_add_' . $entity->getEntityTypeId(), [ + $entity_type_id = $entity->getEntityTypeId(); + $add_url = Url::fromRoute("entity.$entity_type_id.content_translation_add", [ $entity->getEntityTypeId() => $entity->id(), 'source' => $source_langcode, 'target' => $langcode @@ -218,9 +219,8 @@ $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))); - $query = [LanguageNegotiationContentLanguage::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)); + $edit_path = $entity->url('edit-form', array('language' => $language)); + $elements = $this->xpath('//table//ul[@class="dropbutton"]/li/a[@href=:href]', array(':href' => $edit_path)); $this->assertEqual((string) $elements[0], t('Edit'), format_string('Edit link correct for %language translation.', array('%language' => $langcode))); } } @@ -328,20 +328,6 @@ } /** - * Tests the form language switch functionality. - */ - protected function doTestFormLanguageSwitch() { - $entity = entity_load($this->entityTypeId, $this->entityId, TRUE); - - $message = 'The form language can be switched to @langcode through a query string parameter'; - foreach ($entity->getTranslationLanguages() as $langcode => $language) { - $url = $entity->urlInfo('edit-form', ['query' => ['content_translation_target' => $langcode]]); - $this->drupalGet($url); - $this->assertRaw($entity->getTranslation($langcode)->{$this->fieldName}->value, format_string($message, array('@langcode' => $langcode))); - } - } - - /** * Tests translation deletion. */ protected function doTestTranslationDeletion() { @@ -361,7 +347,7 @@ // Check that the translator cannot delete the original translation. $args = [$this->entityTypeId => $entity->id(), 'language' => 'en']; - $this->drupalGet(Url::fromRoute('content_translation.translation_delete_' . $this->entityTypeId, $args)); + $this->drupalGet(Url::fromRoute("entity.$this->entityTypeId.content_translation_delete", $args)); $this->assertResponse(403); } diff -u b/core/modules/content_translation/src/Tests/ContentTranslationWorkflowsTest.php b/core/modules/content_translation/src/Tests/ContentTranslationWorkflowsTest.php --- b/core/modules/content_translation/src/Tests/ContentTranslationWorkflowsTest.php +++ b/core/modules/content_translation/src/Tests/ContentTranslationWorkflowsTest.php @@ -10,7 +10,6 @@ use Drupal\Component\Utility\SafeMarkup; use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Url; -use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationContentLanguage; use Drupal\user\UserInterface; /** @@ -74,7 +73,7 @@ // Create a translation. $this->drupalLogin($this->translator); - $add_translation_url = Url::fromRoute('content_translation.translation_add_' . $this->entityTypeId, [$this->entityTypeId => $this->entity->id(), 'source' => $default_langcode, 'target' => $this->langcodes[2]]); + $add_translation_url = Url::fromRoute("entity.$this->entityTypeId.content_translation_add", [$this->entityTypeId => $this->entity->id(), 'source' => $default_langcode, 'target' => $this->langcodes[2]]); $this->drupalPostForm($add_translation_url, array(), t('Save')); $this->rebuildContainer(); } @@ -176,7 +175,7 @@ $this->assertResponse($expected_status['overview'], SafeMarkup::format('The @user_label has the expected translation overview access.', $args)); // Check whether the user is allowed to create a translation. - $add_translation_url = Url::fromRoute('content_translation.translation_add_' . $this->entityTypeId, [$this->entityTypeId => $this->entity->id(), 'source' => $default_langcode, 'target' => $langcode], $options); + $add_translation_url = Url::fromRoute("entity.$this->entityTypeId.content_translation_add", [$this->entityTypeId => $this->entity->id(), 'source' => $default_langcode, 'target' => $langcode], $options); if ($expected_status['add_translation'] == 200) { $this->clickLink('Add'); $this->assertUrl($add_translation_url->toString(), [], 'The translation overview points to the translation form when creating translations.'); @@ -194,7 +193,7 @@ // Check whether the user is allowed to edit a translation. $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); + $edit_translation_url = Url::fromRoute("entity.$this->entityTypeId.content_translation_edit", [$this->entityTypeId => $this->entity->id(), 'language' => $langcode], $options); if ($expected_status['edit_translation'] == 200) { $this->drupalGet($translations_url); $editor = $expected_status['edit'] == 200; @@ -203,10 +202,8 @@ $this->clickLink('Edit', 2); // An editor should be pointed to the entity form in multilingual mode. // We need a new expected edit path with a new language. - $translate_url = $this->entity->url('drupal:content-translation-overview', ['language' => $languages[$this->langcodes[1]], 'absolute' => FALSE]); - $options = ['query' => [LanguageNegotiationContentLanguage::QUERY_PARAMETER => $langcode, 'destination' => $translate_url]]; - $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.'); + $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.'); } else { $this->clickLink('Edit'); @@ -224,7 +221,7 @@ // Check whether the user is allowed to delete a translation. $langcode = $this->langcodes[2]; $options['language'] = $languages[$langcode]; - $delete_translation_url = Url::fromRoute('content_translation.translation_delete_' . $this->entityTypeId, [$this->entityTypeId => $this->entity->id(), 'language' => $langcode], $options); + $delete_translation_url = Url::fromRoute("entity.$this->entityTypeId.content_translation_delete", [$this->entityTypeId => $this->entity->id(), 'language' => $langcode], $options); if ($expected_status['delete_translation'] == 200) { $this->drupalGet($translations_url); $editor = $expected_status['delete'] == 200; reverted: --- b/core/modules/language/config/install/language.types.yml +++ a/core/modules/language/config/install/language.types.yml @@ -4,12 +4,10 @@ - language_url configurable: - language_interface - - language_content negotiation: language_content: enabled: + language-interface: 0 - language-content: 0 - language-interface: 1 language_url: enabled: language-url: 0 reverted: --- b/core/modules/language/language.module +++ a/core/modules/language/language.module @@ -20,7 +20,6 @@ use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationUI; use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationUrl; use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationUrlFallback; -use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationContentLanguage; /** * Implements hook_help(). @@ -503,6 +502,6 @@ * enabled and we can't be sure of that in the LanguageManager. */ function language_language_types_info_alter(array &$language_types) { + $language_types[LanguageInterface::TYPE_CONTENT]['fixed'] = [LanguageNegotiationUI::METHOD_ID]; - $language_types[LanguageInterface::TYPE_CONTENT]['fixed'] = [LanguageNegotiationContentLanguage::METHOD_ID, LanguageNegotiationUI::METHOD_ID]; $language_types[LanguageInterface::TYPE_URL]['fixed'] = [LanguageNegotiationUrl::METHOD_ID, LanguageNegotiationUrlFallback::METHOD_ID]; } diff -u b/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationContentLanguage.php b/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationContentLanguage.php --- b/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationContentLanguage.php +++ b/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationContentLanguage.php @@ -11,7 +11,9 @@ use Drupal\Component\Utility\UrlHelper; use Drupal\Core\PathProcessor\OutboundPathProcessorInterface; use Drupal\Core\Render\BubbleableMetadata; +use Drupal\Core\Url; use Drupal\language\LanguageNegotiationMethodBase; +use Drupal\language\LanguageSwitcherInterface; use Symfony\Component\HttpFoundation\Request; /** @@ -20,12 +22,12 @@ * @LanguageNegotiation( * id = Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationContentLanguage::METHOD_ID, * types = {Drupal\Core\Language\LanguageInterface::TYPE_CONTENT}, - * weight = -8, + * weight = -9, * name = @Translation("Content language"), * description = @Translation("Determines the translation language from a request parameter."), * ) */ -class LanguageNegotiationContentLanguage extends LanguageNegotiationMethodBase implements OutboundPathProcessorInterface { +class LanguageNegotiationContentLanguage extends LanguageNegotiationMethodBase implements OutboundPathProcessorInterface, LanguageSwitcherInterface { /** * The language negotiation method id. @@ -33,14 +35,16 @@ const METHOD_ID = 'language-content'; /** - * The url option specifying if overwrite is enabled. + * The query string parameter. */ - const OVERWRITE_OPTION = 'content_language_overwrite'; + const QUERY_PARAMETER = 'content_language'; /** - * The query string parameter. + * A list of all the link paths of enabled content entities. + * + * @var array */ - const QUERY_PARAMETER = 'content_language'; + protected $contentEntityPaths; /** * {@inheritdoc} @@ -58,21 +62,79 @@ public function processOutbound($path, &$options = array(), Request $request = NULL, BubbleableMetadata $bubbleable_metadata = NULL) { - if (isset($options[static::OVERWRITE_OPTION]) && $options[static::OVERWRITE_OPTION] && $request && ($langcode = $this->getLangcode($request))) { - if (isset($options['query']) && is_string($options['query'])) { - $query = array(); - parse_str($options['query'], $query); - $options['query'] = $query; - } - else { - $options['query'] = []; - } - if (!isset($options['query'][static::QUERY_PARAMETER])) { - $query_addon = [static::QUERY_PARAMETER => $this->getLangcode($request)]; - $options['query'] += $query_addon; - $path .= (strpos($path, '?') !== FALSE ? '&' : '?') . UrlHelper::buildQuery($query_addon); + // Only run if the LanguageNegotiationContentLanguage outbound function is + // being executed before the outbound function of LanguageNegotiationUrl. + $enabled_methods = $this->config->get('language.types')->get('negotiation.language_content.enabled') ? : []; + $run = isset($enabled_methods[LanguageNegotiationUrl::METHOD_ID]) ? $enabled_methods[static::METHOD_ID] < $enabled_methods[LanguageNegotiationUrl::METHOD_ID] : TRUE; + + if ($run && $request && isset($options['route_name']) && (isset($options['language']) || $langcode = $this->getLangcode($request))) { + $route_name = $options['route_name']; + $route_provider = \Drupal::getContainer()->get('router.route_provider'); + $route_name_path = $route_provider->getRouteByName($route_name)->getPath(); + + if (in_array($route_name_path, $this->getContentEntityPaths())) { + if (isset($options['language'])) { + $langcode = $options['language']->getId(); + unset($options['language']); + } + + if (isset($options['query']) && is_string($options['query'])) { + $query = array(); + parse_str($options['query'], $query); + $options['query'] = $query; + } + else { + $options['query'] = []; + } + if (!isset($options['query'][static::QUERY_PARAMETER])) { + $query_addon = [static::QUERY_PARAMETER => $langcode]; + $options['query'] += $query_addon; + $path .= (strpos($path, '?') !== FALSE ? '&' : '?') . UrlHelper::buildQuery($query_addon); + } } } return $path; } + /** + * {@inheritdoc} + */ + public function getLanguageSwitchLinks(Request $request, $type, Url $url) { + $links = []; + $query = []; + parse_str($request->getQueryString(), $query); + + foreach ($this->languageManager->getNativeLanguages() as $language) { + $langcode = $language->getId(); + $query[static::QUERY_PARAMETER] = $langcode; + $links[$langcode] = [ + 'url' => $url, + 'title' => $language->getName(), + 'attributes' => ['class' => ['language-link']], + 'query' => $query, + ]; + } + + return $links; + } + + /** + * Returns the paths for the link templates of all content entities. + * + * @return array + * The array of the link templates paths of all content entities. + */ + protected function getContentEntityPaths() { + if ($this->contentEntityPaths === NULL) { + $this->contentEntityPaths = []; + $entity_types = \Drupal::entityManager()->getDefinitions(); + foreach ($entity_types as $entity_type_id => $entity_type) { + if ($entity_type->isSubclassOf('\Drupal\Core\Entity\ContentEntityInterface')) { + $this->contentEntityPaths = array_merge($this->contentEntityPaths, array_values($entity_type->getLinkTemplates())); + } + } + } + + return $this->contentEntityPaths; + } + } only in patch2: unchanged: --- a/core/lib/Drupal/Core/Routing/UrlGenerator.php +++ b/core/lib/Drupal/Core/Routing/UrlGenerator.php @@ -310,6 +310,7 @@ public function generateFromRoute($name, $parameters = array(), $options = array $name = $this->getRouteDebugMessage($name); $this->processRoute($name, $route, $parameters, $generated_url); $path = $this->getInternalPathFromRoute($name, $route, $parameters, $query_params); + $options['route_name'] = $name; $path = $this->processPath($path, $options, $generated_url); if (!empty($options['prefix'])) { only in patch2: unchanged: --- a/core/modules/content_translation/src/ContentTranslationHandler.php +++ b/core/modules/content_translation/src/ContentTranslationHandler.php @@ -622,7 +622,7 @@ public function entityFormSourceChange($form, FormStateInterface $form_state) { $source = $form_state->getValue(array('source_langcode', 'source')); $entity_type_id = $entity->getEntityTypeId(); - $form_state->setRedirect('content_translation.translation_add_' . $entity_type_id, array( + $form_state->setRedirect("entity.$entity_type_id.content_translation_add", array( $entity_type_id => $entity->id(), 'source' => $source, 'target' => $form_object->getFormLangcode($form_state), @@ -659,7 +659,7 @@ function entityFormDeleteTranslation($form, FormStateInterface $form_state) { $form_state->setRedirectUrl($entity->urlInfo('delete-form')); } else { - $form_state->setRedirect('content_translation.translation_delete_' . $entity_type_id, [ + $form_state->setRedirect("entity.$entity_type_id.content_translation_delete", [ $entity_type_id => $entity->id(), 'language' => $form_object->getFormLangcode($form_state), ]); only in patch2: unchanged: --- a/core/modules/content_translation/src/Routing/ContentTranslationRouteSubscriber.php +++ b/core/modules/content_translation/src/Routing/ContentTranslationRouteSubscriber.php @@ -113,7 +113,7 @@ protected function alterRoutes(RouteCollection $collection) { '_admin_route' => $is_admin, ) ); - $collection->add("content_translation.translation_add_$entity_type_id", $route); + $collection->add("entity.$entity_type_id.content_translation_add", $route); $route = new Route( $path . '/edit/{language}', @@ -138,7 +138,7 @@ protected function alterRoutes(RouteCollection $collection) { '_admin_route' => $is_admin, ) ); - $collection->add("content_translation.translation_edit_$entity_type_id", $route); + $collection->add("entity.$entity_type_id.content_translation_edit", $route); $route = new Route( $path . '/delete/{language}', @@ -163,7 +163,7 @@ protected function alterRoutes(RouteCollection $collection) { '_admin_route' => $is_admin, ) ); - $collection->add("content_translation.translation_delete_$entity_type_id", $route); + $collection->add("entity.$entity_type_id.content_translation_delete", $route); } } only in patch2: unchanged: --- a/core/modules/language/src/HttpKernel/PathProcessorLanguage.php +++ b/core/modules/language/src/HttpKernel/PathProcessorLanguage.php @@ -125,16 +125,31 @@ public function processOutbound($path, &$options = array(), Request $request = N protected function initProcessors($scope) { $interface = '\Drupal\Core\PathProcessor\\' . Unicode::ucfirst($scope) . 'PathProcessorInterface'; $this->processors[$scope] = array(); + $weights = []; foreach ($this->languageManager->getLanguageTypes() as $type) { foreach ($this->negotiator->getNegotiationMethods($type) as $method_id => $method) { if (!isset($this->processors[$scope][$method_id])) { $reflector = new \ReflectionClass($method['class']); if ($reflector->implementsInterface($interface)) { $this->processors[$scope][$method_id] = $this->negotiator->getNegotiationMethodInstance($method_id); + $weights[$method_id] = $method['weight']; } } } } + + // Sort the outbound processors list, so that their functions are called in + // the order specified by the weight of the methods. + uksort($this->processors[$scope], function ($method_id_a, $method_id_b) use($weights) { + $a_weight = $weights[$method_id_a]; + $b_weight = $weights[$method_id_b]; + + if ($a_weight == $b_weight) { + return 0; + } + + return ($a_weight < $b_weight) ? -1 : 1; + }); } } only in patch2: unchanged: --- a/core/modules/node/src/Tests/NodeTranslationUITest.php +++ b/core/modules/node/src/Tests/NodeTranslationUITest.php @@ -93,7 +93,8 @@ function testPublishedStatusNoFields() { $language = ConfigurableLanguage::load($langcode); $values[$langcode] = array('title' => array(array('value' => $this->randomMachineName()))); - $add_url = Url::fromRoute('content_translation.translation_add_' . $entity->getEntityTypeId(), [ + $entity_type_id = $entity->getEntityTypeId(); + $add_url = Url::fromRoute("entity.$entity_type_id.content_translation_add", [ $entity->getEntityTypeId() => $entity->id(), 'source' => $default_langcode, 'target' => $langcode