Version 1
[yaffs-website] / web / core / modules / language / src / Tests / LanguageUrlRewritingTest.php
1 <?php
2
3 namespace Drupal\language\Tests;
4
5 use Drupal\Core\Language\Language;
6 use Drupal\Core\Language\LanguageInterface;
7 use Drupal\Core\Url;
8 use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationUrl;
9 use Drupal\simpletest\WebTestBase;
10 use Symfony\Component\HttpFoundation\Request;
11
12 /**
13  * Tests that URL rewriting works as expected.
14  *
15  * @group language
16  */
17 class LanguageUrlRewritingTest extends WebTestBase {
18
19   /**
20    * Modules to enable.
21    *
22    * @var array
23    */
24   public static $modules = ['language', 'language_test'];
25
26   /**
27    * An user with permissions to administer languages.
28    *
29    * @var \Drupal\user\UserInterface
30    */
31   protected $webUser;
32
33   protected function setUp() {
34     parent::setUp();
35
36     // Create and log in user.
37     $this->webUser = $this->drupalCreateUser(['administer languages', 'access administration pages']);
38     $this->drupalLogin($this->webUser);
39
40     // Install French language.
41     $edit = [];
42     $edit['predefined_langcode'] = 'fr';
43     $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add language'));
44
45     // Enable URL language detection and selection.
46     $edit = ['language_interface[enabled][language-url]' => 1];
47     $this->drupalPostForm('admin/config/regional/language/detection', $edit, t('Save settings'));
48
49     // Check that drupalSettings contains path prefix.
50     $this->drupalGet('fr/admin/config/regional/language/detection');
51     $this->assertRaw('"pathPrefix":"fr\/"', 'drupalSettings path prefix contains language code.');
52   }
53
54   /**
55    * Check that non-installed languages are not considered.
56    */
57   public function testUrlRewritingEdgeCases() {
58     // Check URL rewriting with a non-installed language.
59     $non_existing = new Language(['id' => $this->randomMachineName()]);
60     $this->checkUrl($non_existing, 'Path language is ignored if language is not installed.', 'URL language negotiation does not work with non-installed languages');
61
62     // Check that URL rewriting is not applied to subrequests.
63     $this->drupalGet('language_test/subrequest');
64     $this->assertText($this->webUser->getUsername(), 'Page correctly retrieved');
65   }
66
67   /**
68    * Check URL rewriting for the given language.
69    *
70    * The test is performed with a fixed URL (the default front page) to simply
71    * check that language prefixes are not added to it and that the prefixed URL
72    * is actually not working.
73    *
74    * @param \Drupal\Core\Language\LanguageInterface $language
75    *   The language object.
76    * @param string $message1
77    *   Message to display in assertion that language prefixes are not added.
78    * @param string $message2
79    *   The message to display confirming prefixed URL is not working.
80    */
81   private function checkUrl(LanguageInterface $language, $message1, $message2) {
82     $options = ['language' => $language, 'script' => ''];
83     $base_path = trim(base_path(), '/');
84     $rewritten_path = trim(str_replace($base_path, '', \Drupal::url('<front>', [], $options)), '/');
85     $segments = explode('/', $rewritten_path, 2);
86     $prefix = $segments[0];
87     $path = isset($segments[1]) ? $segments[1] : $prefix;
88
89     // If the rewritten URL has not a language prefix we pick a random prefix so
90     // we can always check the prefixed URL.
91     $prefixes = language_negotiation_url_prefixes();
92     $stored_prefix = isset($prefixes[$language->getId()]) ? $prefixes[$language->getId()] : $this->randomMachineName();
93     if ($this->assertNotEqual($stored_prefix, $prefix, $message1)) {
94       $prefix = $stored_prefix;
95     }
96
97     $this->drupalGet("$prefix/$path");
98     $this->assertResponse(404, $message2);
99   }
100
101   /**
102    * Check URL rewriting when using a domain name and a non-standard port.
103    */
104   public function testDomainNameNegotiationPort() {
105     global $base_url;
106     $language_domain = 'example.fr';
107     // Get the current host URI we're running on.
108     $base_url_host = parse_url($base_url, PHP_URL_HOST);
109     $edit = [
110       'language_negotiation_url_part' => LanguageNegotiationUrl::CONFIG_DOMAIN,
111       'domain[en]' => $base_url_host,
112       'domain[fr]' => $language_domain
113     ];
114     $this->drupalPostForm('admin/config/regional/language/detection/url', $edit, t('Save configuration'));
115     // Rebuild the container so that the new language gets picked up by services
116     // that hold the list of languages.
117     $this->rebuildContainer();
118
119     // Enable domain configuration.
120     $this->config('language.negotiation')
121       ->set('url.source', LanguageNegotiationUrl::CONFIG_DOMAIN)
122       ->save();
123
124     // Reset static caching.
125     $this->container->get('language_manager')->reset();
126
127     // In case index.php is part of the URLs, we need to adapt the asserted
128     // URLs as well.
129     $index_php = strpos(\Drupal::url('<front>', [], ['absolute' => TRUE]), 'index.php') !== FALSE;
130
131     $request = Request::createFromGlobals();
132     $server = $request->server->all();
133     $request = $this->prepareRequestForGenerator(TRUE, ['HTTP_HOST' => $server['HTTP_HOST'] . ':88']);
134
135     // Create an absolute French link.
136     $language = \Drupal::languageManager()->getLanguage('fr');
137     $url = Url::fromRoute('<front>', [], [
138       'absolute' => TRUE,
139       'language' => $language,
140     ])->toString();
141
142     $expected = ($index_php ? 'http://example.fr:88/index.php' : 'http://example.fr:88') . rtrim(base_path(), '/') . '/';
143
144     $this->assertEqual($url, $expected, 'The right port is used.');
145
146     // If we set the port explicitly, it should not be overridden.
147     $url = Url::fromRoute('<front>', [], [
148       'absolute' => TRUE,
149       'language' => $language,
150       'base_url' => $request->getBaseUrl() . ':90',
151     ])->toString();
152
153     $expected = $index_php ? 'http://example.fr:90/index.php' : 'http://example.fr:90' . rtrim(base_path(), '/') . '/';
154
155     $this->assertEqual($url, $expected, 'A given port is not overridden.');
156
157   }
158
159 }