class-wp-textdomain-registry.php 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. <?php
  2. /**
  3. * Locale API: WP_Textdomain_Registry class
  4. *
  5. * @package WordPress
  6. * @subpackage i18n
  7. * @since 6.1.0
  8. */
  9. /**
  10. * Core class used for registering text domains.
  11. *
  12. * @since 6.1.0
  13. */
  14. #[AllowDynamicProperties]
  15. class WP_Textdomain_Registry {
  16. /**
  17. * List of domains and all their language directory paths for each locale.
  18. *
  19. * @since 6.1.0
  20. *
  21. * @var array
  22. */
  23. protected $all = array();
  24. /**
  25. * List of domains and their language directory path for the current (most recent) locale.
  26. *
  27. * @since 6.1.0
  28. *
  29. * @var array
  30. */
  31. protected $current = array();
  32. /**
  33. * List of domains and their custom language directory paths.
  34. *
  35. * @see load_plugin_textdomain()
  36. * @see load_theme_textdomain()
  37. *
  38. * @since 6.1.0
  39. *
  40. * @var array
  41. */
  42. protected $custom_paths = array();
  43. /**
  44. * Holds a cached list of available .mo files to improve performance.
  45. *
  46. * @since 6.1.0
  47. *
  48. * @var array
  49. */
  50. protected $cached_mo_files;
  51. /**
  52. * Returns the languages directory path for a specific domain and locale.
  53. *
  54. * @since 6.1.0
  55. *
  56. * @param string $domain Text domain.
  57. * @param string $locale Locale.
  58. *
  59. * @return string|false MO file path or false if there is none available.
  60. */
  61. public function get( $domain, $locale ) {
  62. if ( isset( $this->all[ $domain ][ $locale ] ) ) {
  63. return $this->all[ $domain ][ $locale ];
  64. }
  65. return $this->get_path_from_lang_dir( $domain, $locale );
  66. }
  67. /**
  68. * Determines whether any MO file paths are available for the domain.
  69. *
  70. * This is the case if a path has been set for the current locale,
  71. * or if there is no information stored yet, in which case
  72. * {@see _load_textdomain_just_in_time()} will fetch the information first.
  73. *
  74. * @since 6.1.0
  75. *
  76. * @param string $domain Text domain.
  77. * @return bool Whether any MO file paths are available for the domain.
  78. */
  79. public function has( $domain ) {
  80. return ! empty( $this->current[ $domain ] ) || empty( $this->all[ $domain ] );
  81. }
  82. /**
  83. * Sets the language directory path for a specific domain and locale.
  84. *
  85. * Also sets the 'current' property for direct access
  86. * to the path for the current (most recent) locale.
  87. *
  88. * @since 6.1.0
  89. *
  90. * @param string $domain Text domain.
  91. * @param string $locale Locale.
  92. * @param string|false $path Language directory path or false if there is none available.
  93. */
  94. public function set( $domain, $locale, $path ) {
  95. $this->all[ $domain ][ $locale ] = $path ? trailingslashit( $path ) : false;
  96. $this->current[ $domain ] = $this->all[ $domain ][ $locale ];
  97. }
  98. /**
  99. * Sets the custom path to the plugin's/theme's languages directory.
  100. *
  101. * Used by {@see load_plugin_textdomain()} and {@see load_theme_textdomain()}.
  102. *
  103. * @param string $domain Text domain.
  104. * @param string $path Language directory path.
  105. */
  106. public function set_custom_path( $domain, $path ) {
  107. $this->custom_paths[ $domain ] = untrailingslashit( $path );
  108. }
  109. /**
  110. * Gets the path to the language directory for the current locale.
  111. *
  112. * Checks the plugins and themes language directories as well as any
  113. * custom directory set via {@see load_plugin_textdomain()} or {@see load_theme_textdomain()}.
  114. *
  115. * @since 6.1.0
  116. *
  117. * @see _get_path_to_translation_from_lang_dir()
  118. *
  119. * @param string $domain Text domain.
  120. * @param string $locale Locale.
  121. * @return string|false Language directory path or false if there is none available.
  122. */
  123. private function get_path_from_lang_dir( $domain, $locale ) {
  124. $locations = array(
  125. WP_LANG_DIR . '/plugins',
  126. WP_LANG_DIR . '/themes',
  127. );
  128. if ( isset( $this->custom_paths[ $domain ] ) ) {
  129. $locations[] = $this->custom_paths[ $domain ];
  130. }
  131. $mofile = "$domain-$locale.mo";
  132. foreach ( $locations as $location ) {
  133. if ( ! isset( $this->cached_mo_files[ $location ] ) ) {
  134. $this->set_cached_mo_files( $location );
  135. }
  136. $path = $location . '/' . $mofile;
  137. if ( in_array( $path, $this->cached_mo_files[ $location ], true ) ) {
  138. $this->set( $domain, $locale, $location );
  139. return trailingslashit( $location );
  140. }
  141. }
  142. // If no path is found for the given locale and a custom path has been set
  143. // using load_plugin_textdomain/load_theme_textdomain, use that one.
  144. if ( 'en_US' !== $locale && isset( $this->custom_paths[ $domain ] ) ) {
  145. $path = trailingslashit( $this->custom_paths[ $domain ] );
  146. $this->set( $domain, $locale, $path );
  147. return $path;
  148. }
  149. $this->set( $domain, $locale, false );
  150. return false;
  151. }
  152. /**
  153. * Reads and caches all available MO files from a given directory.
  154. *
  155. * @since 6.1.0
  156. *
  157. * @param string $path Language directory path.
  158. */
  159. private function set_cached_mo_files( $path ) {
  160. $this->cached_mo_files[ $path ] = array();
  161. $mo_files = glob( $path . '/*.mo' );
  162. if ( $mo_files ) {
  163. $this->cached_mo_files[ $path ] = $mo_files;
  164. }
  165. }
  166. }