Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 namespace Drupal\Tests\path\Functional;
|
Chris@0
|
4
|
Chris@0
|
5 /**
|
Chris@0
|
6 * Confirm that paths work with translated nodes.
|
Chris@0
|
7 *
|
Chris@0
|
8 * @group path
|
Chris@0
|
9 */
|
Chris@0
|
10 class PathLanguageTest extends PathTestBase {
|
Chris@0
|
11
|
Chris@0
|
12 /**
|
Chris@0
|
13 * Modules to enable.
|
Chris@0
|
14 *
|
Chris@0
|
15 * @var array
|
Chris@0
|
16 */
|
Chris@0
|
17 public static $modules = ['path', 'locale', 'locale_test', 'content_translation'];
|
Chris@0
|
18
|
Chris@0
|
19 /**
|
Chris@0
|
20 * An user with permissions to administer content types.
|
Chris@0
|
21 *
|
Chris@0
|
22 * @var \Drupal\user\UserInterface
|
Chris@0
|
23 */
|
Chris@0
|
24 protected $webUser;
|
Chris@0
|
25
|
Chris@0
|
26 protected function setUp() {
|
Chris@0
|
27 parent::setUp();
|
Chris@0
|
28
|
Chris@0
|
29 $permissions = [
|
Chris@0
|
30 'access administration pages',
|
Chris@0
|
31 'administer content translation',
|
Chris@0
|
32 'administer content types',
|
Chris@0
|
33 'administer languages',
|
Chris@0
|
34 'administer url aliases',
|
Chris@0
|
35 'create content translations',
|
Chris@0
|
36 'create page content',
|
Chris@0
|
37 'create url aliases',
|
Chris@0
|
38 'edit any page content',
|
Chris@0
|
39 'translate any entity',
|
Chris@0
|
40 ];
|
Chris@0
|
41 // Create and log in user.
|
Chris@0
|
42 $this->webUser = $this->drupalCreateUser($permissions);
|
Chris@0
|
43 $this->drupalLogin($this->webUser);
|
Chris@0
|
44
|
Chris@0
|
45 // Enable French language.
|
Chris@0
|
46 $edit = [];
|
Chris@0
|
47 $edit['predefined_langcode'] = 'fr';
|
Chris@0
|
48
|
Chris@0
|
49 $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add language'));
|
Chris@0
|
50
|
Chris@0
|
51 // Enable URL language detection and selection.
|
Chris@0
|
52 $edit = ['language_interface[enabled][language-url]' => 1];
|
Chris@0
|
53 $this->drupalPostForm('admin/config/regional/language/detection', $edit, t('Save settings'));
|
Chris@0
|
54
|
Chris@0
|
55 // Enable translation for page node.
|
Chris@0
|
56 $edit = [
|
Chris@0
|
57 'entity_types[node]' => 1,
|
Chris@0
|
58 'settings[node][page][translatable]' => 1,
|
Chris@0
|
59 'settings[node][page][fields][path]' => 1,
|
Chris@0
|
60 'settings[node][page][fields][body]' => 1,
|
Chris@0
|
61 'settings[node][page][settings][language][language_alterable]' => 1,
|
Chris@0
|
62 ];
|
Chris@0
|
63 $this->drupalPostForm('admin/config/regional/content-language', $edit, t('Save configuration'));
|
Chris@0
|
64
|
Chris@0
|
65 $definitions = \Drupal::entityManager()->getFieldDefinitions('node', 'page');
|
Chris@0
|
66 $this->assertTrue($definitions['path']->isTranslatable(), 'Node path is translatable.');
|
Chris@0
|
67 $this->assertTrue($definitions['body']->isTranslatable(), 'Node body is translatable.');
|
Chris@0
|
68 }
|
Chris@0
|
69
|
Chris@0
|
70 /**
|
Chris@0
|
71 * Test alias functionality through the admin interfaces.
|
Chris@0
|
72 */
|
Chris@0
|
73 public function testAliasTranslation() {
|
Chris@0
|
74 $node_storage = $this->container->get('entity.manager')->getStorage('node');
|
Chris@0
|
75 $english_node = $this->drupalCreateNode(['type' => 'page', 'langcode' => 'en']);
|
Chris@0
|
76 $english_alias = $this->randomMachineName();
|
Chris@0
|
77
|
Chris@0
|
78 // Edit the node to set language and path.
|
Chris@0
|
79 $edit = [];
|
Chris@0
|
80 $edit['path[0][alias]'] = '/' . $english_alias;
|
Chris@0
|
81 $this->drupalPostForm('node/' . $english_node->id() . '/edit', $edit, t('Save'));
|
Chris@0
|
82
|
Chris@0
|
83 // Confirm that the alias works.
|
Chris@0
|
84 $this->drupalGet($english_alias);
|
Chris@0
|
85 $this->assertText($english_node->body->value, 'Alias works.');
|
Chris@0
|
86
|
Chris@0
|
87 // Translate the node into French.
|
Chris@0
|
88 $this->drupalGet('node/' . $english_node->id() . '/translations');
|
Chris@0
|
89 $this->clickLink(t('Add'));
|
Chris@0
|
90
|
Chris@0
|
91 $edit = [];
|
Chris@0
|
92 $edit['title[0][value]'] = $this->randomMachineName();
|
Chris@0
|
93 $edit['body[0][value]'] = $this->randomMachineName();
|
Chris@0
|
94 $french_alias = $this->randomMachineName();
|
Chris@0
|
95 $edit['path[0][alias]'] = '/' . $french_alias;
|
Chris@0
|
96 $this->drupalPostForm(NULL, $edit, t('Save (this translation)'));
|
Chris@0
|
97
|
Chris@0
|
98 // Clear the path lookup cache.
|
Chris@0
|
99 $this->container->get('path.alias_manager')->cacheClear();
|
Chris@0
|
100
|
Chris@0
|
101 // Languages are cached on many levels, and we need to clear those caches.
|
Chris@0
|
102 $this->container->get('language_manager')->reset();
|
Chris@0
|
103 $this->rebuildContainer();
|
Chris@0
|
104 $languages = $this->container->get('language_manager')->getLanguages();
|
Chris@0
|
105
|
Chris@0
|
106 // Ensure the node was created.
|
Chris@0
|
107 $node_storage->resetCache([$english_node->id()]);
|
Chris@0
|
108 $english_node = $node_storage->load($english_node->id());
|
Chris@0
|
109 $english_node_french_translation = $english_node->getTranslation('fr');
|
Chris@0
|
110 $this->assertTrue($english_node->hasTranslation('fr'), 'Node found in database.');
|
Chris@0
|
111
|
Chris@0
|
112 // Confirm that the alias works.
|
Chris@0
|
113 $this->drupalGet('fr' . $edit['path[0][alias]']);
|
Chris@0
|
114 $this->assertText($english_node_french_translation->body->value, 'Alias for French translation works.');
|
Chris@0
|
115
|
Chris@0
|
116 // Confirm that the alias is returned for the URL. Languages are cached on
|
Chris@0
|
117 // many levels, and we need to clear those caches.
|
Chris@0
|
118 $this->container->get('language_manager')->reset();
|
Chris@0
|
119 $languages = $this->container->get('language_manager')->getLanguages();
|
Chris@18
|
120 $url = $english_node_french_translation->toUrl('canonical', ['language' => $languages['fr']])->toString();
|
Chris@0
|
121
|
Chris@0
|
122 $this->assertTrue(strpos($url, $edit['path[0][alias]']), 'URL contains the path alias.');
|
Chris@0
|
123
|
Chris@0
|
124 // Confirm that the alias works even when changing language negotiation
|
Chris@0
|
125 // options. Enable User language detection and selection over URL one.
|
Chris@0
|
126 $edit = [
|
Chris@0
|
127 'language_interface[enabled][language-user]' => 1,
|
Chris@0
|
128 'language_interface[weight][language-user]' => -9,
|
Chris@0
|
129 'language_interface[enabled][language-url]' => 1,
|
Chris@0
|
130 'language_interface[weight][language-url]' => -8,
|
Chris@0
|
131 ];
|
Chris@0
|
132 $this->drupalPostForm('admin/config/regional/language/detection', $edit, t('Save settings'));
|
Chris@0
|
133
|
Chris@0
|
134 // Change user language preference.
|
Chris@0
|
135 $edit = ['preferred_langcode' => 'fr'];
|
Chris@0
|
136 $this->drupalPostForm("user/" . $this->webUser->id() . "/edit", $edit, t('Save'));
|
Chris@0
|
137
|
Chris@0
|
138 // Check that the English alias works. In this situation French is the
|
Chris@0
|
139 // current UI and content language, while URL language is English (since we
|
Chris@0
|
140 // do not have a path prefix we fall back to the site's default language).
|
Chris@0
|
141 // We need to ensure that the user language preference is not taken into
|
Chris@0
|
142 // account while determining the path alias language, because if this
|
Chris@0
|
143 // happens we have no way to check that the path alias is valid: there is no
|
Chris@0
|
144 // path alias for French matching the english alias. So the alias manager
|
Chris@0
|
145 // needs to use the URL language to check whether the alias is valid.
|
Chris@0
|
146 $this->drupalGet($english_alias);
|
Chris@0
|
147 $this->assertText($english_node_french_translation->body->value, 'English alias, but French preferred by the user: French translation.');
|
Chris@0
|
148
|
Chris@0
|
149 // Check that the French alias works.
|
Chris@0
|
150 $this->drupalGet("fr/$french_alias");
|
Chris@0
|
151 $this->assertText($english_node_french_translation->body->value, 'Alias for French translation works.');
|
Chris@0
|
152
|
Chris@0
|
153 // Disable URL language negotiation.
|
Chris@0
|
154 $edit = ['language_interface[enabled][language-url]' => FALSE];
|
Chris@0
|
155 $this->drupalPostForm('admin/config/regional/language/detection', $edit, t('Save settings'));
|
Chris@0
|
156
|
Chris@0
|
157 // Check that the English alias still works.
|
Chris@0
|
158 $this->drupalGet($english_alias);
|
Chris@0
|
159 $this->assertText($english_node_french_translation->body->value, 'English alias, but French preferred by the user: French translation.');
|
Chris@0
|
160
|
Chris@0
|
161 // Check that the French alias is not available. We check the unprefixed
|
Chris@0
|
162 // alias because we disabled URL language negotiation above. In this
|
Chris@0
|
163 // situation only aliases in the default language and language neutral ones
|
Chris@0
|
164 // should keep working.
|
Chris@0
|
165 $this->drupalGet($french_alias);
|
Chris@0
|
166 $this->assertResponse(404, 'Alias for French translation is unavailable when URL language negotiation is disabled.');
|
Chris@0
|
167
|
Chris@0
|
168 // The alias manager has an internal path lookup cache. Check to see that
|
Chris@0
|
169 // it has the appropriate contents at this point.
|
Chris@0
|
170 $this->container->get('path.alias_manager')->cacheClear();
|
Chris@0
|
171 $french_node_path = $this->container->get('path.alias_manager')->getPathByAlias('/' . $french_alias, 'fr');
|
Chris@0
|
172 $this->assertEqual($french_node_path, '/node/' . $english_node_french_translation->id(), 'Normal path works.');
|
Chris@0
|
173 // Second call should return the same path.
|
Chris@0
|
174 $french_node_path = $this->container->get('path.alias_manager')->getPathByAlias('/' . $french_alias, 'fr');
|
Chris@0
|
175 $this->assertEqual($french_node_path, '/node/' . $english_node_french_translation->id(), 'Normal path is the same.');
|
Chris@0
|
176
|
Chris@0
|
177 // Confirm that the alias works.
|
Chris@0
|
178 $french_node_alias = $this->container->get('path.alias_manager')->getAliasByPath('/node/' . $english_node_french_translation->id(), 'fr');
|
Chris@0
|
179 $this->assertEqual($french_node_alias, '/' . $french_alias, 'Alias works.');
|
Chris@0
|
180 // Second call should return the same alias.
|
Chris@0
|
181 $french_node_alias = $this->container->get('path.alias_manager')->getAliasByPath('/node/' . $english_node_french_translation->id(), 'fr');
|
Chris@0
|
182 $this->assertEqual($french_node_alias, '/' . $french_alias, 'Alias is the same.');
|
Chris@0
|
183
|
Chris@0
|
184 // Confirm that the alias is removed if the translation is deleted.
|
Chris@0
|
185 $english_node->removeTranslation('fr');
|
Chris@0
|
186 $english_node->save();
|
Chris@0
|
187 $this->assertFalse($this->container->get('path.alias_storage')->aliasExists('/' . $french_alias, 'fr'), 'Alias for French translation is removed when translation is deleted.');
|
Chris@0
|
188
|
Chris@0
|
189 // Check that the English alias still works.
|
Chris@0
|
190 $this->drupalGet($english_alias);
|
Chris@0
|
191 $this->assertTrue($this->container->get('path.alias_storage')->aliasExists('/' . $english_alias, 'en'), 'English alias is not deleted when French translation is removed.');
|
Chris@0
|
192 $this->assertText($english_node->body->value, 'English alias still works');
|
Chris@0
|
193 }
|
Chris@0
|
194
|
Chris@0
|
195 }
|