These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | use SilverStripe\ORM\DataObject; |
||
4 | require_once 'Zend/Translate.php'; |
||
5 | |||
6 | /** |
||
7 | * @package framework |
||
8 | * @subpackage tests |
||
9 | */ |
||
10 | class i18nTest extends SapphireTest { |
||
11 | |||
12 | /** |
||
13 | * @var string $tmpBasePath Used to write language files. |
||
14 | * We don't want to store them inside framework (or in any web-accessible place) |
||
15 | * in case something goes wrong with the file parsing. |
||
16 | */ |
||
17 | protected $alternateBaseSavePath; |
||
18 | |||
19 | /** |
||
20 | * @var string $alternateBasePath Fake webroot with a single module |
||
21 | * /i18ntestmodule which contains some files with _t() calls. |
||
22 | */ |
||
23 | protected $alternateBasePath; |
||
24 | |||
25 | protected $extraDataObjects = array( |
||
26 | 'i18nTest_DataObject' |
||
27 | ); |
||
28 | |||
29 | |||
30 | public function setUp() { |
||
31 | parent::setUp(); |
||
32 | |||
33 | $this->alternateBasePath = $this->getCurrentAbsolutePath() . DIRECTORY_SEPARATOR . "_fakewebroot"; |
||
34 | $this->alternateBaseSavePath = TEMP_FOLDER . DIRECTORY_SEPARATOR . 'i18nTextCollectorTest_webroot'; |
||
35 | FileSystem::makeFolder($this->alternateBaseSavePath); |
||
36 | Config::inst()->update('Director', 'alternate_base_folder', $this->alternateBasePath); |
||
37 | |||
38 | // Push a template loader running from the fake webroot onto the stack. |
||
39 | $templateManifest = new SS_TemplateManifest($this->alternateBasePath, null, false, true); |
||
40 | $templateManifest->regenerate(false); |
||
41 | SS_TemplateLoader::instance()->pushManifest($templateManifest); |
||
42 | $this->_oldTheme = Config::inst()->get('SSViewer', 'theme'); |
||
43 | Config::inst()->update('SSViewer', 'theme', 'testtheme1'); |
||
44 | |||
45 | $this->originalLocale = i18n::get_locale(); |
||
46 | |||
47 | // Override default adapter to avoid cached translations between tests. |
||
48 | // Emulates behaviour in i18n::get_translators() |
||
49 | $this->origAdapter = i18n::get_translator('core'); |
||
50 | $adapter = new Zend_Translate(array( |
||
51 | 'adapter' => 'i18nRailsYamlAdapter', |
||
52 | 'locale' => i18n::default_locale(), |
||
0 ignored issues
–
show
|
|||
53 | 'disableNotices' => true, |
||
54 | )); |
||
55 | i18n::register_translator($adapter, 'core'); |
||
56 | $adapter->removeCache(); |
||
57 | i18n::include_by_locale('en'); |
||
58 | } |
||
59 | |||
60 | public function tearDown() { |
||
61 | SS_TemplateLoader::instance()->popManifest(); |
||
62 | i18n::set_locale($this->originalLocale); |
||
63 | Config::inst()->update('Director', 'alternate_base_folder', null); |
||
64 | Config::inst()->update('SSViewer', 'theme', $this->_oldTheme); |
||
65 | i18n::register_translator($this->origAdapter, 'core'); |
||
66 | |||
67 | parent::tearDown(); |
||
68 | } |
||
69 | |||
70 | public function testGetExistingTranslations() { |
||
71 | $translations = i18n::get_existing_translations(); |
||
72 | $this->assertTrue(isset($translations['en_US']), 'Checking for en translation'); |
||
73 | $this->assertEquals($translations['en_US'], 'English (United States)'); |
||
74 | $this->assertTrue(isset($translations['de_DE']), 'Checking for de_DE translation'); |
||
75 | } |
||
76 | |||
77 | public function testGetClosestTranslation() { |
||
78 | |||
79 | // Validate necessary assumptions for this test |
||
80 | $translations = i18n::get_existing_translations(); |
||
81 | $this->assertTrue(isset($translations['en_US'])); |
||
82 | $this->assertTrue(isset($translations['en_GB'])); |
||
83 | $this->assertTrue(isset($translations['es_ES'])); |
||
84 | $this->assertTrue(isset($translations['es_AR'])); |
||
85 | $this->assertFalse(isset($translations['en_ZZ'])); |
||
86 | $this->assertFalse(isset($translations['es_ZZ'])); |
||
87 | $this->assertFalse(isset($translations['zz_ZZ'])); |
||
88 | |||
89 | // Test indeterminate locales |
||
90 | $this->assertEmpty(i18n::get_closest_translation('zz_ZZ')); |
||
91 | |||
92 | // Test english fallback |
||
93 | $this->assertEquals('en_US', i18n::get_closest_translation('en_US')); |
||
94 | $this->assertEquals('en_GB', i18n::get_closest_translation('en_GB')); |
||
95 | $this->assertEquals('en_US', i18n::get_closest_translation('en_ZZ')); |
||
96 | |||
97 | // Test spanish fallbacks |
||
98 | $this->assertEquals('es_AR', i18n::get_closest_translation('es_AR')); |
||
99 | $this->assertEquals('es_ES', i18n::get_closest_translation('es_ES')); |
||
100 | $this->assertEquals('es_ES', i18n::get_closest_translation('es_XX')); |
||
101 | } |
||
102 | |||
103 | public function testDataObjectFieldLabels() { |
||
104 | $oldLocale = i18n::get_locale(); |
||
105 | i18n::set_locale('de_DE'); |
||
106 | $obj = new i18nTest_DataObject(); |
||
107 | |||
108 | i18n::get_translator('core')->getAdapter()->addTranslation(array( |
||
109 | 'i18nTest_DataObject.MyProperty' => 'MyProperty' |
||
110 | ), 'en_US'); |
||
111 | i18n::get_translator('core')->getAdapter()->addTranslation(array( |
||
112 | 'i18nTest_DataObject.MyProperty' => 'Mein Attribut' |
||
113 | ), 'de_DE'); |
||
114 | |||
115 | $this->assertEquals( |
||
116 | $obj->fieldLabel('MyProperty'), |
||
117 | 'Mein Attribut' |
||
118 | ); |
||
119 | |||
120 | i18n::get_translator('core')->getAdapter()->addTranslation(array( |
||
121 | 'i18nTest_DataObject.MyUntranslatedProperty' => 'Mein Attribut' |
||
122 | ), 'en_US'); |
||
123 | $this->assertEquals( |
||
124 | $obj->fieldLabel('MyUntranslatedProperty'), |
||
125 | 'My Untranslated Property' |
||
126 | ); |
||
127 | |||
128 | i18n::set_locale($oldLocale); |
||
129 | } |
||
130 | |||
131 | public function testProvideI18nEntities() { |
||
132 | $oldLocale = i18n::get_locale(); |
||
133 | i18n::set_locale('en_US'); |
||
134 | |||
135 | i18n::get_translator('core')->getAdapter()->addTranslation(array( |
||
136 | 'i18nTest_Object.MyProperty' => 'Untranslated' |
||
137 | ), 'en_US'); |
||
138 | i18n::get_translator('core')->getAdapter()->addTranslation(array( |
||
139 | 'i18nTest_Object.my_translatable_property' => 'Übersetzt' |
||
140 | ), 'de_DE'); |
||
141 | |||
142 | $this->assertEquals( |
||
143 | i18nTest_Object::$my_translatable_property, |
||
144 | 'Untranslated' |
||
145 | ); |
||
146 | $this->assertEquals( |
||
147 | i18nTest_Object::my_translatable_property(), |
||
148 | 'Untranslated' |
||
149 | ); |
||
150 | |||
151 | i18n::set_locale('en_US'); |
||
152 | $this->assertEquals( |
||
153 | i18nTest_Object::my_translatable_property(), |
||
154 | 'Untranslated', |
||
155 | 'Getter returns original static value when called in default locale' |
||
156 | ); |
||
157 | |||
158 | i18n::set_locale('de_DE'); |
||
159 | $this->assertEquals( |
||
160 | i18nTest_Object::my_translatable_property(), |
||
161 | 'Übersetzt', |
||
162 | 'Getter returns translated value when called in another locale' |
||
163 | ); |
||
164 | } |
||
165 | |||
166 | public function testTemplateTranslation() { |
||
167 | $oldLocale = i18n::get_locale(); |
||
168 | |||
169 | i18n::set_locale('en_US'); |
||
170 | i18n::get_translator('core')->getAdapter()->addTranslation(array( |
||
171 | 'i18nTestModule.MAINTEMPLATE' => 'Main Template', |
||
172 | 'i18nTestModule.ss.SPRINTFNONAMESPACE' => 'My replacement no namespace: %s', |
||
173 | 'i18nTestModule.LAYOUTTEMPLATE' => 'Layout Template', |
||
174 | 'i18nTestModule.ss.LAYOUTTEMPLATENONAMESPACE' => 'Layout Template no namespace', |
||
175 | 'i18nTestModule.SPRINTFNAMESPACE' => 'My replacement: %s', |
||
176 | 'i18nTestModule.WITHNAMESPACE' => 'Include Entity with Namespace', |
||
177 | 'i18nTestModuleInclude.ss.NONAMESPACE' => 'Include Entity without Namespace', |
||
178 | 'i18nTestModuleInclude.ss.SPRINTFINCLUDENAMESPACE' => 'My include replacement: %s', |
||
179 | 'i18nTestModuleInclude.ss.SPRINTFINCLUDENONAMESPACE' => 'My include replacement no namespace: %s' |
||
180 | ), 'en_US'); |
||
181 | |||
182 | $viewer = new SSViewer('i18nTestModule'); |
||
183 | $parsedHtml = Convert::nl2os($viewer->process(new ArrayData(array('TestProperty' => 'TestPropertyValue')))); |
||
184 | $this->assertContains( |
||
185 | Convert::nl2os("Layout Template\n"), |
||
186 | $parsedHtml |
||
187 | ); |
||
188 | $this->assertContains( |
||
189 | Convert::nl2os("Layout Template no namespace\n"), |
||
190 | $parsedHtml |
||
191 | ); |
||
192 | |||
193 | i18n::set_locale('de_DE'); |
||
194 | i18n::get_translator('core')->getAdapter()->addTranslation(array( |
||
195 | 'i18nTestModule.MAINTEMPLATE' => 'TRANS Main Template', |
||
196 | 'i18nTestModule.ss.SPRINTFNONAMESPACE' => 'TRANS My replacement no namespace: %s', |
||
197 | 'i18nTestModule.LAYOUTTEMPLATE' => 'TRANS Layout Template', |
||
198 | 'i18nTestModule.ss.LAYOUTTEMPLATENONAMESPACE' => 'TRANS Layout Template no namespace', |
||
199 | 'i18nTestModule.SPRINTFNAMESPACE' => 'TRANS My replacement: %s', |
||
200 | 'i18nTestModule.WITHNAMESPACE' => 'TRANS Include Entity with Namespace', |
||
201 | 'i18nTestModuleInclude.ss.NONAMESPACE' => 'TRANS Include Entity without Namespace', |
||
202 | 'i18nTestModuleInclude.ss.SPRINTFINCLUDENAMESPACE' => 'TRANS My include replacement: %s', |
||
203 | 'i18nTestModuleInclude.ss.SPRINTFINCLUDENONAMESPACE' => 'TRANS My include replacement no namespace: %s' |
||
204 | ), 'de_DE'); |
||
205 | |||
206 | $viewer = new SSViewer('i18nTestModule'); |
||
207 | $parsedHtml = Convert::nl2os($viewer->process(new ArrayData(array('TestProperty' => 'TestPropertyValue')))); |
||
208 | $this->assertContains( |
||
209 | Convert::nl2os("TRANS Main Template\n"), |
||
210 | $parsedHtml |
||
211 | ); |
||
212 | $this->assertContains( |
||
213 | Convert::nl2os("TRANS Layout Template\n"), |
||
214 | $parsedHtml |
||
215 | ); |
||
216 | $this->assertContains( |
||
217 | Convert::nl2os("TRANS Layout Template no namespace\n"), |
||
218 | $parsedHtml |
||
219 | ); |
||
220 | $this->assertContains( |
||
221 | Convert::nl2os("TRANS My replacement: TestPropertyValue\n"), |
||
222 | $parsedHtml |
||
223 | ); |
||
224 | $this->assertContains( |
||
225 | Convert::nl2os("TRANS Include Entity with Namespace\n"), |
||
226 | $parsedHtml |
||
227 | ); |
||
228 | $this->assertContains( |
||
229 | Convert::nl2os("TRANS Include Entity without Namespace\n"), |
||
230 | $parsedHtml |
||
231 | ); |
||
232 | $this->assertContains( |
||
233 | Convert::nl2os("TRANS My include replacement: TestPropertyValue\n"), |
||
234 | $parsedHtml |
||
235 | ); |
||
236 | $this->assertContains( |
||
237 | Convert::nl2os("TRANS My include replacement no namespace: TestPropertyValue\n"), |
||
238 | $parsedHtml |
||
239 | ); |
||
240 | |||
241 | i18n::set_locale($oldLocale); |
||
242 | } |
||
243 | |||
244 | public function testNewTMethodSignature() { |
||
245 | global $lang; |
||
0 ignored issues
–
show
Compatibility
Best Practice
introduced
by
Use of
global functionality is not recommended; it makes your code harder to test, and less reusable.
Instead of relying on 1. Pass all data via parametersfunction myFunction($a, $b) {
// Do something
}
2. Create a class that maintains your stateclass MyClass {
private $a;
private $b;
public function __construct($a, $b) {
$this->a = $a;
$this->b = $b;
}
public function myFunction() {
// Do something
}
}
Loading history...
|
|||
246 | $oldLocale = i18n::get_locale(); |
||
247 | |||
248 | i18n::set_locale('en_US'); |
||
249 | |||
250 | i18n::get_translator('core')->getAdapter()->addTranslation(array( |
||
251 | 'i18nTestModule.NEWMETHODSIG' => 'TRANS New _t method signature test', |
||
252 | 'i18nTestModule.INJECTIONS' => 'TRANS Hello {name} {greeting}. But it is late, {goodbye}', |
||
253 | 'i18nTestModule.INJECTIONSLEGACY' => 'TRANS Hello %s %s. But it is late, %s', |
||
254 | ), 'en_US'); |
||
255 | |||
256 | $entity = "i18nTestModule.INJECTIONS"; |
||
257 | $default = "Hello {name} {greeting}. But it is late, {goodbye}"; |
||
258 | |||
259 | $translated = i18n::_t('i18nTestModule.NEWMETHODSIG',"New _t method signature test"); |
||
260 | $this->assertContains( |
||
261 | "TRANS New _t method signature test", |
||
262 | $translated |
||
263 | ); |
||
264 | |||
265 | $translated = i18n::_t($entity.'_DOES_NOT_EXIST', $default, |
||
266 | array("name"=>"Mark", "greeting"=>"welcome", "goodbye"=>"bye")); |
||
267 | $this->assertContains( |
||
268 | "Hello Mark welcome. But it is late, bye", |
||
269 | $translated, "Testing fallback to the translation default (but using the injection array)" |
||
270 | ); |
||
271 | |||
272 | $translated = i18n::_t($entity, $default, |
||
273 | array("name"=>"Paul", "greeting"=>"good you are here", "goodbye"=>"see you")); |
||
274 | $this->assertContains( |
||
275 | "TRANS Hello Paul good you are here. But it is late, see you", |
||
276 | $translated, "Testing entity, default string and injection array" |
||
277 | ); |
||
278 | |||
279 | $translated = i18n::_t($entity, $default, "New context (this should be ignored)", |
||
280 | array("name"=>"Steffen", "greeting"=>"willkommen", "goodbye"=>"wiedersehen")); |
||
281 | $this->assertContains( |
||
282 | "TRANS Hello Steffen willkommen. But it is late, wiedersehen", |
||
283 | $translated, "Full test of translation, using default, context and injection array" |
||
284 | ); |
||
285 | |||
286 | $translated = i18n::_t($entity, array("name"=>"Cat", "greeting"=>"meow", "goodbye"=>"meow")); |
||
287 | $this->assertContains( |
||
288 | "TRANS Hello Cat meow. But it is late, meow", |
||
289 | $translated, "Testing a translation with just entity and injection array" |
||
290 | ); |
||
291 | |||
292 | $translated = i18n::_t( |
||
293 | 'i18nTestModule.INJECTIONSLEGACY', // has %s placeholders |
||
294 | array("name"=>"Cat", "greeting2"=>"meow", "goodbye"=>"meow") |
||
295 | ); |
||
296 | $this->assertContains( |
||
297 | "TRANS Hello Cat meow. But it is late, meow", |
||
298 | $translated, "Testing sprintf placeholders with named injections" |
||
299 | ); |
||
300 | |||
301 | $translated = i18n::_t( |
||
302 | 'i18nTestModule.INJECTIONSLEGACY', // has %s placeholders |
||
303 | array("Cat", "meow"/*, "meow" */) // remove third arg |
||
304 | ); |
||
305 | $this->assertContains( |
||
306 | "TRANS Hello Cat meow. But it is late, ", |
||
307 | $translated, "Testing sprintf placeholders with unnamed injections and too few args" |
||
308 | ); |
||
309 | |||
310 | $translated = i18n::_t( |
||
311 | 'i18nTestModule.INJECTIONS', // has {name} placeholders |
||
312 | array("Cat", "meow", "meow") |
||
313 | ); |
||
314 | $this->assertContains( |
||
315 | "TRANS Hello Cat meow. But it is late, meow", |
||
316 | $translated, "Testing named injection placeholders with unnamed injections" |
||
317 | ); |
||
318 | |||
319 | i18n::set_locale($oldLocale); |
||
320 | } |
||
321 | |||
322 | /** |
||
323 | * See @i18nTestModule.ss for the template that is being used for this test |
||
324 | * */ |
||
325 | public function testNewTemplateTranslation() { |
||
326 | global $lang; |
||
0 ignored issues
–
show
Compatibility
Best Practice
introduced
by
Use of
global functionality is not recommended; it makes your code harder to test, and less reusable.
Instead of relying on 1. Pass all data via parametersfunction myFunction($a, $b) {
// Do something
}
2. Create a class that maintains your stateclass MyClass {
private $a;
private $b;
public function __construct($a, $b) {
$this->a = $a;
$this->b = $b;
}
public function myFunction() {
// Do something
}
}
Loading history...
|
|||
327 | $oldLocale = i18n::get_locale(); |
||
328 | |||
329 | i18n::set_locale('en_US'); |
||
330 | i18n::get_translator('core')->getAdapter()->addTranslation(array( |
||
331 | 'i18nTestModule.NEWMETHODSIG' => 'TRANS New _t method signature test', |
||
332 | 'i18nTestModule.INJECTIONS' => 'TRANS Hello {name} {greeting}. But it is late, {goodbye}' |
||
333 | ),'en_US'); |
||
334 | |||
335 | $viewer = new SSViewer('i18nTestModule'); |
||
336 | $parsedHtml = Convert::nl2os($viewer->process(new ArrayData(array('TestProperty' => 'TestPropertyValue')))); |
||
337 | $this->assertContains( |
||
338 | Convert::nl2os("Hello Mark welcome. But it is late, bye\n"), |
||
339 | $parsedHtml, "Testing fallback to the translation default (but using the injection array)" |
||
340 | ); |
||
341 | |||
342 | $this->assertContains( |
||
343 | Convert::nl2os("TRANS Hello Paul good you are here. But it is late, see you\n"), |
||
344 | $parsedHtml, "Testing entity, default string and injection array" |
||
345 | ); |
||
346 | |||
347 | $this->assertContains( |
||
348 | Convert::nl2os("TRANS Hello Cat meow. But it is late, meow\n"), |
||
349 | $parsedHtml, "Testing a translation with just entity and injection array" |
||
350 | ); |
||
351 | |||
352 | //test injected calls |
||
353 | $this->assertContains( |
||
354 | Convert::nl2os( |
||
355 | "TRANS Hello ".Director::absoluteBaseURL()." ".i18n::get_locale().". But it is late, global calls\n" |
||
356 | ), |
||
357 | $parsedHtml, |
||
358 | "Testing a translation with just entity and injection array, but with global variables injected in" |
||
359 | ); |
||
360 | |||
361 | i18n::set_locale($oldLocale); |
||
362 | } |
||
363 | |||
364 | public function testGetLocaleFromLang() { |
||
365 | $this->assertEquals('en_US', i18n::get_locale_from_lang('en')); |
||
366 | $this->assertEquals('de_DE', i18n::get_locale_from_lang('de_DE')); |
||
367 | $this->assertEquals('xy_XY', i18n::get_locale_from_lang('xy')); |
||
368 | } |
||
369 | |||
370 | public function testValidateLocale() { |
||
371 | $this->assertTrue(i18n::validate_locale('en_US'), 'Known locale in underscore format is valid'); |
||
372 | $this->assertTrue(i18n::validate_locale('en-US'), 'Known locale in dash format is valid'); |
||
373 | $this->assertFalse(i18n::validate_locale('en'), 'Short lang format is not valid'); |
||
374 | $this->assertFalse(i18n::validate_locale('xx_XX'), 'Unknown locale in correct format is not valid'); |
||
375 | $this->assertFalse(i18n::validate_locale(''), 'Empty string is not valid'); |
||
376 | } |
||
377 | |||
378 | public function testTranslate() { |
||
379 | $oldLocale = i18n::get_locale(); |
||
380 | |||
381 | i18n::get_translator('core')->getAdapter()->addTranslation(array( |
||
382 | 'i18nTestModule.ENTITY' => 'Entity with "Double Quotes"', |
||
383 | ), 'en_US'); |
||
384 | i18n::get_translator('core')->getAdapter()->addTranslation(array( |
||
385 | 'i18nTestModule.ENTITY' => 'Entity with "Double Quotes" (de)', |
||
386 | 'i18nTestModule.ADDITION' => 'Addition (de)', |
||
387 | ), 'de'); |
||
388 | i18n::get_translator('core')->getAdapter()->addTranslation(array( |
||
389 | 'i18nTestModule.ENTITY' => 'Entity with "Double Quotes" (de_AT)', |
||
390 | ), 'de_AT'); |
||
391 | |||
392 | |||
393 | $this->assertEquals(i18n::_t('i18nTestModule.ENTITY'), 'Entity with "Double Quotes"', |
||
394 | 'Returns translation in default language' |
||
395 | ); |
||
396 | |||
397 | i18n::set_locale('de'); |
||
398 | $this->assertEquals(i18n::_t('i18nTestModule.ENTITY'), 'Entity with "Double Quotes" (de)', |
||
399 | 'Returns translation according to current locale' |
||
400 | ); |
||
401 | |||
402 | i18n::set_locale('de_AT'); |
||
403 | $this->assertEquals(i18n::_t('i18nTestModule.ENTITY'), 'Entity with "Double Quotes" (de_AT)', |
||
404 | 'Returns specific regional translation if available' |
||
405 | ); |
||
406 | $this->assertEquals(i18n::_t('i18nTestModule.ADDITION'), 'Addition (de)', |
||
407 | 'Returns fallback non-regional translation if regional is not available' |
||
408 | ); |
||
409 | |||
410 | i18n::set_locale('fr'); |
||
411 | $this->assertEquals(i18n::_t('i18nTestModule.ENTITY'), '', |
||
412 | 'Returns empty translation without default string if locale is not found' |
||
413 | ); |
||
414 | $this->assertEquals(i18n::_t('i18nTestModule.ENTITY', 'default'), 'default', |
||
415 | 'Returns default string if locale is not found' |
||
416 | ); |
||
417 | |||
418 | i18n::set_locale($oldLocale); |
||
419 | } |
||
420 | |||
421 | public function testIncludeByLocale() { |
||
422 | // Looping through modules, so we can test the translation autoloading |
||
423 | // Load non-exclusive to retain core class autoloading |
||
424 | $classManifest = new SS_ClassManifest($this->alternateBasePath, true, true, false); |
||
425 | SS_ClassLoader::instance()->pushManifest($classManifest); |
||
426 | |||
427 | $adapter = i18n::get_translator('core')->getAdapter(); |
||
428 | $this->assertTrue($adapter->isAvailable('en')); |
||
429 | $this->assertFalse($adapter->isAvailable('de')); |
||
430 | $this->assertFalse($adapter->isTranslated('i18nTestModule.ENTITY', 'de'), |
||
431 | 'Existing unloaded entity not available before call' |
||
432 | ); |
||
433 | $this->assertFalse($adapter->isTranslated('i18nTestModule.ENTITY', 'af'), |
||
434 | 'Non-existing unloaded entity not available before call' |
||
435 | ); |
||
436 | |||
437 | // set _fakewebroot module priority |
||
438 | Config::inst()->update('i18n', 'module_priority', array('subfolder','i18ntestmodule')); |
||
439 | |||
440 | i18n::include_by_locale('de'); |
||
441 | |||
442 | $this->assertTrue($adapter->isAvailable('en')); |
||
443 | $this->assertTrue($adapter->isAvailable('de')); |
||
444 | $this->assertTrue($adapter->isTranslated('i18nTestModule.ENTITY', null, 'de'), 'Includes module files'); |
||
445 | $this->assertTrue($adapter->isTranslated('i18nTestTheme1.LAYOUTTEMPLATE', null, 'de'), 'Includes theme files'); |
||
446 | $this->assertTrue($adapter->isTranslated('i18nTestModule.OTHERENTITY', null, 'de'), 'Includes submodule files'); |
||
447 | |||
448 | // check module priority |
||
449 | $this->assertEquals($adapter->translate('i18nTestModule.PRIORITYNOTICE', 'de'), |
||
450 | 'High Module Priority (de)' |
||
451 | ); |
||
452 | |||
453 | SS_ClassLoader::instance()->popManifest(); |
||
454 | } |
||
455 | |||
456 | public function testIncludeByLocaleWithoutFallbackLanguage() { |
||
457 | $classManifest = new SS_ClassManifest($this->alternateBasePath, true, true, false); |
||
458 | SS_ClassLoader::instance()->pushManifest($classManifest); |
||
459 | |||
460 | $adapter = i18n::get_translator('core')->getAdapter(); |
||
461 | $this->assertTrue($adapter->isAvailable('en')); |
||
462 | $this->assertFalse($adapter->isAvailable('mi')); // not defined at all |
||
463 | $this->assertFalse($adapter->isAvailable('mi_NZ')); // defined, but not loaded yet |
||
464 | $this->assertFalse($adapter->isTranslated('i18nTestModule.ENTITY', 'mi'), |
||
465 | 'Existing unloaded entity not available before call' |
||
466 | ); |
||
467 | $this->assertFalse($adapter->isTranslated('i18nTestModule.ENTITY', 'mi_NZ'), |
||
468 | 'Non-existing unloaded entity not available before call' |
||
469 | ); |
||
470 | |||
471 | i18n::include_by_locale('mi_NZ'); |
||
472 | |||
473 | $this->assertFalse($adapter->isAvailable('mi')); |
||
474 | $this->assertTrue($adapter->isAvailable('mi_NZ')); |
||
475 | $this->assertTrue($adapter->isTranslated('i18nTestModule.ENTITY', null, 'mi_NZ'), 'Includes module files'); |
||
476 | |||
477 | SS_ClassLoader::instance()->popManifest(); |
||
478 | } |
||
479 | |||
480 | public function testRegisterTranslator() { |
||
481 | $translator = new Zend_Translate(array( |
||
482 | 'adapter' => 'i18nTest_CustomTranslatorAdapter', |
||
483 | 'disableNotices' => true, |
||
484 | )); |
||
485 | |||
486 | i18n::register_translator($translator, 'custom', 10); |
||
487 | $translators = i18n::get_translators(); |
||
488 | $this->assertArrayHasKey('custom', $translators[10]); |
||
489 | $this->assertInstanceOf('Zend_Translate', $translators[10]['custom']); |
||
490 | $this->assertInstanceOf('i18nTest_CustomTranslatorAdapter', $translators[10]['custom']->getAdapter()); |
||
491 | |||
492 | i18n::unregister_translator('custom'); |
||
493 | $translators = i18n::get_translators(); |
||
494 | $this->assertArrayNotHasKey('custom', $translators[10]); |
||
495 | } |
||
496 | |||
497 | public function testMultipleTranslators() { |
||
498 | // Looping through modules, so we can test the translation autoloading |
||
499 | // Load non-exclusive to retain core class autoloading |
||
500 | $classManifest = new SS_ClassManifest($this->alternateBasePath, true, true, false); |
||
501 | SS_ClassLoader::instance()->pushManifest($classManifest); |
||
502 | |||
503 | // Changed manifest, so we also need to unset all previously collected messages. |
||
504 | // The easiest way to do this it to register a new adapter. |
||
505 | $adapter = new Zend_Translate(array( |
||
506 | 'adapter' => 'i18nRailsYamlAdapter', |
||
507 | 'locale' => i18n::default_locale(), |
||
0 ignored issues
–
show
The method
i18n::default_locale() has been deprecated with message: since version 4.0; Use the "i18n.default_locale" config setting instead
This method has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.
Loading history...
|
|||
508 | 'disableNotices' => true, |
||
509 | )); |
||
510 | i18n::register_translator($adapter, 'core'); |
||
511 | |||
512 | i18n::set_locale('en_US'); |
||
513 | |||
514 | $this->assertEquals( |
||
515 | i18n::_t('i18nTestModule.ENTITY'), |
||
516 | 'Entity with "Double Quotes"' |
||
517 | ); |
||
518 | $this->assertEquals( |
||
519 | i18n::_t('AdapterEntity1', 'AdapterEntity1'), |
||
520 | 'AdapterEntity1', |
||
521 | 'Falls back to default string if not found' |
||
522 | ); |
||
523 | |||
524 | // Add a new translator |
||
525 | $translator = new Zend_Translate(array( |
||
526 | 'adapter' => 'i18nTest_CustomTranslatorAdapter', |
||
527 | 'disableNotices' => true, |
||
528 | )); |
||
529 | i18n::register_translator($translator, 'custom', 11); |
||
530 | $this->assertEquals( |
||
531 | i18n::_t('i18nTestModule.ENTITY'), |
||
532 | 'i18nTestModule.ENTITY CustomAdapter (en_US)', |
||
533 | 'Existing entities overruled by adapter with higher priority' |
||
534 | ); |
||
535 | $this->assertEquals( |
||
536 | i18n::_t('AdapterEntity1', 'AdapterEntity1'), |
||
537 | 'AdapterEntity1 CustomAdapter (en_US)', |
||
538 | 'New entities only defined in new adapter are detected' |
||
539 | ); |
||
540 | |||
541 | // Add a second new translator to test priorities |
||
542 | $translator = new Zend_Translate(array( |
||
543 | 'adapter' => 'i18nTest_OtherCustomTranslatorAdapter', |
||
544 | 'disableNotices' => true, |
||
545 | )); |
||
546 | i18n::register_translator($translator, 'othercustom_lower_prio', 5); |
||
547 | $this->assertEquals( |
||
548 | i18n::_t('i18nTestModule.ENTITY'), |
||
549 | 'i18nTestModule.ENTITY CustomAdapter (en_US)', |
||
550 | 'Adapter with lower priority loses' |
||
551 | ); |
||
552 | |||
553 | // Add a third new translator to test priorities |
||
554 | $translator = new Zend_Translate(array( |
||
555 | 'adapter' => 'i18nTest_OtherCustomTranslatorAdapter', |
||
556 | 'disableNotices' => true, |
||
557 | )); |
||
558 | |||
559 | i18n::register_translator($translator, 'othercustom_higher_prio', 15); |
||
560 | |||
561 | $this->assertEquals( |
||
562 | i18n::_t('i18nTestModule.ENTITY'), |
||
563 | 'i18nTestModule.ENTITY OtherCustomAdapter (en_US)', |
||
564 | 'Adapter with higher priority wins' |
||
565 | ); |
||
566 | |||
567 | i18n::unregister_translator('custom'); |
||
568 | i18n::unregister_translator('othercustom_lower_prio'); |
||
569 | i18n::unregister_translator('othercustom_higher_prio'); |
||
570 | |||
571 | SS_ClassLoader::instance()->popManifest(); |
||
572 | } |
||
573 | |||
574 | public function testGetLanguageName() { |
||
575 | Config::inst()->update( |
||
576 | 'i18n', |
||
577 | 'common_languages', |
||
578 | array('de_CGN' => array('name' => 'German (Cologne)', 'native' => 'Kölsch')) |
||
579 | ); |
||
580 | $this->assertEquals('German (Cologne)', i18n::get_language_name('de_CGN')); |
||
581 | $this->assertEquals('Kölsch', i18n::get_language_name('de_CGN', true)); |
||
582 | } |
||
583 | } |
||
584 | |||
585 | class i18nTest_DataObject extends DataObject implements TestOnly { |
||
586 | |||
587 | private static $db = array( |
||
588 | 'MyProperty' => 'Varchar', |
||
589 | 'MyUntranslatedProperty' => 'Text' |
||
590 | ); |
||
591 | |||
592 | private static $has_one = array( |
||
593 | 'HasOneRelation' => 'SilverStripe\\Security\\Member' |
||
594 | ); |
||
595 | |||
596 | private static $has_many = array( |
||
597 | 'HasManyRelation' => 'SilverStripe\\Security\\Member' |
||
598 | ); |
||
599 | |||
600 | private static $many_many = array( |
||
601 | 'ManyManyRelation' => 'SilverStripe\\Security\\Member' |
||
602 | ); |
||
603 | |||
604 | /** |
||
605 | * |
||
606 | * @param boolean $includerelations a boolean value to indicate if the labels returned include relation fields |
||
607 | * |
||
608 | */ |
||
609 | public function fieldLabels($includerelations = true) { |
||
610 | $labels = parent::fieldLabels($includerelations); |
||
611 | $labels['MyProperty'] = _t('i18nTest_DataObject.MyProperty', 'My Property'); |
||
612 | |||
613 | return $labels; |
||
614 | } |
||
615 | |||
616 | } |
||
617 | |||
618 | class i18nTest_Object extends Object implements TestOnly, i18nEntityProvider { |
||
619 | static $my_translatable_property = "Untranslated"; |
||
620 | |||
621 | public static function my_translatable_property() { |
||
622 | return _t("i18nTest_Object.my_translatable_property", self::$my_translatable_property); |
||
623 | } |
||
624 | |||
625 | public function provideI18nEntities() { |
||
626 | return array( |
||
627 | "i18nTest_Object.my_translatable_property" => array( |
||
628 | self::$my_translatable_property |
||
629 | ) |
||
630 | ); |
||
631 | } |
||
632 | } |
||
633 | |||
634 | class i18nTest_CustomTranslatorAdapter extends Zend_Translate_Adapter |
||
635 | implements TestOnly,i18nTranslateAdapterInterface { |
||
0 ignored issues
–
show
|
|||
636 | protected function _loadTranslationData($filename, $locale, array $options = array()) { |
||
637 | return array( |
||
638 | $locale => array( |
||
639 | 'AdapterEntity1' => 'AdapterEntity1 CustomAdapter (' . $locale . ')', |
||
640 | 'i18nTestModule.ENTITY' => 'i18nTestModule.ENTITY CustomAdapter (' . $locale . ')', |
||
641 | ) |
||
642 | ); |
||
643 | } |
||
644 | |||
645 | public function toString() { |
||
646 | return 'i18nTest_CustomTranslatorAdapter'; |
||
647 | } |
||
648 | |||
649 | public function getFilenameForLocale($locale) { |
||
650 | return false; // not file based |
||
651 | } |
||
652 | } |
||
653 | |||
654 | class i18nTest_OtherCustomTranslatorAdapter extends Zend_Translate_Adapter |
||
655 | implements TestOnly,i18nTranslateAdapterInterface { |
||
0 ignored issues
–
show
|
|||
656 | protected function _loadTranslationData($filename, $locale, array $options = array()) { |
||
657 | return array( |
||
658 | $locale => array( |
||
659 | 'i18nTestModule.ENTITY' => 'i18nTestModule.ENTITY OtherCustomAdapter (' . $locale . ')', |
||
660 | ) |
||
661 | ); |
||
662 | } |
||
663 | |||
664 | public function toString() { |
||
665 | return 'i18nTest_OtherCustomTranslatorAdapter'; |
||
666 | } |
||
667 | |||
668 | public function getFilenameForLocale($locale) { |
||
669 | return false; // not file based |
||
670 | } |
||
671 | } |
||
672 |
This method has been deprecated. The supplier of the class has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.