These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
0 ignored issues
–
show
|
|||
2 | /** |
||
3 | * @todo Test Versioned getters |
||
4 | * |
||
5 | * @package translatable |
||
6 | */ |
||
7 | class TranslatableTest extends FunctionalTest |
||
8 | { |
||
9 | protected static $fixture_file = 'translatable/tests/unit/TranslatableTest.yml'; |
||
10 | |||
11 | protected $extraDataObjects = array( |
||
12 | 'TranslatableTest_DataObject', |
||
13 | 'TranslatableTest_OneByLocaleDataObject', |
||
14 | 'TranslatableTest_Page', |
||
15 | ); |
||
16 | |||
17 | protected $requiredExtensions = array( |
||
18 | 'SiteTree' => array('Translatable', 'Versioned', 'EveryoneCanPublish'), |
||
19 | 'SiteConfig' => array('Translatable'), |
||
20 | 'TranslatableTest_DataObject' => array('Translatable'), |
||
21 | 'TranslatableTest_OneByLocaleDataObject' => array('Translatable'), |
||
22 | ); |
||
23 | |||
24 | private $origLocale; |
||
25 | |||
26 | protected $autoFollowRedirection = false; |
||
27 | |||
28 | public function setUp() |
||
29 | { |
||
30 | parent::setUp(); |
||
31 | |||
32 | // whenever a translation is created, canTranslate() is checked |
||
33 | $cmseditor = $this->objFromFixture('Member', 'cmseditor'); |
||
34 | $cmseditor->logIn(); |
||
35 | |||
36 | $this->origLocale = Translatable::default_locale(); |
||
37 | Translatable::set_default_locale("en_US"); |
||
38 | } |
||
39 | |||
40 | public function tearDown() |
||
41 | { |
||
42 | Translatable::set_default_locale($this->origLocale); |
||
43 | Translatable::set_current_locale($this->origLocale); |
||
44 | |||
45 | parent::tearDown(); |
||
46 | } |
||
47 | |||
48 | public function assertArrayEqualsAfterSort($expected, $actual, $message = null) |
||
49 | { |
||
50 | sort($expected); |
||
51 | sort($actual); |
||
52 | return $this->assertEquals($expected, $actual, $message); |
||
53 | } |
||
54 | |||
55 | public function testGetOneByLocale() |
||
56 | { |
||
57 | Translatable::disable_locale_filter(); |
||
58 | $this->assertEquals( |
||
59 | 0, |
||
60 | TranslatableTest_OneByLocaleDataObject::get()->count(), |
||
61 | 'should not be any test objects yet' |
||
62 | ); |
||
63 | Translatable::enable_locale_filter(); |
||
64 | |||
65 | $obj = new TranslatableTest_OneByLocaleDataObject(); |
||
66 | $obj->TranslatableProperty = 'test - en'; |
||
67 | $obj->write(); |
||
68 | |||
69 | Translatable::disable_locale_filter(); |
||
70 | $this->assertEquals( |
||
71 | 1, |
||
72 | TranslatableTest_OneByLocaleDataObject::get()->count(), |
||
73 | 'should not be any test objects yet' |
||
74 | ); |
||
75 | Translatable::enable_locale_filter(); |
||
76 | |||
77 | $found = Translatable::get_one_by_locale('TranslatableTest_OneByLocaleDataObject', $obj->Locale); |
||
78 | $this->assertNotNull($found, 'should have found one for ' . $obj->Locale); |
||
79 | $this->assertEquals($obj->ID, $found->ID); |
||
80 | |||
81 | $translated = $obj->createTranslation('de_DE'); |
||
82 | $translated->write(); |
||
83 | |||
84 | Translatable::disable_locale_filter(); |
||
85 | $this->assertEquals( |
||
86 | 2, |
||
87 | TranslatableTest_OneByLocaleDataObject::get()->count(), |
||
88 | 'should not be any test objects yet' |
||
89 | ); |
||
90 | Translatable::enable_locale_filter(); |
||
91 | |||
92 | $found = Translatable::get_one_by_locale( |
||
93 | 'TranslatableTest_OneByLocaleDataObject', |
||
94 | $translated->Locale |
||
95 | ); |
||
96 | $this->assertNotNull($found, 'should have found one for ' . $translated->Locale); |
||
97 | $this->assertEquals($translated->ID, $found->ID); |
||
98 | |||
99 | // test again to make sure that get_one_by_locale works when locale filter disabled |
||
100 | Translatable::disable_locale_filter(); |
||
101 | $found = Translatable::get_one_by_locale( |
||
102 | 'TranslatableTest_OneByLocaleDataObject', |
||
103 | $translated->Locale |
||
104 | ); |
||
105 | $this->assertEquals($translated->ID, $found->ID); |
||
106 | Translatable::enable_locale_filter(); |
||
107 | } |
||
108 | |||
109 | public function testLocaleFilteringEnabledAndDisabled() |
||
110 | { |
||
111 | $this->assertTrue(Translatable::locale_filter_enabled()); |
||
112 | |||
113 | // get our base page to use for testing |
||
114 | $origPage = $this->objFromFixture('Page', 'testpage_en'); |
||
115 | $origPage->MenuTitle = 'unique-key-used-in-my-query'; |
||
116 | $origPage->write(); |
||
117 | $origPage->publish('Stage', 'Live'); |
||
118 | |||
119 | // create a translation of it so that we can see if translations are filtered |
||
120 | $translatedPage = $origPage->createTranslation('de_DE'); |
||
121 | $translatedPage->MenuTitle = $origPage->MenuTitle; |
||
122 | $translatedPage->write(); |
||
123 | $translatedPage->publish('Stage', 'Live'); |
||
124 | |||
125 | $where = sprintf("\"MenuTitle\" = '%s'", Convert::raw2sql($origPage->MenuTitle)); |
||
126 | |||
127 | // make sure that our query was filtered |
||
128 | $this->assertEquals(1, Page::get()->where($where)->count()); |
||
129 | |||
130 | // test no filtering with disabled locale filter |
||
131 | Translatable::disable_locale_filter(); |
||
132 | $this->assertEquals(2, Page::get()->where($where)->count()); |
||
133 | Translatable::enable_locale_filter(); |
||
134 | |||
135 | // make sure that our query was filtered after re-enabling the filter |
||
136 | $this->assertEquals(1, Page::get()->where($where)->count()); |
||
137 | |||
138 | // test effectiveness of disabling locale filter with 3.x delayed querying |
||
139 | // see https://github.com/silverstripe/silverstripe-translatable/issues/113 |
||
140 | Translatable::disable_locale_filter(); |
||
141 | // create the DataList while the locale filter is disabled |
||
142 | $dataList = Page::get()->where($where); |
||
143 | Translatable::enable_locale_filter(); |
||
144 | // but don't use it until later - after the filter is re-enabled |
||
145 | $this->assertEquals(2, $dataList->count()); |
||
146 | } |
||
147 | |||
148 | public function testLocaleGetParamRedirectsToTranslation() |
||
149 | { |
||
150 | $origPage = $this->objFromFixture('Page', 'testpage_en'); |
||
151 | $origPage->publish('Stage', 'Live'); |
||
152 | $translatedPage = $origPage->createTranslation('de_DE'); |
||
153 | $translatedPage->URLSegment = 'ueber-uns'; |
||
154 | $translatedPage->write(); |
||
155 | $translatedPage->publish('Stage', 'Live'); |
||
156 | |||
157 | // Need to log out, otherwise pages redirect to CMS views |
||
158 | $this->session()->inst_set('loggedInAs', null); |
||
159 | |||
160 | $response = $this->get($origPage->URLSegment); |
||
161 | $this->assertEquals(200, $response->getStatusCode(), 'Page request without Locale GET param doesnt redirect'); |
||
162 | |||
163 | $response = $this->get(Controller::join_links($origPage->URLSegment, '?locale=de_DE')); |
||
164 | $this->assertEquals(301, $response->getStatusCode(), 'Locale GET param causes redirect if it exists'); |
||
165 | $this->assertContains($translatedPage->URLSegment, $response->getHeader('Location')); |
||
166 | |||
167 | $response = $this->get(Controller::join_links($origPage->URLSegment, '?locale=fr_FR')); |
||
168 | $this->assertEquals(200, $response->getStatusCode(), |
||
169 | 'Locale GET param without existing translation shows original page' |
||
170 | ); |
||
171 | } |
||
172 | |||
173 | public function testTranslationGroups() |
||
174 | { |
||
175 | // first in french |
||
176 | $frPage = new SiteTree(); |
||
177 | $frPage->Locale = 'fr_FR'; |
||
178 | $frPage->write(); |
||
179 | |||
180 | // second in english (from french "original") |
||
181 | $enPage = $frPage->createTranslation('en_US'); |
||
182 | |||
183 | // third in spanish (from the english translation) |
||
184 | $esPage = $enPage->createTranslation('es_ES'); |
||
185 | |||
186 | // test french |
||
187 | |||
188 | $this->assertArrayEqualsAfterSort( |
||
189 | array('en_US', 'es_ES'), |
||
190 | $frPage->getTranslations()->column('Locale') |
||
191 | ); |
||
192 | $this->assertNotNull($frPage->getTranslation('en_US')); |
||
193 | $this->assertEquals( |
||
194 | $frPage->getTranslation('en_US')->ID, |
||
195 | $enPage->ID |
||
196 | ); |
||
197 | $this->assertNotNull($frPage->getTranslation('es_ES')); |
||
198 | $this->assertEquals( |
||
199 | $frPage->getTranslation('es_ES')->ID, |
||
200 | $esPage->ID |
||
201 | ); |
||
202 | |||
203 | // test english |
||
204 | $this->assertArrayEqualsAfterSort( |
||
205 | array('es_ES', 'fr_FR'), |
||
206 | $enPage->getTranslations()->column('Locale') |
||
207 | ); |
||
208 | $this->assertNotNull($frPage->getTranslation('fr_FR')); |
||
209 | $this->assertEquals( |
||
210 | $enPage->getTranslation('fr_FR')->ID, |
||
211 | $frPage->ID |
||
212 | ); |
||
213 | $this->assertNotNull($frPage->getTranslation('es_ES')); |
||
214 | $this->assertEquals( |
||
215 | $enPage->getTranslation('es_ES')->ID, |
||
216 | $esPage->ID |
||
217 | ); |
||
218 | |||
219 | // test spanish |
||
220 | $this->assertArrayEqualsAfterSort( |
||
221 | array('en_US', 'fr_FR'), |
||
222 | $esPage->getTranslations()->column('Locale') |
||
223 | ); |
||
224 | $this->assertNotNull($esPage->getTranslation('fr_FR')); |
||
225 | $this->assertEquals( |
||
226 | $esPage->getTranslation('fr_FR')->ID, |
||
227 | $frPage->ID |
||
228 | ); |
||
229 | $this->assertNotNull($esPage->getTranslation('en_US')); |
||
230 | $this->assertEquals( |
||
231 | $esPage->getTranslation('en_US')->ID, |
||
232 | $enPage->ID |
||
233 | ); |
||
234 | } |
||
235 | |||
236 | public function assertClass($class, $node) |
||
237 | { |
||
238 | $this->assertNotNull($node); |
||
239 | $this->assertEquals($class, $node->ClassName); |
||
240 | $this->assertEquals($class, get_class($node)); |
||
241 | } |
||
242 | |||
243 | public function testChangingClassOfDefaultLocaleTranslationChangesOthers() |
||
244 | { |
||
245 | // see https://github.com/silverstripe/silverstripe-translatable/issues/97 |
||
246 | // create an English SiteTree |
||
247 | $enST = new SiteTree(); |
||
248 | $enST->Locale = 'en_US'; |
||
249 | $enST->write(); |
||
250 | |||
251 | // create French and Spanish translations |
||
252 | $frST = $enST->createTranslation('fr_FR'); |
||
253 | $esST = $enST->createTranslation('es_ES'); |
||
254 | |||
255 | // change the class name of the default locale's translation (as CMS admin would) |
||
256 | $enST->setClassName('Page'); |
||
257 | $enST->write(); |
||
258 | |||
259 | // reload them all to get fresh instances |
||
260 | $enPg = DataObject::get_by_id('Page', $enST->ID, $cache = false); |
||
261 | $frPg = DataObject::get_by_id('Page', $frST->ID, $cache = false); |
||
262 | $esPg = DataObject::get_by_id('Page', $esST->ID, $cache = false); |
||
263 | |||
264 | // make sure they are all the right class |
||
265 | $this->assertClass('Page', $enPg); |
||
266 | $this->assertClass('Page', $frPg); |
||
267 | $this->assertClass('Page', $esPg); |
||
268 | |||
269 | // test that we get the right translations back from each instance |
||
270 | $this->assertArrayEqualsAfterSort( |
||
271 | array('fr_FR', 'es_ES'), |
||
272 | $enPg->getTranslations()->column('Locale') |
||
273 | ); |
||
274 | $this->assertArrayEqualsAfterSort( |
||
275 | array('en_US', 'es_ES'), |
||
276 | $frPg->getTranslations()->column('Locale') |
||
277 | ); |
||
278 | $this->assertArrayEqualsAfterSort( |
||
279 | array('en_US', 'fr_FR'), |
||
280 | $esPg->getTranslations()->column('Locale') |
||
281 | ); |
||
282 | } |
||
283 | |||
284 | public function testChangingClassOfDefaultLocaleTranslationChangesOthersWhenPublished() |
||
285 | { |
||
286 | // create an English SiteTree |
||
287 | $enST = new SiteTree(); |
||
288 | $enST->Locale = 'en_US'; |
||
289 | $enST->write(); |
||
290 | $enST->doPublish(); |
||
291 | |||
292 | // create and publish French and Spanish translations |
||
293 | $frST = $enST->createTranslation('fr_FR'); |
||
294 | $this->assertTrue($frST->doPublish(), 'should have been able to publish French translation'); |
||
295 | $esST = $enST->createTranslation('es_ES'); |
||
296 | $this->assertTrue($esST->doPublish(), 'should have been able to publish Spanish translation'); |
||
297 | |||
298 | // change the class name of the default locale's translation (as CMS admin would) |
||
299 | // and publish the change - we should see both versions of English change class |
||
300 | $enST->setClassName('Page'); |
||
301 | $enST->doPublish(); |
||
302 | $this->assertClass('Page', Versioned::get_one_by_stage('SiteTree', 'Stage', '"ID" = ' . $enST->ID)); |
||
303 | $this->assertClass('Page', Versioned::get_one_by_stage('SiteTree', 'Live', '"ID" = ' . $enST->ID)); |
||
304 | |||
305 | // and all of the draft versions of translations: |
||
306 | $this->assertClass('Page', Versioned::get_one_by_stage('SiteTree', 'Stage', '"ID" = ' . $frST->ID)); |
||
307 | $this->assertClass('Page', Versioned::get_one_by_stage('SiteTree', 'Stage', '"ID" = ' . $esST->ID)); |
||
308 | |||
309 | // and all of the live versions of translations as well: |
||
310 | $this->assertClass('Page', Versioned::get_one_by_stage('SiteTree', 'Live', '"ID" = ' . $frST->ID)); |
||
311 | $this->assertClass('Page', Versioned::get_one_by_stage('SiteTree', 'Live', '"ID" = ' . $esST->ID)); |
||
312 | } |
||
313 | |||
314 | public function testTranslationGroupsWhenTranslationIsSubclass() |
||
315 | { |
||
316 | // create an English SiteTree |
||
317 | $enST = new SiteTree(); |
||
318 | $enST->Locale = 'en_US'; |
||
319 | $enST->write(); |
||
320 | |||
321 | // create French and Spanish translations |
||
322 | $frST = $enST->createTranslation('fr_FR'); |
||
323 | $esST = $enST->createTranslation('es_ES'); |
||
324 | |||
325 | // test that we get the right translations back from each instance |
||
326 | $this->assertArrayEqualsAfterSort( |
||
327 | array('fr_FR', 'es_ES'), |
||
328 | $enST->getTranslations()->column('Locale') |
||
329 | ); |
||
330 | $this->assertArrayEqualsAfterSort( |
||
331 | array('en_US', 'es_ES'), |
||
332 | $frST->getTranslations()->column('Locale') |
||
333 | ); |
||
334 | $this->assertArrayEqualsAfterSort( |
||
335 | array('en_US', 'fr_FR'), |
||
336 | $esST->getTranslations()->column('Locale') |
||
337 | ); |
||
338 | |||
339 | // this should be considered an edge-case, but on some sites translations |
||
340 | // may be allowed to be a subclass of the default locale's translation of |
||
341 | // the same page. In this case, we need to support getTranslations returning |
||
342 | // all of the translations, even if one of the translations is a different |
||
343 | // class from others |
||
344 | $esST->setClassName('Page'); |
||
345 | $esST->write(); |
||
346 | $esPg = DataObject::get_by_id('Page', $esST->ID, $cache = false); |
||
347 | |||
348 | // make sure we successfully changed the class |
||
349 | $this->assertClass('Page', $esPg); |
||
350 | |||
351 | // and make sure that the class of the others did not change |
||
352 | $frST = DataObject::get_by_id('SiteTree', $frST->ID, $cache = false); |
||
353 | $this->assertClass('SiteTree', $frST); |
||
354 | $enST = DataObject::get_by_id('SiteTree', $enST->ID, $cache = false); |
||
355 | $this->assertClass('SiteTree', $enST); |
||
356 | |||
357 | // now that we know our edge case is successfully configured, we need to |
||
358 | // make sure that we get the right translations back from everything |
||
359 | $this->assertArrayEqualsAfterSort( |
||
360 | array('fr_FR', 'es_ES'), |
||
361 | $enST->getTranslations()->column('Locale') |
||
362 | ); |
||
363 | $this->assertArrayEqualsAfterSort( |
||
364 | array('en_US', 'es_ES'), |
||
365 | $frST->getTranslations()->column('Locale') |
||
366 | ); |
||
367 | $this->assertArrayEqualsAfterSort( |
||
368 | array('en_US', 'fr_FR'), |
||
369 | $esPg->getTranslations()->column('Locale') |
||
370 | ); |
||
371 | $this->assertEquals($enST->ID, $esPg->getTranslation('en_US')->ID); |
||
372 | $this->assertEquals($frST->ID, $esPg->getTranslation('fr_FR')->ID); |
||
373 | $this->assertEquals($esPg->ID, $enST->getTranslation('es_ES')->ID); |
||
374 | $this->assertEquals($esPg->ID, $frST->getTranslation('es_ES')->ID); |
||
375 | } |
||
376 | |||
377 | public function testTranslationGroupNotRemovedWhenSiteTreeUnpublished() |
||
378 | { |
||
379 | $enPage = new Page(); |
||
380 | $enPage->Locale = 'en_US'; |
||
381 | $enPage->write(); |
||
382 | $enPage->publish('Stage', 'Live'); |
||
383 | $enTranslationGroup = $enPage->getTranslationGroup(); |
||
384 | |||
385 | $frPage = $enPage->createTranslation('fr_FR'); |
||
386 | $frPage->write(); |
||
387 | $frPage->publish('Stage', 'Live'); |
||
388 | $frTranslationGroup = $frPage->getTranslationGroup(); |
||
389 | |||
390 | $enPage->doUnpublish(); |
||
391 | $this->assertEquals($enPage->getTranslationGroup(), $enTranslationGroup); |
||
392 | |||
393 | $frPage->doUnpublish(); |
||
394 | $this->assertEquals($frPage->getTranslationGroup(), $frTranslationGroup); |
||
395 | } |
||
396 | |||
397 | public function testGetTranslationOnSiteTree() |
||
398 | { |
||
399 | $origPage = $this->objFromFixture('Page', 'testpage_en'); |
||
400 | |||
401 | $translatedPage = $origPage->createTranslation('fr_FR'); |
||
402 | $getTranslationPage = $origPage->getTranslation('fr_FR'); |
||
403 | |||
404 | $this->assertNotNull($getTranslationPage); |
||
405 | $this->assertEquals($getTranslationPage->ID, $translatedPage->ID); |
||
406 | } |
||
407 | |||
408 | public function testGetTranslatedLanguages() |
||
409 | { |
||
410 | $origPage = $this->objFromFixture('Page', 'testpage_en'); |
||
411 | |||
412 | // through createTranslation() |
||
413 | $translationAf = $origPage->createTranslation('af_ZA'); |
||
414 | |||
415 | // create a new language on an unrelated page which shouldnt be returned from $origPage |
||
416 | $otherPage = new Page(); |
||
417 | $otherPage->write(); |
||
418 | $otherTranslationEs = $otherPage->createTranslation('es_ES'); |
||
419 | |||
420 | $this->assertEquals( |
||
421 | $origPage->getTranslatedLangs(), |
||
422 | array( |
||
423 | 'af_ZA', |
||
424 | //'en_US', // default language is not included |
||
425 | ), |
||
426 | 'Language codes are returned specifically for the queried page through getTranslatedLangs()' |
||
427 | ); |
||
428 | |||
429 | $pageWithoutTranslations = new Page(); |
||
430 | $pageWithoutTranslations->write(); |
||
431 | $this->assertEquals( |
||
432 | $pageWithoutTranslations->getTranslatedLangs(), |
||
433 | array(), |
||
434 | 'A page without translations returns empty array through getTranslatedLangs(), ' . |
||
435 | 'even if translations for other pages exist in the database' |
||
436 | ); |
||
437 | |||
438 | // manual creation of page without an original link |
||
439 | $translationDeWithoutOriginal = new Page(); |
||
440 | $translationDeWithoutOriginal->Locale = 'de_DE'; |
||
441 | $translationDeWithoutOriginal->write(); |
||
442 | $this->assertEquals( |
||
443 | $translationDeWithoutOriginal->getTranslatedLangs(), |
||
444 | array(), |
||
445 | 'A translated page without an original doesn\'t return anything through getTranslatedLang()' |
||
446 | ); |
||
447 | } |
||
448 | |||
449 | public function testTranslationCantHaveSameURLSegmentAcrossLanguages() |
||
450 | { |
||
451 | $origPage = $this->objFromFixture('Page', 'testpage_en'); |
||
452 | $translatedPage = $origPage->createTranslation('de_DE'); |
||
453 | $this->assertEquals($translatedPage->URLSegment, 'testpage-de-de'); |
||
454 | |||
455 | $translatedPage->URLSegment = 'testpage'; // de_DE clashes with en_US |
||
456 | $translatedPage->write(); |
||
457 | $this->assertNotEquals($origPage->URLSegment, $translatedPage->URLSegment); |
||
458 | |||
459 | Translatable::set_current_locale('de_DE'); |
||
460 | Config::inst()->update('Translatable', 'enforce_global_unique_urls', false); |
||
461 | $translatedPage->URLSegment = 'testpage'; // de_DE clashes with en_US |
||
462 | $translatedPage->write(); |
||
463 | $this->assertEquals('testpage', $translatedPage->URLSegment); |
||
464 | Config::inst()->update('Translatable', 'enforce_global_unique_urls', true); |
||
465 | Translatable::set_current_locale('en_US'); |
||
466 | } |
||
467 | |||
468 | public function testUpdateCMSFieldsOnSiteTree() |
||
469 | { |
||
470 | $pageOrigLang = new TranslatableTest_Page(); |
||
471 | $pageOrigLang->write(); |
||
472 | |||
473 | // first test with default language |
||
474 | $fields = $pageOrigLang->getCMSFields(); |
||
475 | // title |
||
476 | $this->assertInstanceOf( |
||
477 | 'TextField', |
||
478 | $fields->dataFieldByName('Title'), |
||
479 | 'Translatable doesnt modify fields if called in default language (e.g. "non-translation mode")' |
||
480 | ); |
||
481 | $this->assertNull( |
||
482 | $fields->dataFieldByName('Title_original'), |
||
483 | 'Translatable doesnt modify fields if called in default language (e.g. "non-translation mode")' |
||
484 | ); |
||
485 | // custom property |
||
486 | $this->assertInstanceOf( |
||
487 | 'TextField', |
||
488 | $fields->dataFieldByName('TranslatableProperty'), |
||
489 | 'Has custom field' |
||
490 | ); |
||
491 | // custom has_one |
||
492 | $this->assertInstanceOf( |
||
493 | 'DropdownField', |
||
494 | $fields->dataFieldByName('TranslatableObjectID'), |
||
495 | 'Has custom dropdown field' |
||
496 | ); |
||
497 | |||
498 | // then in "translation mode" |
||
499 | $pageTranslated = $pageOrigLang->createTranslation('fr_FR'); |
||
500 | $fields = $pageTranslated->getCMSFields(); |
||
501 | // title |
||
502 | $this->assertInstanceOf( |
||
503 | 'TextField', |
||
504 | $fields->dataFieldByName('Title'), |
||
505 | 'Translatable leaves original formfield intact in "translation mode"' |
||
506 | ); |
||
507 | $readonlyField = $fields->dataFieldByName('Title')->performReadonlyTransformation(); |
||
508 | $this->assertInstanceOf( |
||
509 | $readonlyField->class, |
||
510 | $fields->dataFieldByName('Title_original'), |
||
511 | 'Translatable adds the original value as a ReadonlyField in "translation mode"' |
||
512 | ); |
||
513 | // custom property |
||
514 | $this->assertInstanceOf( |
||
515 | 'ReadonlyField', |
||
516 | $fields->dataFieldByName('TranslatableProperty_original'), |
||
517 | 'Adds original value for custom field as ReadonlyField' |
||
518 | ); |
||
519 | $this->assertInstanceOf( |
||
520 | 'TextField', |
||
521 | $fields->dataFieldByName('TranslatableProperty'), |
||
522 | 'Retains custom field as TextField' |
||
523 | ); |
||
524 | // custom has_one |
||
525 | $this->assertInstanceOf( |
||
526 | 'LookupField', |
||
527 | $fields->dataFieldByName('TranslatableObjectID_original'), |
||
528 | 'Adds original value for custom dropdown field as LookupField (= readonly version of DropdownField)' |
||
529 | ); |
||
530 | $this->assertInstanceOf( |
||
531 | 'DropdownField', |
||
532 | $fields->dataFieldByName('TranslatableObjectID'), |
||
533 | 'Retains custom dropdown field as DropdownField' |
||
534 | ); |
||
535 | } |
||
536 | |||
537 | public function testDataObjectGetWithReadingLanguage() |
||
538 | { |
||
539 | $origTestPage = $this->objFromFixture('Page', 'testpage_en'); |
||
540 | $otherTestPage = $this->objFromFixture('Page', 'othertestpage_en'); |
||
541 | $translatedPage = $origTestPage->createTranslation('de_DE'); |
||
542 | |||
543 | // test in default language |
||
544 | $resultPagesDefaultLang = DataObject::get( |
||
545 | 'Page', |
||
546 | sprintf("\"SiteTree\".\"MenuTitle\" = '%s'", 'A Testpage') |
||
547 | ); |
||
548 | $resultPagesDefaultLangIDs = $resultPagesDefaultLang->column('ID'); |
||
549 | foreach ($resultPagesDefaultLangIDs as $key => $val) { |
||
550 | $resultPagesDefaultLangIDs[$key] = intval($val); |
||
551 | } |
||
552 | $this->assertEquals($resultPagesDefaultLang->Count(), 2); |
||
553 | $this->assertContains((int)$origTestPage->ID, $resultPagesDefaultLangIDs); |
||
554 | $this->assertContains((int)$otherTestPage->ID, $resultPagesDefaultLangIDs); |
||
555 | $this->assertNotContains((int)$translatedPage->ID, $resultPagesDefaultLangIDs); |
||
556 | |||
557 | // test in custom language |
||
558 | Translatable::set_current_locale('de_DE'); |
||
559 | $resultPagesCustomLang = DataObject::get( |
||
560 | 'Page', |
||
561 | sprintf("\"SiteTree\".\"MenuTitle\" = '%s'", 'A Testpage') |
||
562 | ); |
||
563 | $resultPagesCustomLangIDs = $resultPagesCustomLang->column('ID'); |
||
564 | foreach ($resultPagesCustomLangIDs as $key => $val) { |
||
565 | $resultPagesCustomLangIDs[$key] = intval($val); |
||
566 | } |
||
567 | $this->assertEquals($resultPagesCustomLang->Count(), 1); |
||
568 | $this->assertNotContains((int)$origTestPage->ID, $resultPagesCustomLangIDs); |
||
569 | $this->assertNotContains((int)$otherTestPage->ID, $resultPagesCustomLangIDs); |
||
570 | $this->assertContains((int)$translatedPage->ID, $resultPagesCustomLangIDs); |
||
571 | |||
572 | Translatable::set_current_locale('en_US'); |
||
573 | } |
||
574 | |||
575 | public function testDataObjectGetByIdWithReadingLanguage() |
||
576 | { |
||
577 | $origPage = $this->objFromFixture('Page', 'testpage_en'); |
||
578 | $translatedPage = $origPage->createTranslation('de_DE'); |
||
579 | $compareOrigPage = DataObject::get_by_id('Page', $origPage->ID); |
||
580 | |||
581 | $this->assertEquals( |
||
582 | $origPage->ID, |
||
583 | $compareOrigPage->ID, |
||
584 | 'DataObject::get_by_id() should work independently of the reading language' |
||
585 | ); |
||
586 | } |
||
587 | |||
588 | public function testDataObjectGetOneWithReadingLanguage() |
||
589 | { |
||
590 | $origPage = $this->objFromFixture('Page', 'testpage_en'); |
||
591 | $translatedPage = $origPage->createTranslation('de_DE'); |
||
592 | |||
593 | // running the same query twice with different |
||
594 | Translatable::set_current_locale('de_DE'); |
||
595 | $compareTranslatedPage = DataObject::get_one( |
||
596 | 'Page', |
||
597 | sprintf("\"SiteTree\".\"Title\" = '%s'", $translatedPage->Title) |
||
598 | ); |
||
599 | $this->assertNotNull($compareTranslatedPage); |
||
600 | $this->assertEquals( |
||
601 | $translatedPage->ID, |
||
602 | $compareTranslatedPage->ID, |
||
603 | "Translated page is found through get_one() when reading lang is not the default language" |
||
604 | ); |
||
605 | |||
606 | // reset language to default |
||
607 | Translatable::set_current_locale('en_US'); |
||
608 | } |
||
609 | |||
610 | public function testModifyTranslationWithDefaultReadingLang() |
||
611 | { |
||
612 | $origPage = $this->objFromFixture('Page', 'testpage_en'); |
||
613 | $translatedPage = $origPage->createTranslation('de_DE'); |
||
614 | |||
615 | Translatable::set_current_locale('en_US'); |
||
616 | $translatedPage->Title = 'De Modified'; |
||
617 | $translatedPage->write(); |
||
618 | $savedTranslatedPage = $origPage->getTranslation('de_DE'); |
||
619 | $this->assertEquals( |
||
620 | $savedTranslatedPage->Title, |
||
621 | 'De Modified', |
||
622 | 'Modifying a record in language which is not the reading language should still write the record correctly' |
||
623 | ); |
||
624 | $this->assertEquals( |
||
625 | $origPage->Title, |
||
626 | 'Home', |
||
627 | 'Modifying a record in language which is not the reading language does not modify the original record' |
||
628 | ); |
||
629 | } |
||
630 | |||
631 | public function testSiteTreePublication() |
||
632 | { |
||
633 | $origPage = $this->objFromFixture('Page', 'testpage_en'); |
||
634 | $translatedPage = $origPage->createTranslation('de_DE'); |
||
635 | |||
636 | Translatable::set_current_locale('en_US'); |
||
637 | $origPage->Title = 'En Modified'; |
||
638 | $origPage->write(); |
||
639 | // modifying a record in language which is not the reading language should still write the record correctly |
||
640 | $translatedPage->Title = 'De Modified'; |
||
641 | $translatedPage->write(); |
||
642 | $origPage->publish('Stage', 'Live'); |
||
643 | $liveOrigPage = Versioned::get_one_by_stage('Page', 'Live', "\"SiteTree\".\"ID\" = {$origPage->ID}"); |
||
644 | $this->assertEquals( |
||
645 | $liveOrigPage->Title, |
||
646 | 'En Modified', |
||
647 | 'Publishing a record in its original language publshes correct properties' |
||
648 | ); |
||
649 | } |
||
650 | |||
651 | public function testDeletingTranslationKeepsOriginal() |
||
652 | { |
||
653 | $origPage = $this->objFromFixture('Page', 'testpage_en'); |
||
654 | $translatedPage = $origPage->createTranslation('de_DE'); |
||
655 | $translatedPageID = $translatedPage->ID; |
||
656 | $translatedPage->delete(); |
||
657 | |||
658 | $translatedPage->flushCache(); |
||
659 | $origPage->flushCache(); |
||
660 | |||
661 | $this->assertNull($origPage->getTranslation('de_DE')); |
||
662 | $this->assertNotNull(DataObject::get_by_id('Page', $origPage->ID)); |
||
663 | } |
||
664 | |||
665 | public function testHierarchyChildren() |
||
666 | { |
||
667 | $parentPage = $this->objFromFixture('Page', 'parent'); |
||
668 | $child1Page = $this->objFromFixture('Page', 'child1'); |
||
669 | $child2Page = $this->objFromFixture('Page', 'child2'); |
||
670 | $child3Page = $this->objFromFixture('Page', 'child3'); |
||
671 | $grandchildPage = $this->objFromFixture('Page', 'grandchild1'); |
||
672 | |||
673 | $parentPageTranslated = $parentPage->createTranslation('de_DE'); |
||
674 | $child4PageTranslated = new SiteTree(); |
||
675 | $child4PageTranslated->Locale = 'de_DE'; |
||
676 | $child4PageTranslated->ParentID = $parentPageTranslated->ID; |
||
677 | $child4PageTranslated->write(); |
||
678 | |||
679 | Translatable::set_current_locale('en_US'); |
||
680 | $this->assertArrayEqualsAfterSort( |
||
681 | array( |
||
682 | $child1Page->ID, |
||
683 | $child2Page->ID, |
||
684 | $child3Page->ID |
||
685 | ), |
||
686 | $parentPage->Children()->column('ID'), |
||
687 | "Showing Children() in default language doesnt show children in other languages" |
||
688 | ); |
||
689 | |||
690 | Translatable::set_current_locale('de_DE'); |
||
691 | $parentPage->flushCache(); |
||
692 | $this->assertEquals( |
||
693 | $parentPageTranslated->Children()->column('ID'), |
||
694 | array($child4PageTranslated->ID), |
||
695 | "Showing Children() in translation mode doesnt show children in default languages" |
||
696 | ); |
||
697 | |||
698 | // reset language |
||
699 | Translatable::set_current_locale('en_US'); |
||
700 | } |
||
701 | |||
702 | public function testHierarchyLiveStageChildren() |
||
703 | { |
||
704 | $parentPage = $this->objFromFixture('Page', 'parent'); |
||
705 | $child1Page = $this->objFromFixture('Page', 'child1'); |
||
706 | $child1Page->publish('Stage', 'Live'); |
||
707 | $child2Page = $this->objFromFixture('Page', 'child2'); |
||
708 | $child3Page = $this->objFromFixture('Page', 'child3'); |
||
709 | $grandchildPage = $this->objFromFixture('Page', 'grandchild1'); |
||
710 | |||
711 | $parentPageTranslated = $parentPage->createTranslation('de_DE'); |
||
712 | |||
713 | $child4PageTranslated = new SiteTree(); |
||
714 | $child4PageTranslated->Locale = 'de_DE'; |
||
715 | $child4PageTranslated->ParentID = $parentPageTranslated->ID; |
||
716 | $child4PageTranslated->write(); |
||
717 | $child4PageTranslated->publish('Stage', 'Live'); |
||
718 | |||
719 | $child5PageTranslated = new SiteTree(); |
||
720 | $child5PageTranslated->Locale = 'de_DE'; |
||
721 | $child5PageTranslated->ParentID = $parentPageTranslated->ID; |
||
722 | $child5PageTranslated->write(); |
||
723 | |||
724 | Translatable::set_current_locale('en_US'); |
||
725 | $this->assertNotNull($parentPage->liveChildren()); |
||
726 | $this->assertEquals( |
||
727 | $parentPage->liveChildren()->column('ID'), |
||
728 | array( |
||
729 | $child1Page->ID |
||
730 | ), |
||
731 | "Showing liveChildren() in default language doesnt show children in other languages" |
||
732 | ); |
||
733 | $this->assertNotNull($parentPage->stageChildren()); |
||
734 | $this->assertArrayEqualsAfterSort( |
||
735 | array( |
||
736 | $child1Page->ID, |
||
737 | $child2Page->ID, |
||
738 | $child3Page->ID |
||
739 | ), |
||
740 | $parentPage->stageChildren()->column('ID'), |
||
741 | "Showing stageChildren() in default language doesnt show children in other languages" |
||
742 | ); |
||
743 | |||
744 | Translatable::set_current_locale('de_DE'); |
||
745 | $parentPage->flushCache(); |
||
746 | $this->assertNotNull($parentPageTranslated->liveChildren()); |
||
747 | $this->assertEquals( |
||
748 | $parentPageTranslated->liveChildren()->column('ID'), |
||
749 | array($child4PageTranslated->ID), |
||
750 | "Showing liveChildren() in translation mode doesnt show children in default languages" |
||
751 | ); |
||
752 | $this->assertNotNull($parentPageTranslated->stageChildren()); |
||
753 | $this->assertEquals( |
||
754 | $parentPageTranslated->stageChildren()->column('ID'), |
||
755 | array( |
||
756 | $child4PageTranslated->ID, |
||
757 | $child5PageTranslated->ID, |
||
758 | ), |
||
759 | "Showing stageChildren() in translation mode doesnt show children in default languages" |
||
760 | ); |
||
761 | |||
762 | // reset language |
||
763 | Translatable::set_current_locale('en_US'); |
||
764 | } |
||
765 | |||
766 | public function testTranslatablePropertiesOnSiteTree() |
||
767 | { |
||
768 | $origObj = $this->objFromFixture('TranslatableTest_Page', 'testpage_en'); |
||
769 | |||
770 | $translatedObj = $origObj->createTranslation('fr_FR'); |
||
771 | $translatedObj->TranslatableProperty = 'fr_FR'; |
||
772 | $translatedObj->write(); |
||
773 | |||
774 | $this->assertEquals( |
||
775 | $origObj->TranslatableProperty, |
||
776 | 'en_US', |
||
777 | 'Creating a translation doesnt affect database field on original object' |
||
778 | ); |
||
779 | $this->assertEquals( |
||
780 | $translatedObj->TranslatableProperty, |
||
781 | 'fr_FR', |
||
782 | 'Translated object saves database field independently of original object' |
||
783 | ); |
||
784 | } |
||
785 | |||
786 | View Code Duplication | public function testCreateTranslationOnSiteTree() |
|
787 | { |
||
788 | $origPage = $this->objFromFixture('Page', 'testpage_en'); |
||
789 | $translatedPage = $origPage->createTranslation('de_DE'); |
||
790 | |||
791 | $this->assertEquals($translatedPage->Locale, 'de_DE'); |
||
792 | $this->assertNotEquals($translatedPage->ID, $origPage->ID); |
||
793 | |||
794 | $subsequentTranslatedPage = $origPage->createTranslation('de_DE'); |
||
795 | $this->assertEquals( |
||
796 | $translatedPage->ID, |
||
797 | $subsequentTranslatedPage->ID, |
||
798 | 'Subsequent calls to createTranslation() dont cause new records in database' |
||
799 | ); |
||
800 | } |
||
801 | |||
802 | public function testTranslatablePropertiesOnDataObject() |
||
803 | { |
||
804 | $origObj = $this->objFromFixture('TranslatableTest_DataObject', 'testobject_en'); |
||
805 | $translatedObj = $origObj->createTranslation('fr_FR'); |
||
806 | $translatedObj->TranslatableProperty = 'fr_FR'; |
||
807 | $translatedObj->TranslatableDecoratedProperty = 'fr_FR'; |
||
808 | $translatedObj->write(); |
||
809 | |||
810 | $this->assertEquals( |
||
811 | $origObj->TranslatableProperty, |
||
812 | 'en_US', |
||
813 | 'Creating a translation doesnt affect database field on original object' |
||
814 | ); |
||
815 | $this->assertEquals( |
||
816 | $origObj->TranslatableDecoratedProperty, |
||
817 | 'en_US', |
||
818 | 'Creating a translation doesnt affect decorated database field on original object' |
||
819 | ); |
||
820 | $this->assertEquals( |
||
821 | $translatedObj->TranslatableProperty, |
||
822 | 'fr_FR', |
||
823 | 'Translated object saves database field independently of original object' |
||
824 | ); |
||
825 | $this->assertEquals( |
||
826 | $translatedObj->TranslatableDecoratedProperty, |
||
827 | 'fr_FR', |
||
828 | 'Translated object saves decorated database field independently of original object' |
||
829 | ); |
||
830 | } |
||
831 | |||
832 | public function testCreateTranslationWithoutOriginal() |
||
833 | { |
||
834 | $origParentPage = $this->objFromFixture('Page', 'testpage_en'); |
||
835 | $translatedParentPage = $origParentPage->createTranslation('de_DE'); |
||
836 | |||
837 | $translatedPageWithoutOriginal = new SiteTree(); |
||
838 | $translatedPageWithoutOriginal->ParentID = $translatedParentPage->ID; |
||
839 | $translatedPageWithoutOriginal->Locale = 'de_DE'; |
||
840 | $translatedPageWithoutOriginal->write(); |
||
841 | |||
842 | Translatable::set_current_locale('de_DE'); |
||
843 | $this->assertEquals( |
||
844 | $translatedParentPage->stageChildren()->column('ID'), |
||
845 | array( |
||
846 | $translatedPageWithoutOriginal->ID |
||
847 | ), |
||
848 | "Children() still works on a translated page even if no translation group is set" |
||
849 | ); |
||
850 | |||
851 | Translatable::set_current_locale('en_US'); |
||
852 | } |
||
853 | |||
854 | public function testCreateTranslationTranslatesUntranslatedParents() |
||
855 | { |
||
856 | $parentPage = $this->objFromFixture('Page', 'parent'); |
||
857 | $child1Page = $this->objFromFixture('Page', 'child1'); |
||
858 | $child1PageOrigID = $child1Page->ID; |
||
859 | $grandChild1Page = $this->objFromFixture('Page', 'grandchild1'); |
||
860 | $grandChild2Page = $this->objFromFixture('Page', 'grandchild2'); |
||
861 | |||
862 | $this->assertFalse($grandChild1Page->hasTranslation('de_DE')); |
||
863 | $this->assertFalse($child1Page->hasTranslation('de_DE')); |
||
864 | $this->assertFalse($parentPage->hasTranslation('de_DE')); |
||
865 | |||
866 | $translatedGrandChild1Page = $grandChild1Page->createTranslation('de_DE'); |
||
867 | $translatedGrandChild2Page = $grandChild2Page->createTranslation('de_DE'); |
||
868 | $translatedChildPage = $child1Page->getTranslation('de_DE'); |
||
869 | $translatedParentPage = $parentPage->getTranslation('de_DE'); |
||
870 | |||
871 | $this->assertTrue($grandChild1Page->hasTranslation('de_DE')); |
||
872 | $this->assertEquals($translatedGrandChild1Page->ParentID, $translatedChildPage->ID); |
||
873 | |||
874 | $this->assertTrue($grandChild2Page->hasTranslation('de_DE')); |
||
875 | $this->assertEquals($translatedGrandChild2Page->ParentID, $translatedChildPage->ID); |
||
876 | |||
877 | $this->assertTrue($child1Page->hasTranslation('de_DE')); |
||
878 | $this->assertEquals($translatedChildPage->ParentID, $translatedParentPage->ID); |
||
879 | |||
880 | $this->assertTrue($parentPage->hasTranslation('de_DE')); |
||
881 | } |
||
882 | |||
883 | public function testHierarchyAllChildrenIncludingDeleted() |
||
884 | { |
||
885 | // Original tree in 'en_US': |
||
886 | // parent |
||
887 | // child1 (Live only, deleted from stage) |
||
888 | // child2 (Stage only, never published) |
||
889 | // child3 (Stage only, never published, untranslated) |
||
890 | // Translated tree in 'de_DE': |
||
891 | // parent |
||
892 | // child1 (Live only, deleted from stage) |
||
893 | // child2 (Stage only) |
||
894 | |||
895 | // Create parent |
||
896 | $parentPage = $this->objFromFixture('Page', 'parent'); |
||
897 | $parentPageID = $parentPage->ID; |
||
898 | |||
899 | // Create parent translation |
||
900 | $translatedParentPage = $parentPage->createTranslation('de_DE'); |
||
901 | $translatedParentPageID = $translatedParentPage->ID; |
||
902 | |||
903 | // Create child1 |
||
904 | $child1Page = $this->objFromFixture('Page', 'child1'); |
||
905 | $child1PageID = $child1Page->ID; |
||
906 | $child1Page->publish('Stage', 'Live'); |
||
907 | |||
908 | // Create child1 translation |
||
909 | $child1PageTranslated = $child1Page->createTranslation('de_DE'); |
||
910 | $child1PageTranslatedID = $child1PageTranslated->ID; |
||
911 | $child1PageTranslated->publish('Stage', 'Live'); |
||
912 | $child1PageTranslated->deleteFromStage('Stage'); // deleted from stage only, record still exists on live |
||
913 | $child1Page->deleteFromStage('Stage'); // deleted from stage only, record still exists on live |
||
914 | |||
915 | // Create child2 |
||
916 | $child2Page = $this->objFromFixture('Page', 'child2'); |
||
917 | $child2PageID = $child2Page->ID; |
||
918 | |||
919 | // Create child2 translation |
||
920 | $child2PageTranslated = $child2Page->createTranslation('de_DE'); |
||
921 | $child2PageTranslatedID = $child2PageTranslated->ID; |
||
922 | |||
923 | // Create child3 |
||
924 | $child3Page = $this->objFromFixture('Page', 'child3'); |
||
925 | $child3PageID = $child3Page->ID; |
||
926 | |||
927 | // on original parent in default language |
||
928 | Translatable::set_current_locale('en_US'); |
||
929 | SiteTree::flush_and_destroy_cache(); |
||
930 | $parentPage = $this->objFromFixture('Page', 'parent'); |
||
931 | $children = $parentPage->AllChildrenIncludingDeleted(); |
||
932 | $this->assertArrayEqualsAfterSort( |
||
933 | array( |
||
934 | $child2PageID, |
||
935 | $child3PageID, |
||
936 | $child1PageID // $child1Page was deleted from stage, so the original record doesn't have the ID set |
||
937 | ), |
||
938 | $parentPage->AllChildrenIncludingDeleted()->column('ID'), |
||
939 | "Showing AllChildrenIncludingDeleted() in default language doesnt show deleted children in other languages" |
||
940 | ); |
||
941 | |||
942 | // on original parent in translation mode |
||
943 | Translatable::set_current_locale('de_DE'); |
||
944 | SiteTree::flush_and_destroy_cache(); |
||
945 | $parentPage = $this->objFromFixture('Page', 'parent'); |
||
946 | $this->assertEquals( |
||
947 | $translatedParentPage->AllChildrenIncludingDeleted()->column('ID'), |
||
948 | array( |
||
949 | $child2PageTranslatedID, |
||
950 | // $child1PageTranslated was deleted from stage, so the original record doesn't have the ID set |
||
951 | $child1PageTranslatedID |
||
952 | ), |
||
953 | "Showing AllChildrenIncludingDeleted() in translation mode with parent page in " . |
||
954 | "translated language shows children in translated language" |
||
955 | ); |
||
956 | |||
957 | Translatable::set_current_locale('de_DE'); |
||
958 | SiteTree::flush_and_destroy_cache(); |
||
959 | $parentPage = $this->objFromFixture('Page', 'parent'); |
||
960 | $this->assertEquals( |
||
961 | $parentPage->AllChildrenIncludingDeleted()->column('ID'), |
||
962 | array(), |
||
963 | "Showing AllChildrenIncludingDeleted() in translation mode with parent page in " . |
||
964 | "translated language shows children in default language" |
||
965 | ); |
||
966 | |||
967 | // reset language |
||
968 | Translatable::set_current_locale('en_US'); |
||
969 | } |
||
970 | |||
971 | public function testRootUrlDefaultsToTranslatedLink() |
||
972 | { |
||
973 | $origPage = $this->objFromFixture('Page', 'homepage_en'); |
||
974 | $origPage->publish('Stage', 'Live'); |
||
975 | $translationDe = $origPage->createTranslation('de_DE'); |
||
976 | $translationDe->URLSegment = 'heim'; |
||
977 | $translationDe->write(); |
||
978 | $translationDe->publish('Stage', 'Live'); |
||
979 | |||
980 | // test with translatable |
||
981 | Translatable::set_current_locale('de_DE'); |
||
982 | $this->assertEquals( |
||
983 | RootURLController::get_homepage_link(), |
||
984 | 'heim', |
||
985 | 'Homepage with different URLSegment in non-default language is found' |
||
986 | ); |
||
987 | |||
988 | // @todo Fix add/remove extension |
||
989 | // test with translatable disabled |
||
990 | // Object::remove_extension('Page', 'Translatable'); |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
64% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them.
Loading history...
|
|||
991 | // $_SERVER['HTTP_HOST'] = '/'; |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
60% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them.
Loading history...
|
|||
992 | // $this->assertEquals( |
||
993 | // RootURLController::get_homepage_urlsegment(), |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
58% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them.
Loading history...
|
|||
994 | // 'home', |
||
995 | // 'Homepage is showing in default language if ?lang GET variable is left out' |
||
996 | // ); |
||
997 | // Object::add_extension('Page', 'Translatable'); |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
64% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them.
Loading history...
|
|||
998 | |||
999 | // setting back to default |
||
1000 | Translatable::set_current_locale('en_US'); |
||
1001 | } |
||
1002 | |||
1003 | public function testSiteTreeChangePageTypeInMaster() |
||
1004 | { |
||
1005 | // create original |
||
1006 | $origPage = new SiteTree(); |
||
1007 | $origPage->Locale = 'en_US'; |
||
1008 | $origPage->write(); |
||
1009 | $origPageID = $origPage->ID; |
||
1010 | |||
1011 | // create translation |
||
1012 | $translatedPage = $origPage->createTranslation('de_DE'); |
||
1013 | $translatedPageID = $translatedPage->ID; |
||
1014 | |||
1015 | // change page type |
||
1016 | $newPage = $origPage->newClassInstance('RedirectorPage'); |
||
1017 | $newPage->write(); |
||
1018 | |||
1019 | // re-fetch original page with new instance |
||
1020 | $origPageChanged = DataObject::get_by_id('RedirectorPage', $origPageID); |
||
1021 | $this->assertEquals($origPageChanged->ClassName, 'RedirectorPage', |
||
1022 | 'A ClassName change to an original page doesnt change original classname' |
||
1023 | ); |
||
1024 | |||
1025 | // re-fetch the translation with new instance |
||
1026 | Translatable::set_current_locale('de_DE'); |
||
1027 | $translatedPageChanged = DataObject::get_by_id('RedirectorPage', $translatedPageID); |
||
1028 | $translatedPageChanged = $origPageChanged->getTranslation('de_DE'); |
||
1029 | $this->assertEquals($translatedPageChanged->ClassName, 'RedirectorPage', |
||
1030 | 'ClassName change on an original page also changes ClassName attribute of translation' |
||
1031 | ); |
||
1032 | } |
||
1033 | |||
1034 | public function testGetTranslationByStage() |
||
1035 | { |
||
1036 | $publishedPage = new SiteTree(); |
||
1037 | $publishedPage->Locale = 'en_US'; |
||
1038 | $publishedPage->Title = 'Published'; |
||
1039 | $publishedPage->write(); |
||
1040 | $publishedPage->publish('Stage', 'Live'); |
||
1041 | $publishedPage->Title = 'Unpublished'; |
||
1042 | $publishedPage->write(); |
||
1043 | |||
1044 | $publishedTranslatedPage = $publishedPage->createTranslation('de_DE'); |
||
1045 | $publishedTranslatedPage->Title = 'Publiziert'; |
||
1046 | $publishedTranslatedPage->write(); |
||
1047 | $publishedTranslatedPage->publish('Stage', 'Live'); |
||
1048 | $publishedTranslatedPage->Title = 'Unpubliziert'; |
||
1049 | $publishedTranslatedPage->write(); |
||
1050 | |||
1051 | $compareStage = $publishedPage->getTranslation('de_DE', 'Stage'); |
||
1052 | $this->assertNotNull($compareStage); |
||
1053 | $this->assertEquals($compareStage->Title, 'Unpubliziert'); |
||
1054 | |||
1055 | $compareLive = $publishedPage->getTranslation('de_DE', 'Live'); |
||
1056 | $this->assertNotNull($compareLive); |
||
1057 | $this->assertEquals($compareLive->Title, 'Publiziert'); |
||
1058 | } |
||
1059 | |||
1060 | public function testCanTranslateAllowedLocales() |
||
1061 | { |
||
1062 | $origAllowedLocales = Translatable::get_allowed_locales(); |
||
1063 | |||
1064 | $cmseditor = $this->objFromFixture('Member', 'cmseditor'); |
||
1065 | |||
1066 | $testPage = $this->objFromFixture('Page', 'testpage_en'); |
||
1067 | $this->assertTrue( |
||
1068 | $testPage->canTranslate($cmseditor, 'de_DE'), |
||
1069 | "Users with canEdit() and TRANSLATE_ALL permission can create a new translation if locales are not limited" |
||
1070 | ); |
||
1071 | |||
1072 | Translatable::set_allowed_locales(array('ja_JP')); |
||
1073 | $this->assertTrue( |
||
1074 | $testPage->canTranslate($cmseditor, 'ja_JP'), |
||
1075 | "Users with canEdit() and TRANSLATE_ALL permission can create a new translation " . |
||
1076 | "if locale is in Translatable::get_allowed_locales()" |
||
1077 | ); |
||
1078 | $this->assertFalse( |
||
1079 | $testPage->canTranslate($cmseditor, 'de_DE'), |
||
1080 | "Users with canEdit() and TRANSLATE_ALL permission can't create a new translation if " . |
||
1081 | "locale is not in Translatable::get_allowed_locales()" |
||
1082 | ); |
||
1083 | |||
1084 | $this->assertInstanceOf( |
||
1085 | 'Page', |
||
1086 | $testPage->createTranslation('ja_JP') |
||
1087 | ); |
||
1088 | try { |
||
1089 | $testPage->createTranslation('de_DE'); |
||
1090 | $this->setExpectedException("Exception"); |
||
1091 | } catch (Exception $e) { |
||
1092 | } |
||
1093 | |||
1094 | Translatable::set_allowed_locales($origAllowedLocales); |
||
1095 | } |
||
1096 | |||
1097 | public function testCanTranslatePermissionCodes() |
||
1098 | { |
||
1099 | $origAllowedLocales = Translatable::get_allowed_locales(); |
||
1100 | |||
1101 | Translatable::set_allowed_locales(array('ja_JP', 'de_DE')); |
||
1102 | |||
1103 | $cmseditor = $this->objFromFixture('Member', 'cmseditor'); |
||
1104 | |||
1105 | $testPage = $this->objFromFixture('Page', 'testpage_en'); |
||
1106 | $this->assertTrue( |
||
1107 | $testPage->canTranslate($cmseditor, 'de_DE'), |
||
1108 | "Users with TRANSLATE_ALL permission can create a new translation" |
||
1109 | ); |
||
1110 | |||
1111 | $translator = $this->objFromFixture('Member', 'germantranslator'); |
||
1112 | |||
1113 | $testPage = $this->objFromFixture('Page', 'testpage_en'); |
||
1114 | $this->assertTrue( |
||
1115 | $testPage->canTranslate($translator, 'de_DE'), |
||
1116 | "Users with TRANSLATE_<locale> permission can create a new translation" |
||
1117 | ); |
||
1118 | |||
1119 | $this->assertFalse( |
||
1120 | $testPage->canTranslate($translator, 'ja_JP'), |
||
1121 | "Users without TRANSLATE_<locale> permission can create a new translation" |
||
1122 | ); |
||
1123 | |||
1124 | Translatable::set_allowed_locales($origAllowedLocales); |
||
1125 | } |
||
1126 | |||
1127 | public function testLocalesForMember() |
||
1128 | { |
||
1129 | $origAllowedLocales = Translatable::get_allowed_locales(); |
||
1130 | Translatable::set_allowed_locales(array('de_DE', 'ja_JP')); |
||
1131 | |||
1132 | $cmseditor = $this->objFromFixture('Member', 'cmseditor'); |
||
1133 | $translator = $this->objFromFixture('Member', 'germantranslator'); |
||
1134 | |||
1135 | $this->assertEquals( |
||
1136 | array('de_DE', 'ja_JP'), |
||
1137 | singleton('SiteTree')->getAllowedLocalesForMember($cmseditor), |
||
1138 | 'Members with TRANSLATE_ALL permission can edit all locales' |
||
1139 | ); |
||
1140 | |||
1141 | $this->assertEquals( |
||
1142 | array('de_DE'), |
||
1143 | singleton('SiteTree')->getAllowedLocalesForMember($translator), |
||
1144 | 'Members with TRANSLATE_<locale> permission cant edit all locales' |
||
1145 | ); |
||
1146 | |||
1147 | Translatable::set_allowed_locales($origAllowedLocales); |
||
1148 | } |
||
1149 | |||
1150 | public function testSavePageInCMS() |
||
1151 | { |
||
1152 | $adminUser = $this->objFromFixture('Member', 'admin'); |
||
1153 | $enPage = $this->objFromFixture('Page', 'testpage_en'); |
||
1154 | |||
1155 | $group = new Group(); |
||
1156 | $group->Title = 'Example Group'; |
||
1157 | $group->write(); |
||
1158 | |||
1159 | $frPage = $enPage->createTranslation('fr_FR'); |
||
1160 | $frPage->write(); |
||
1161 | |||
1162 | $adminUser->logIn(); |
||
1163 | |||
1164 | $cmsMain = new CMSPageEditController(); |
||
1165 | |||
1166 | $origLocale = Translatable::get_current_locale(); |
||
1167 | Translatable::set_current_locale('fr_FR'); |
||
1168 | |||
1169 | $form = $cmsMain->getEditForm($frPage->ID); |
||
1170 | $form->loadDataFrom(array( |
||
1171 | 'Title' => 'Translated', // $db field |
||
1172 | )); |
||
1173 | $form->saveInto($frPage); |
||
1174 | $frPage->write(); |
||
1175 | |||
1176 | $this->assertEquals('Translated', $frPage->Title); |
||
1177 | |||
1178 | $adminUser->logOut(); |
||
1179 | Translatable::set_current_locale($origLocale); |
||
1180 | } |
||
1181 | |||
1182 | public function testAlternateGetByLink() |
||
1183 | { |
||
1184 | $parent = $this->objFromFixture('Page', 'parent'); |
||
1185 | $child = $this->objFromFixture('Page', 'child1'); |
||
1186 | $grandchild = $this->objFromFixture('Page', 'grandchild1'); |
||
1187 | |||
1188 | $parentTranslation = $parent->createTranslation('en_AU'); |
||
1189 | $parentTranslation->write(); |
||
1190 | |||
1191 | $childTranslation = $child->createTranslation('en_AU'); |
||
1192 | $childTranslation->write(); |
||
1193 | |||
1194 | $grandchildTranslation = $grandchild->createTranslation('en_AU'); |
||
1195 | $grandchildTranslation->write(); |
||
1196 | |||
1197 | Translatable::set_current_locale('en_AU'); |
||
1198 | |||
1199 | $this->assertEquals( |
||
1200 | $parentTranslation->ID, |
||
1201 | Sitetree::get_by_link($parentTranslation->Link())->ID, |
||
1202 | 'Top level pages can be found.' |
||
1203 | ); |
||
1204 | |||
1205 | $this->assertEquals( |
||
1206 | $childTranslation->ID, |
||
1207 | SiteTree::get_by_link($childTranslation->Link())->ID, |
||
1208 | 'Child pages can be found.' |
||
1209 | ); |
||
1210 | |||
1211 | $this->assertEquals( |
||
1212 | $grandchildTranslation->ID, |
||
1213 | SiteTree::get_by_link($grandchildTranslation->Link())->ID, |
||
1214 | 'Grandchild pages can be found.' |
||
1215 | ); |
||
1216 | |||
1217 | // TODO Re-enable test after clarifying with ajshort (see r88503). |
||
1218 | // Its unclear if this is valid behaviour, and/or necessary for translated nested URLs |
||
1219 | // to work properly |
||
1220 | // |
||
1221 | // $this->assertEquals ( |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
50% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them.
Loading history...
|
|||
1222 | // $child->ID, |
||
1223 | // SiteTree::get_by_link($parentTranslation->Link($child->URLSegment))->ID, |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
65% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them.
Loading history...
|
|||
1224 | // 'Links can be made up of multiple languages' |
||
1225 | // ); |
||
1226 | } |
||
1227 | |||
1228 | View Code Duplication | public function testSiteTreeGetByLinkFindsTranslationWithoutLocale() |
|
1229 | { |
||
1230 | $parent = $this->objFromFixture('Page', 'parent'); |
||
1231 | |||
1232 | $parentTranslation = $parent->createTranslation('en_AU'); |
||
1233 | $parentTranslation->URLSegment = 'parent-en-AU'; |
||
1234 | $parentTranslation->write(); |
||
1235 | |||
1236 | $match = Sitetree::get_by_link($parentTranslation->URLSegment); |
||
1237 | $this->assertNotNull( |
||
1238 | $match, |
||
1239 | 'SiteTree::get_by_link() doesnt need a locale setting to find translated pages' |
||
1240 | ); |
||
1241 | $this->assertEquals( |
||
1242 | $parentTranslation->ID, |
||
1243 | $match->ID, |
||
1244 | 'SiteTree::get_by_link() doesnt need a locale setting to find translated pages' |
||
1245 | ); |
||
1246 | } |
||
1247 | } |
||
1248 | |||
1249 | class TranslatableTest_OneByLocaleDataObject extends DataObject implements TestOnly |
||
1250 | { |
||
1251 | private static $db = array( |
||
1252 | 'TranslatableProperty' => 'Text' |
||
1253 | ); |
||
1254 | } |
||
1255 | |||
1256 | class TranslatableTest_DataObject extends DataObject implements TestOnly |
||
1257 | { |
||
1258 | // add_extension() used to add decorator at end of file |
||
1259 | |||
1260 | private static $db = array( |
||
1261 | 'TranslatableProperty' => 'Text' |
||
1262 | ); |
||
1263 | } |
||
1264 | |||
1265 | class TranslatableTest_Extension extends DataExtension implements TestOnly |
||
1266 | { |
||
1267 | private static $db = array( |
||
1268 | 'TranslatableDecoratedProperty' => 'Text' |
||
1269 | ); |
||
1270 | } |
||
1271 | |||
1272 | class TranslatableTest_Page extends Page implements TestOnly |
||
1273 | { |
||
1274 | // static $extensions is inherited from SiteTree, |
||
1275 | // we don't need to explicitly specify the fields |
||
1276 | |||
1277 | private static $db = array( |
||
1278 | 'TranslatableProperty' => 'Text' |
||
1279 | ); |
||
1280 | |||
1281 | private static $has_one = array( |
||
1282 | 'TranslatableObject' => 'TranslatableTest_DataObject' |
||
1283 | ); |
||
1284 | |||
1285 | public function getCMSFields() |
||
1286 | { |
||
1287 | $fields = parent::getCMSFields(); |
||
1288 | $fields->addFieldToTab( |
||
1289 | 'Root.Main', |
||
1290 | new TextField('TranslatableProperty') |
||
1291 | ); |
||
1292 | $fields->addFieldToTab( |
||
1293 | 'Root.Main', |
||
1294 | new DropdownField('TranslatableObjectID') |
||
1295 | ); |
||
1296 | |||
1297 | $this->applyTranslatableFieldsUpdate($fields, 'updateCMSFields'); |
||
1298 | |||
1299 | return $fields; |
||
1300 | } |
||
1301 | } |
||
1302 | |||
1303 | |||
1304 | class EveryoneCanPublish extends DataExtension |
||
1305 | { |
||
1306 | public function canPublish($member = null) |
||
1307 | { |
||
1308 | return true; |
||
1309 | } |
||
1310 | } |
||
1311 | |||
1312 | TranslatableTest_DataObject::add_extension('TranslatableTest_Extension'); |
||
1313 |
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.