Commit d09a7d16 authored by samuel.mortenson's avatar samuel.mortenson Committed by Samuel Mortenson

Issue #2996234 by samuel.mortenson: Support domain based language negotiation

parent e9261b51
......@@ -14,8 +14,8 @@ use Symfony\Component\EventDispatcher\Event;
* metadata to the untransformed path, if the original path is not already set.
*
* If your event subscriber adds a path that is already multilingual, you
* should set the "language_processed" metadata to any value. This prevents
* your paths from being prefixed with language path prefixes.
* should set the "language_processed" metadata to any value, and the
* "langcode" metadata to the language for the path.
*/
class CollectPathsEvent extends Event {
......
......@@ -74,6 +74,7 @@ class EntityPathSubscriber implements EventSubscriberInterface {
$entity_id,
]), [
'language_processed' => 'language_processed',
'langcode' => $langcode,
]);
}
}
......@@ -114,7 +115,7 @@ class EntityPathSubscriber implements EventSubscriberInterface {
$event->setInvalid();
return;
}
$event->setPath($url->toString());
$event->setPath(parse_url($url->toString(), PHP_URL_PATH));
}
}
......
......@@ -52,28 +52,41 @@ class LanguagePathSubscriber implements EventSubscriberInterface {
*/
public function collectPaths(CollectPathsEvent $event) {
$config = $this->configFactory->get('language.negotiation')->get('url');
if (is_array($config) && isset($config['source']) && $config['source'] === LanguageNegotiationUrl::CONFIG_PATH_PREFIX) {
foreach ($this->languageManager->getLanguages() as $language) {
$langcode = $language->getId();
if (isset($config['prefixes'][$langcode]) && !$language->isDefault()) {
$prefix = $this->joinPaths('/', $config['prefixes'][$langcode]);
$event->addPath($prefix, ['language_processed' => 'language_processed']);
foreach ($event->getPaths(TRUE) as $path => $metadata) {
if (!isset($metadata['language_processed']) && (!isset($metadata['language_prefix']) || $metadata['language_prefix'] === $langcode)) {
if (!isset($metadata['original_path'])) {
$metadata['original_path'] = $path;
}
$metadata['language_processed'] = 'language_processed';
if (isset($metadata['language_prefix'])) {
$event->replacePath($path, $this->joinPaths($prefix, $path), $metadata);
}
else {
$event->addPath($this->joinPaths($prefix, $path), $metadata);
if (is_array($config) && isset($config['source'])) {
if ($config['source'] === LanguageNegotiationUrl::CONFIG_PATH_PREFIX) {
foreach ($this->languageManager->getLanguages() as $language) {
$langcode = $language->getId();
if (isset($config['prefixes'][$langcode]) && !$language->isDefault()) {
$prefix = $this->joinPaths('/', $config['prefixes'][$langcode]);
$event->addPath($prefix, ['language_processed' => 'language_processed']);
foreach ($event->getPaths(TRUE) as $path => $metadata) {
if (!isset($metadata['language_processed']) && (!isset($metadata['language_prefix']) || $metadata['language_prefix'] === $langcode)) {
if (!isset($metadata['original_path'])) {
$metadata['original_path'] = $path;
}
$metadata['language_processed'] = 'language_processed';
if (isset($metadata['language_prefix'])) {
$event->replacePath($path, $this->joinPaths($prefix, $path), $metadata);
}
else {
$event->addPath($this->joinPaths($prefix, $path), $metadata);
}
}
}
}
}
}
elseif ($config['source'] === LanguageNegotiationUrl::CONFIG_DOMAIN) {
$paths = $event->getPaths(TRUE);
foreach ($paths as $path => $metadata) {
if (isset($metadata['language_processed']) && isset($metadata['langcode'])) {
if ($metadata['langcode'] !== $this->languageManager->getCurrentLanguage()->getId()) {
unset($paths[$path]);
}
}
}
$event->replacePaths($paths);
}
}
}
......
......@@ -42,7 +42,7 @@ class RoutePathSubscriber implements EventSubscriberInterface {
$url = Url::fromRoute($route_name);
$path = $url->toString();
if ($path && $url->access()) {
$event->addPath($path);
$event->addPath(parse_url($path, PHP_URL_PATH));
}
}
catch (\Exception $e) {
......
......@@ -6,8 +6,10 @@ use Drupal\block_content\Entity\BlockContent;
use Drupal\block_content\Entity\BlockContentType;
use Drupal\Core\Datetime\Entity\DateFormat;
use Drupal\Core\Site\Settings;
use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationUrl;
use Drupal\node\Entity\Node;
use Drupal\Tests\tome_base\Kernel\TestBase;
use Symfony\Component\HttpFoundation\Request;
/**
* Tests that static site generation works.
......@@ -92,6 +94,41 @@ class StaticGeneratorTest extends TestBase {
], $static->getPaths());
}
/**
* @covers \Drupal\tome_static\EventSubscriber\LanguagePathSubscriber::collectPaths
*/
public function testDomainNegotiation() {
$this->config('language.negotiation')
->set('url.source', LanguageNegotiationUrl::CONFIG_DOMAIN)
->set('url.domains', [
'en' => 'example.com',
'fr' => 'example.fr',
])
->save();
$article = Node::create(['type' => 'article', 'title' => 'My article']);
$article->addTranslation('fr', ['title' => 'My french article']);
$article->save();
/** @var \Drupal\tome_static\StaticGenerator $static */
$static = \Drupal::service('tome_static.generator');
$this->assertUnsortedEquals([
'/',
'_entity:node:en:1',
], $static->getPaths());
$request = Request::create('http://example.fr');
\Drupal::requestStack()->push($request);
\Drupal::service('language_manager')->reset();
$this->assertUnsortedEquals([
'/',
'_entity:node:fr:1',
], $static->getPaths());
}
/**
* @covers \Drupal\tome_static\StaticGenerator::requestPath
*/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment