I18n.php 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. <?php
  2. /**
  3. * Internationalization (i18n) class. Provides language loading and translation
  4. * methods without dependencies on [gettext](http://php.net/gettext).
  5. * Typically this class would never be used directly, but used via the __()
  6. * function, which loads the message and replaces parameters:
  7. *
  8. * // Display a translated message in APPATH
  9. * echo __('Hello, world');
  10. *
  11. * // Display a translated message in SYSPATH and MODPATH
  12. * echo I18n::get('Hello, world');
  13. *
  14. * // With parameter replacement in APPATH
  15. * echo __('Hello, :user', [':user' => $username]);
  16. *
  17. * // With parameter replacement in SYSPATH nad MODPATH
  18. * echo I18n::get(['Hello, :user', [':user' => $username]]);
  19. *
  20. * @package KO7
  21. * @category Base
  22. *
  23. * @copyright (c) 2008 - 2016 Kohana Team
  24. * @copyright (c) since 2018 Koseven Team
  25. * @license https://koseven.dev/LICENSE
  26. */
  27. class KO7_I18n {
  28. /**
  29. * Target language: en-us, es-es, zh-cn, etc
  30. * @var string
  31. */
  32. public static $lang = 'en-us';
  33. /**
  34. * Source language: en-us, es-es, zh-cb, etc
  35. * @var string
  36. */
  37. public static $source = 'en-us';
  38. /**
  39. * Cache of loaded languages
  40. * @var array
  41. */
  42. protected static $_cache = [];
  43. /**
  44. * Get and set the target language.
  45. *
  46. * // Get the current language
  47. * $lang = I18n::lang();
  48. *
  49. * // Change the current language to Spanish
  50. * I18n::lang('es-es');
  51. *
  52. * @param string $lang New target language
  53. *
  54. * @return string
  55. * @since 3.0.2
  56. */
  57. public static function lang(string $lang = NULL) : string
  58. {
  59. if ($lang && $lang !== I18n::$lang)
  60. {
  61. I18n::$lang = strtolower(str_replace([' ', '_'], '-', $lang));
  62. }
  63. return I18n::$lang;
  64. }
  65. /**
  66. * Returns translation of a string. If no translation exists, the original
  67. * string will be returned. No parameters are replaced.
  68. *
  69. * $hello = I18n::get('Hello friends, my name is :name');
  70. *
  71. * @param string|array $string Text to translate or array [text, values]
  72. * @param string $lang Target Language
  73. * @param string $source Source Language
  74. * @return string
  75. */
  76. public static function get($string, string $lang = NULL, string $source = NULL)
  77. {
  78. $values = [];
  79. // Check if $string is array [text, values]
  80. if (Arr::is_array($string))
  81. {
  82. if (isset($string[1]) && Arr::is_array($string[1]))
  83. {
  84. $values = $string[1];
  85. }
  86. $string = $string[0];
  87. }
  88. // Set Target Language if not set
  89. if ( ! $lang)
  90. {
  91. // Use the global target language
  92. $lang = I18n::$lang;
  93. }
  94. // Set source Language if not set
  95. if ( ! $source)
  96. {
  97. // Use the global source language
  98. $source = I18n::$source;
  99. }
  100. // Load Table only if Source language does not match target language
  101. if ($source !== $lang)
  102. {
  103. // Load the translation table for this language
  104. $table = I18n::load($lang);
  105. // Return the translated string if it exists
  106. $string = $table[$string] ?? $string;
  107. }
  108. return empty($values) ? $string : strtr($string, $values);
  109. }
  110. /**
  111. * Returns the translation table for a given language.
  112. *
  113. * // Get all defined English messages.
  114. * // This will look for translation inside 'i18n/en/us.php'
  115. * // and overwrite the ones in 'i18n/en.php'
  116. * $messages = I18n::load('en-us');
  117. *
  118. * @param string $lang language to load
  119. * @return array
  120. */
  121. public static function load(string $lang) : array
  122. {
  123. if (isset(I18n::$_cache[$lang]))
  124. {
  125. return I18n::$_cache[$lang];
  126. }
  127. // New translation table
  128. $table = [[]];
  129. // Split the language: language, region, locale, etc
  130. $parts = explode('-', $lang);
  131. // Loop through Paths
  132. foreach ([$parts[0], implode(DIRECTORY_SEPARATOR, $parts)] as $path)
  133. {
  134. // Load files
  135. $files = KO7::find_file('i18n', $path);
  136. // Loop through files
  137. if ( ! empty($files))
  138. {
  139. $t = [[]];
  140. foreach ($files as $file)
  141. {
  142. // Merge the language strings into the sub table
  143. $t[] = KO7::load($file);
  144. }
  145. $table[] = $t;
  146. }
  147. }
  148. $table = array_merge(...array_merge(...$table));
  149. // Cache the translation table locally
  150. return I18n::$_cache[$lang] = $table;
  151. }
  152. }
  153. if ( ! function_exists('__'))
  154. {
  155. /**
  156. * KO7 translation/internationalization function. The PHP function
  157. * [strtr](http://php.net/strtr) is used for replacing parameters.
  158. *
  159. * __('Welcome back, :user', array(':user' => $username));
  160. *
  161. * [!!] The target language is defined by [I18n::$lang].
  162. *
  163. * @uses I18n::get
  164. *
  165. * @param string $string Text to translate
  166. * @param array $values Values to replace in the translated text
  167. * @param string $lang Source language
  168. *
  169. * @return string
  170. */
  171. function __(string $string, array $values = NULL, $lang = NULL)
  172. {
  173. return I18n::get($values ? [$string, $values] : $string, NULL, $lang);
  174. }
  175. }