diff --git a/core/modules/block/tests/src/Functional/BlockUiTest.php b/core/modules/block/tests/src/Functional/BlockUiTest.php index 55f103a0116877ba60e7eba0f7dc0eb0fc901c13..1e3cd81b319dd0d92b15f0b716679ec82285a441 100644 --- a/core/modules/block/tests/src/Functional/BlockUiTest.php +++ b/core/modules/block/tests/src/Functional/BlockUiTest.php @@ -345,9 +345,7 @@ public function testBlockPlacementIndicator(): void { // Removing a block will remove the block placement indicator. $this->clickLink('Remove'); $this->submitForm([], 'Remove'); - // @todo https://www.drupal.org/project/drupal/issues/2980527 this should be - // 'admin/structure/block/list/stark' but there is a bug. - $this->assertSession()->addressEquals('admin/structure/block'); + $this->assertSession()->addressEquals('admin/structure/block/list/stark'); } /** diff --git a/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationUrl.php b/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationUrl.php index ac156eeee2d55f35b38d668a890b5dc54cf29d42..3b00c83c8d0253bd3921ce9a362d2568773294d1 100644 --- a/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationUrl.php +++ b/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationUrl.php @@ -152,6 +152,11 @@ public function processOutbound($path, &$options = [], ?Request $request = NULL, elseif ($config['source'] == LanguageNegotiationUrl::CONFIG_DOMAIN) { if (is_object($options['language']) && !empty($config['domains'][$options['language']->getId()])) { + // Check if the base URLs match, return early if they do. + if (isset($options['base_url']) && $request && $request->getHost() === parse_url($options['base_url'], PHP_URL_HOST)) { + return $path; + } + // Save the original base URL. If it contains a port, we need to // retain it below. if (!empty($options['base_url'])) { @@ -159,33 +164,36 @@ public function processOutbound($path, &$options = [], ?Request $request = NULL, $normalized_base_url = str_replace(['https://', 'http://'], '', $options['base_url']); } - // Ask for an absolute URL with our modified base URL. - $options['absolute'] = TRUE; - $options['base_url'] = $url_scheme . '://' . $config['domains'][$options['language']->getId()]; - - // In case either the original base URL or the HTTP host contains a - // port, retain it. - if (isset($normalized_base_url) && str_contains($normalized_base_url, ':')) { - [, $port] = explode(':', $normalized_base_url); - $options['base_url'] .= ':' . $port; - } - elseif (($url_scheme == 'http' && $port != 80) || ($url_scheme == 'https' && $port != 443)) { - $options['base_url'] .= ':' . $port; - } - - if (isset($options['https'])) { - if ($options['https'] === TRUE) { - $options['base_url'] = str_replace('http://', 'https://', $options['base_url']); + // Ask for an absolute URL with our modified base URL only if the domain + // is different from the current request domain. + if ($request && $request->getHost() !== $config['domains'][$options['language']->getId()]) { + $options['absolute'] = TRUE; + $options['base_url'] = $url_scheme . '://' . $config['domains'][$options['language']->getId()]; + + // In case either the original base URL or the HTTP host contains a + // port, retain it. + if (isset($normalized_base_url) && str_contains($normalized_base_url, ':')) { + [, $port] = explode(':', $normalized_base_url); + $options['base_url'] .= ':' . $port; } - elseif ($options['https'] === FALSE) { - $options['base_url'] = str_replace('https://', 'http://', $options['base_url']); + elseif (($url_scheme == 'http' && $port != 80) || ($url_scheme == 'https' && $port != 443)) { + $options['base_url'] .= ':' . $port; } - } - // Add Drupal's subfolder from the base_path if there is one. - $options['base_url'] .= rtrim(base_path(), '/'); - if ($bubbleable_metadata) { - $bubbleable_metadata->addCacheContexts(['languages:' . LanguageInterface::TYPE_URL, 'url.site']); + if (isset($options['https'])) { + if ($options['https'] === TRUE) { + $options['base_url'] = str_replace('http://', 'https://', $options['base_url']); + } + elseif ($options['https'] === FALSE) { + $options['base_url'] = str_replace('https://', 'http://', $options['base_url']); + } + } + + // Add Drupal's subfolder from the base_path if there is one. + $options['base_url'] .= rtrim(base_path(), '/'); + if ($bubbleable_metadata) { + $bubbleable_metadata->addCacheContexts(['languages:' . LanguageInterface::TYPE_URL, 'url.site']); + } } } } diff --git a/core/modules/language/tests/src/Unit/LanguageNegotiationUrlTest.php b/core/modules/language/tests/src/Unit/LanguageNegotiationUrlTest.php index 8fb765cdcaad92d648ac5acc99f5f55bb8b8e9c9..f637fe782ed11517d6a3811535f9c2d93aa7b0a4 100644 --- a/core/modules/language/tests/src/Unit/LanguageNegotiationUrlTest.php +++ b/core/modules/language/tests/src/Unit/LanguageNegotiationUrlTest.php @@ -338,6 +338,51 @@ public static function providerTestDomain() { return $domain_configuration; } + /** + * Tests path outbound processing correctly setting relative/absolute paths. + */ + public function testProcessOutboundOutputsRelativePathsForSameDomain(): void { + $this->languageManager->expects($this->any()) + ->method('getCurrentLanguage') + ->willReturn($this->languages['en']); + + $config = $this->getConfigFactoryStub([ + 'language.negotiation' => [ + 'url' => [ + 'source' => LanguageNegotiationUrl::CONFIG_DOMAIN, + 'domains' => [ + 'de' => 'example.de', + 'en' => 'example.com', + ], + ], + ], + ]); + + $request = Request::create('', 'GET', [], [], [], ['HTTP_HOST' => 'example.com']); + $method = new LanguageNegotiationUrl(); + $method->setLanguageManager($this->languageManager); + $method->setConfig($config); + $method->setCurrentUser($this->user); + + // Check relative paths are used when the language + // is the current language. + $options = [ + 'language' => $this->languages['en'], + ]; + $method->processOutbound('foo', $options, $request); + // $options['absolute'] not set or null equals to FALSE. + $this->assertFalse($options['absolute'] ?? FALSE); + + // Check absolute paths are used when the language + // is not the current language. + $options = [ + 'language' => $this->languages['de'], + ]; + $method->processOutbound('foo', $options, $request); + $this->assertTrue($options['absolute']); + + } + } // @todo Remove as part of https://www.drupal.org/node/2481833.