loadTextdomainJustInTime.php 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. <?php
  2. /**
  3. * @group l10n
  4. * @group i18n
  5. */
  6. class Tests_L10n_LoadTextdomainJustInTime extends WP_UnitTestCase {
  7. protected $orig_theme_dir;
  8. protected $theme_root;
  9. protected static $user_id;
  10. private $locale_count;
  11. public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ) {
  12. self::$user_id = $factory->user->create(
  13. array(
  14. 'role' => 'administrator',
  15. 'locale' => 'de_DE',
  16. )
  17. );
  18. }
  19. public function setUp() {
  20. parent::setUp();
  21. $this->theme_root = DIR_TESTDATA . '/themedir1';
  22. $this->orig_theme_dir = $GLOBALS['wp_theme_directories'];
  23. $this->locale_count = 0;
  24. // /themes is necessary as theme.php functions assume /themes is the root if there is only one root.
  25. $GLOBALS['wp_theme_directories'] = array( WP_CONTENT_DIR . '/themes', $this->theme_root );
  26. add_filter( 'theme_root', array( $this, 'filter_theme_root' ) );
  27. add_filter( 'stylesheet_root', array( $this, 'filter_theme_root' ) );
  28. add_filter( 'template_root', array( $this, 'filter_theme_root' ) );
  29. wp_clean_themes_cache();
  30. unset( $GLOBALS['wp_themes'] );
  31. unset( $GLOBALS['l10n'] );
  32. unset( $GLOBALS['l10n_unloaded'] );
  33. _get_path_to_translation( null, true );
  34. }
  35. public function tearDown() {
  36. $GLOBALS['wp_theme_directories'] = $this->orig_theme_dir;
  37. wp_clean_themes_cache();
  38. unset( $GLOBALS['wp_themes'] );
  39. unset( $GLOBALS['l10n'] );
  40. unset( $GLOBALS['l10n_unloaded'] );
  41. _get_path_to_translation( null, true );
  42. parent::tearDown();
  43. }
  44. /**
  45. * Replace the normal theme root dir with our pre-made test dir.
  46. */
  47. public function filter_theme_root() {
  48. return $this->theme_root;
  49. }
  50. public function filter_set_locale_to_german() {
  51. return 'de_DE';
  52. }
  53. /**
  54. * @ticket 34114
  55. */
  56. public function test_plugin_translation_should_be_translated_without_calling_load_plugin_textdomain() {
  57. add_filter( 'locale', array( $this, 'filter_set_locale_to_german' ) );
  58. require_once DIR_TESTDATA . '/plugins/internationalized-plugin.php';
  59. $is_textdomain_loaded_before = is_textdomain_loaded( 'internationalized-plugin' );
  60. $expected_output = i18n_plugin_test();
  61. $is_textdomain_loaded_after = is_textdomain_loaded( 'internationalized-plugin' );
  62. remove_filter( 'locale', array( $this, 'filter_set_locale_to_german' ) );
  63. $this->assertFalse( $is_textdomain_loaded_before );
  64. $this->assertSame( 'Das ist ein Dummy Plugin', $expected_output );
  65. $this->assertTrue( $is_textdomain_loaded_after );
  66. }
  67. /**
  68. * @ticket 34114
  69. */
  70. public function test_theme_translation_should_be_translated_without_calling_load_theme_textdomain() {
  71. add_filter( 'locale', array( $this, 'filter_set_locale_to_german' ) );
  72. switch_theme( 'internationalized-theme' );
  73. require_once get_stylesheet_directory() . '/functions.php';
  74. $is_textdomain_loaded_before = is_textdomain_loaded( 'internationalized-theme' );
  75. $expected_output = i18n_theme_test();
  76. $is_textdomain_loaded_after = is_textdomain_loaded( 'internationalized-theme' );
  77. remove_filter( 'locale', array( $this, 'filter_set_locale_to_german' ) );
  78. $this->assertFalse( $is_textdomain_loaded_before );
  79. $this->assertSame( 'Das ist ein Dummy Theme', $expected_output );
  80. $this->assertTrue( $is_textdomain_loaded_after );
  81. }
  82. /**
  83. * @ticket 34114
  84. */
  85. public function test_get_translations_for_domain_does_not_return_null_if_override_load_textdomain_is_used() {
  86. add_filter( 'locale', array( $this, 'filter_set_locale_to_german' ) );
  87. add_filter( 'override_load_textdomain', '__return_true' );
  88. $translations = get_translations_for_domain( 'internationalized-plugin' );
  89. remove_filter( 'override_load_textdomain', '__return_true' );
  90. remove_filter( 'locale', array( $this, 'filter_set_locale_to_german' ) );
  91. $this->assertTrue( $translations instanceof NOOP_Translations );
  92. }
  93. /**
  94. * @ticket 37113
  95. */
  96. public function test_should_allow_unloading_of_text_domain() {
  97. add_filter( 'locale', array( $this, 'filter_set_locale_to_german' ) );
  98. require_once DIR_TESTDATA . '/plugins/internationalized-plugin.php';
  99. $expected_output_before = i18n_plugin_test();
  100. $is_textdomain_loaded_before = is_textdomain_loaded( 'internationalized-plugin' );
  101. unload_textdomain( 'internationalized-plugin' );
  102. remove_filter( 'locale', array( $this, 'filter_set_locale_to_german' ) );
  103. $expected_output_after = i18n_plugin_test();
  104. $is_textdomain_loaded_after = is_textdomain_loaded( 'internationalized-plugin' );
  105. add_filter( 'locale', array( $this, 'filter_set_locale_to_german' ) );
  106. load_textdomain( 'internationalized-plugin', WP_LANG_DIR . '/plugins/internationalized-plugin-de_DE.mo' );
  107. $expected_output_final = i18n_plugin_test();
  108. $is_textdomain_loaded_final = is_textdomain_loaded( 'internationalized-plugin' );
  109. unload_textdomain( 'internationalized-plugin' );
  110. remove_filter( 'locale', array( $this, 'filter_set_locale_to_german' ) );
  111. // Text domain loaded just in time.
  112. $this->assertSame( 'Das ist ein Dummy Plugin', $expected_output_before );
  113. $this->assertTrue( $is_textdomain_loaded_before );
  114. // Text domain unloaded.
  115. $this->assertSame( 'This is a dummy plugin', $expected_output_after );
  116. $this->assertFalse( $is_textdomain_loaded_after );
  117. // Text domain loaded manually again.
  118. $this->assertSame( 'Das ist ein Dummy Plugin', $expected_output_final );
  119. $this->assertTrue( $is_textdomain_loaded_final );
  120. }
  121. /**
  122. * @ticket 26511
  123. */
  124. public function test_plugin_translation_after_switching_locale() {
  125. require_once DIR_TESTDATA . '/plugins/internationalized-plugin.php';
  126. switch_to_locale( 'de_DE' );
  127. $expected = i18n_plugin_test();
  128. restore_previous_locale();
  129. $this->assertSame( 'Das ist ein Dummy Plugin', $expected );
  130. }
  131. /**
  132. * @ticket 37997
  133. */
  134. public function test_plugin_translation_after_switching_locale_twice() {
  135. require_once DIR_TESTDATA . '/plugins/internationalized-plugin.php';
  136. switch_to_locale( 'de_DE' );
  137. $expected_de_de = i18n_plugin_test();
  138. switch_to_locale( 'es_ES' );
  139. $expected_es_es = i18n_plugin_test();
  140. restore_current_locale();
  141. $this->assertSame( 'Das ist ein Dummy Plugin', $expected_de_de );
  142. $this->assertSame( 'This is a dummy plugin', $expected_es_es );
  143. }
  144. /**
  145. * @ticket 26511
  146. */
  147. public function test_theme_translation_after_switching_locale() {
  148. switch_theme( 'internationalized-theme' );
  149. require_once get_stylesheet_directory() . '/functions.php';
  150. switch_to_locale( 'de_DE' );
  151. $expected = i18n_theme_test();
  152. restore_previous_locale();
  153. switch_theme( WP_DEFAULT_THEME );
  154. $this->assertSame( 'Das ist ein Dummy Theme', $expected );
  155. }
  156. /**
  157. * @ticket 38485
  158. */
  159. public function test_plugin_translation_with_user_locale() {
  160. require_once DIR_TESTDATA . '/plugins/internationalized-plugin.php';
  161. set_current_screen( 'dashboard' );
  162. wp_set_current_user( self::$user_id );
  163. $expected = i18n_plugin_test();
  164. set_current_screen( 'front' );
  165. $this->assertSame( 'Das ist ein Dummy Plugin', $expected );
  166. }
  167. /**
  168. * @ticket 38485
  169. */
  170. public function test_theme_translation_with_user_locale() {
  171. switch_theme( 'internationalized-theme' );
  172. set_current_screen( 'dashboard' );
  173. wp_set_current_user( self::$user_id );
  174. require_once get_stylesheet_directory() . '/functions.php';
  175. $expected = i18n_theme_test();
  176. set_current_screen( 'front' );
  177. switch_theme( WP_DEFAULT_THEME );
  178. $this->assertSame( 'Das ist ein Dummy Theme', $expected );
  179. }
  180. /**
  181. * @ticket 37997
  182. */
  183. public function test_get_locale_is_called_only_once_per_textdomain() {
  184. $textdomain = 'foo-bar-baz';
  185. add_filter( 'locale', array( $this, '_filter_locale_count' ) );
  186. __( 'Foo', $textdomain );
  187. __( 'Bar', $textdomain );
  188. __( 'Baz', $textdomain );
  189. __( 'Foo Bar', $textdomain );
  190. __( 'Foo Bar Baz', $textdomain );
  191. remove_filter( 'locale', array( $this, '_filter_locale_count' ) );
  192. $this->assertFalse( is_textdomain_loaded( $textdomain ) );
  193. $this->assertSame( 1, $this->locale_count );
  194. }
  195. public function _filter_locale_count( $locale ) {
  196. ++$this->locale_count;
  197. return $locale;
  198. }
  199. }