This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
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'); |
||
0 ignored issues
–
show
|
|||
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'); |
||
0 ignored issues
–
show
$otherTranslationEs is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
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'); |
||
0 ignored issues
–
show
$translatedPage is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
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; |
||
0 ignored issues
–
show
$translatedPageID is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
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'); |
||
0 ignored issues
–
show
$grandchildPage is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
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'); |
||
0 ignored issues
–
show
$grandchildPage is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
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() |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
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; |
||
0 ignored issues
–
show
$child1PageOrigID is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
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; |
||
0 ignored issues
–
show
$parentPageID is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
898 | |||
899 | // Create parent translation |
||
900 | $translatedParentPage = $parentPage->createTranslation('de_DE'); |
||
901 | $translatedParentPageID = $translatedParentPage->ID; |
||
0 ignored issues
–
show
$translatedParentPageID is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
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(); |
||
0 ignored issues
–
show
$children is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
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'); |
||
0 ignored issues
–
show
$parentPage is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
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'); |
||
991 | // $_SERVER['HTTP_HOST'] = '/'; |
||
992 | // $this->assertEquals( |
||
993 | // RootURLController::get_homepage_urlsegment(), |
||
994 | // 'home', |
||
995 | // 'Homepage is showing in default language if ?lang GET variable is left out' |
||
996 | // ); |
||
997 | // Object::add_extension('Page', 'Translatable'); |
||
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); |
||
0 ignored issues
–
show
$translatedPageChanged is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
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) { |
||
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
|
|||
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 ( |
||
1222 | // $child->ID, |
||
1223 | // SiteTree::get_by_link($parentTranslation->Link($child->URLSegment))->ID, |
||
1224 | // 'Links can be made up of multiple languages' |
||
1225 | // ); |
||
1226 | } |
||
1227 | |||
1228 | View Code Duplication | public function testSiteTreeGetByLinkFindsTranslationWithoutLocale() |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
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 |
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.
Both the
$myVar
assignment in line 1 and the$higher
assignment in line 2 are dead. The first because$myVar
is never used and the second because$higher
is always overwritten for every possible time line.