text.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. <?php
  2. /**
  3. * Get the text for the correct translation
  4. *
  5. */
  6. class text {
  7. public $languages;
  8. public $legacy_map = array(
  9. 'he' => 'he-il',
  10. 'pl' => 'pl-pl',
  11. 'uk' => 'uk-ua',
  12. 'ro' => 'ro-ro',
  13. 'he-il' => 'he',
  14. 'pl-pl' => 'pl',
  15. 'uk-ua' => 'uk',
  16. 'ro-ro' => 'ro',
  17. //we use the following to indicate which is the preferred
  18. 'de' => 'de-de',
  19. 'es' => 'es-cl',
  20. 'fr' => 'fr-fr',
  21. 'pt' => 'pt-pt',
  22. );
  23. /**
  24. * Called when the object is created
  25. */
  26. public function __construct() {
  27. //define the text array
  28. $text = array();
  29. //get the global app_languages.php so we can get the list of languages
  30. if (file_exists($_SERVER["PROJECT_ROOT"]."/resources/app_languages.php")) {
  31. include $_SERVER["PROJECT_ROOT"]."/resources/app_languages.php";
  32. }
  33. //get the list of languages, remove en-us, sort it then put en-us in front
  34. unset($text['language-name']['en-us']);
  35. if (is_array($text['language-name'])) {
  36. $languages = array_keys($text['language-name']);
  37. asort($languages);
  38. array_unshift($languages, 'en-us');
  39. }
  40. //support legacy variable
  41. if (is_array($languages)) {
  42. $_SESSION['app']['languages'] = $languages;
  43. $this->languages = $languages;
  44. }
  45. }
  46. /**
  47. * Get a specific item from the cache
  48. * @var string $language_code examples: en-us, es-cl, fr-fr, pt-pt
  49. * @var string $app_path examples: app/exec or core/domains
  50. */
  51. public function get($language_code = null, $app_path = null, $exclude_global = false) {
  52. //define the text array
  53. $text = array();
  54. //get the global app_languages.php
  55. if (!$exclude_global && file_exists($_SERVER["PROJECT_ROOT"]."/resources/app_languages.php")) {
  56. require $_SERVER["PROJECT_ROOT"]."/resources/app_languages.php";
  57. }
  58. //get the app_languages.php
  59. if ($app_path != null) {
  60. $lang_path = $_SERVER["PROJECT_ROOT"]."/".$app_path;
  61. }
  62. else {
  63. $lang_path = getcwd();
  64. }
  65. if (file_exists($lang_path."/app_languages.php")) {
  66. if ($lang_path != 'resources' or $exclude_global) {
  67. include "{$lang_path}/app_languages.php";
  68. }
  69. }
  70. //else {
  71. // throw new Exception("could not find app_languages for '$app_path'");
  72. //}
  73. //check the session language
  74. if (isset($_SESSION['domain']) and $language_code == null) {
  75. $language_code = $_SESSION['domain']['language']['code'];
  76. }
  77. elseif ($language_code == null) {
  78. $language_code = 'en-us';
  79. }
  80. //check the language code
  81. if (strlen($language_code) == 2) {
  82. if (array_key_exists($language_code, $this->legacy_map)) {
  83. $language_code = $this->legacy_map[$language_code];
  84. }
  85. }
  86. //reduce to specific language
  87. if ($language_code != 'all') {
  88. if (is_array($text)) {
  89. foreach ($text as $key => $value) {
  90. if (isset($value[$language_code]) && !empty($value[$language_code])) {
  91. $text[$key] = $value[$language_code];
  92. }
  93. else {
  94. //fallback to en-us
  95. $text[$key] = $value['en-us'];
  96. }
  97. }
  98. }
  99. }
  100. //return the array of translations
  101. return $text;
  102. }
  103. /**
  104. * reorganize an app_languages.php into a consistent format
  105. * @var string $app_path examples: app/exec or core/domains
  106. * @var string $no_sort don't sort the text label order
  107. */
  108. public function organize_language($app_path = null, $no_sort = false) {
  109. //clear $text ready for the import
  110. $text = array();
  111. //get the app_languages.php
  112. if ($app_path == null) {
  113. throw new Exception("\$app_path must be specified");
  114. }
  115. $lang_path = $_SERVER["PROJECT_ROOT"]."/$app_path/app_languages.php";
  116. if (!file_exists($lang_path)) {
  117. throw new Exception("could not find app_languages for '$app_path'");
  118. }
  119. require $lang_path;
  120. if (!is_array($text)) {
  121. throw new Exception("failed to import text data from '$app_path'");
  122. }
  123. //collect existing comments
  124. $comment = array();
  125. $file_handle = fopen($lang_path, "r");
  126. while (!feof($file_handle)) {
  127. if(preg_match('/\$text\[[\'"](.+)[\'"]\]\[[\'"](.+)[\'"]]\s+=\s+[\'"].*[\'"];\s+\/\/(.+)/', fgets($file_handle), $matches)){
  128. $comment[$matches[0]][$matches[1]] = $matches[2];
  129. }
  130. }
  131. fclose($file_handle);
  132. //open the language file for writing
  133. $lang_file = fopen($lang_path, 'w');
  134. date_default_timezone_set('UTC');
  135. fwrite($lang_file, "<?php\n#This file was last reorganized on " . date("jS \of F Y h:i:s A e") . "\n");
  136. if (!$no_sort) {
  137. if ($app_path == 'resources') {
  138. $temp_A['language-name'] = $text['language-name'];
  139. unset($text['language-name']);
  140. foreach($this->languages as $language) {
  141. $temp_B["language-$language"] = $text["language-$language"];
  142. unset($text["language-$language"]);
  143. }
  144. $temp_C["language-en-us"] = $temp_B["language-en-us"];
  145. unset($temp_B["language-en-us"]);
  146. ksort($temp_B);
  147. $temp_B = array_merge($temp_C, $temp_B);
  148. ksort($text);
  149. $text = array_merge($temp_A, $temp_B, $text);
  150. unset($temp_A, $temp_B, $temp_C);
  151. }
  152. else {
  153. ksort($text);
  154. }
  155. }
  156. else {
  157. if ($app_path == 'resources') {
  158. foreach($this->languages as $language) {
  159. $label = array_shift($text["language-$language"]);
  160. if (empty($label))
  161. $label = $language;
  162. $text["language-$language"]['en-us'] = $label;
  163. }
  164. }
  165. }
  166. $last_lang_label = "";
  167. foreach ($text as $lang_label => $lang_codes) {
  168. //behave differently if we are one of the special language-* tags
  169. if (preg_match('/\Alanguage-(\w{2}|\w{2}-\w{2})\z/', $lang_label, $lang_code)) {
  170. if ($lang_label == 'language-en-us')
  171. fwrite($lang_file, "\n");
  172. $target_lang = $lang_code[1];
  173. if (strlen($target_lang) == 2) {
  174. if (array_key_exists($target_lang, $this->legacy_map)) {
  175. $target_lang = $this->legacy_map[$target_lang];
  176. }
  177. }
  178. $spacer = "";
  179. if (strlen($target_lang) == 11)
  180. $spacer = " ";
  181. $language_name = $this->escape_str(array_shift($text[$lang_label]));
  182. if (empty($language_name))
  183. $language_name = $this->escape_str($target_lang);
  184. fwrite($lang_file, "\$text['language-$target_lang'$spacer]['en-us'] = \"$language_name\";\n");
  185. }
  186. else {
  187. //put a line break in between the last tag if it has changed
  188. if ($last_lang_label != $lang_label)
  189. fwrite($lang_file, "\n");
  190. foreach ($this->languages as $lang_code) {
  191. $value = "";
  192. $append = "";
  193. $spacer = "";
  194. $target_lang = $lang_code;
  195. if (strlen($lang_code) == 2) {
  196. if (array_key_exists($lang_code, $this->legacy_map)) {
  197. $target_lang = $this->legacy_map[$lang_code];
  198. }
  199. }
  200. if (strlen($target_lang) == 2)
  201. $spacer = " ";
  202. if (array_key_exists($lang_code, $text[$lang_label]))
  203. $value = $text[$lang_label][$lang_code];
  204. if (empty($value) and array_key_exists($target_lang, $this->legacy_map)) {
  205. $value = $text[$lang_label][$this->legacy_map[$target_lang]];
  206. }
  207. $base_code = substr($target_lang, 0, 2);
  208. if (!empty($value)
  209. and array_key_exists($base_code, $this->legacy_map )
  210. and $this->legacy_map[$base_code] != $target_lang
  211. and $value == $text[$lang_label][$this->legacy_map[$base_code]]
  212. ) {
  213. $append = " //copied from ".$this->legacy_map[$base_code];
  214. }
  215. if (empty($value)) {
  216. foreach($this->languages as $lang_code) {
  217. if (substr($lang_code, 0, 2) == $base_code and !empty($text[$lang_label][$lang_code])) {
  218. $value = $text[$lang_label][$lang_code];
  219. $append = " //copied from $lang_code";
  220. continue;
  221. }
  222. }
  223. }
  224. if(empty($append) && array_key_exists($comment, $lang_label) && array_key_exists($comment[$lang_label], $lang_code)) {
  225. $append = " //$comment[$lang_label][$lang_code]";
  226. }
  227. fwrite($lang_file, "\$text['$lang_label']['$target_lang'$spacer] = \"".$this->escape_str($value)."\";$append\n");
  228. }
  229. }
  230. $last_lang_label = $lang_label;
  231. }
  232. //close the language file
  233. fwrite($lang_file, "\n?>\n");
  234. fclose($lang_file);
  235. }
  236. public function detect_all_languages($no_sort = false) {
  237. //clear $text ready for the import
  238. $text = array();
  239. $languages = array();
  240. //retrieve all the languages
  241. $files = glob($_SERVER["PROJECT_ROOT"] . "/*/*/app_languages.php");
  242. foreach($files as $file) {
  243. include $file;
  244. }
  245. include $_SERVER["PROJECT_ROOT"] . "/resources/app_languages.php";
  246. //check every tag
  247. foreach($text as $lang_codes) {
  248. foreach($lang_codes as $language_code => $value) {
  249. if (strlen($language_code) == 2) {
  250. if (array_key_exists($language_code, $this->legacy_map)) {
  251. $language_code = $this->legacy_map[$language_code];
  252. }
  253. }
  254. $languages[$language_code] = 1;
  255. }
  256. }
  257. //set $this->languages up according to what we found
  258. unset($languages['en-us']);
  259. $languages = array_keys($languages);
  260. asort($languages);
  261. array_unshift($languages, 'en-us');
  262. //support legacy variable
  263. $_SESSION['app']['languages'] = $languages;
  264. $this->languages = $languages;
  265. //rewrite resources/app_languges
  266. $this->organize_language('resources', $no_sort);
  267. }
  268. public function language_totals() {
  269. //setup variables
  270. $language_totals = array();
  271. $language_totals['languages']['total'] = 0;
  272. $language_totals['menu_items']['total'] = 0;
  273. $language_totals['app_descriptions']['total'] = 0;
  274. foreach ($this->languages as $language_code) {
  275. $language_totals[$language_code] = 0;
  276. }
  277. //retrieve all the languages
  278. $text = array();
  279. $files = glob($_SERVER["PROJECT_ROOT"] . "/*/*/app_languages.php");
  280. foreach($files as $file) {
  281. include $file;
  282. }
  283. include $_SERVER["PROJECT_ROOT"] . "/resources/app_languages.php";
  284. //check every tag
  285. foreach($text as $label_name => $values) {
  286. $language_totals['languages']['total']++;
  287. foreach ($this->languages as $language_code) {
  288. if (!empty($values[$language_code]))
  289. $language_totals['languages'][$language_code]++;
  290. }
  291. }
  292. unset($text);
  293. //retrieve all the menus
  294. $x = 0;
  295. $files = glob($_SERVER["PROJECT_ROOT"] . "/*/*");
  296. foreach($files as $file) {
  297. if (file_exists($file . "/app_menu.php"))
  298. include $file . "/app_menu.php";
  299. if (file_exists($file . "/app_config.php"))
  300. include $file . "/app_config.php";
  301. $x++;
  302. }
  303. //check every tag
  304. foreach($apps as $app) {
  305. $language_totals['app_descriptions']['total']++;
  306. foreach($app['menu'] as $menu_item) {
  307. $language_totals['menu_items']['total']++;
  308. foreach ($this->languages as $language_code) {
  309. if (!empty($menu_item['title'][$language_code]))
  310. $language_totals['menu_items'][$language_code]++;
  311. }
  312. }
  313. foreach ($this->languages as $language_code) {
  314. if (!empty($app['description'][$language_code])) {
  315. $language_totals['app_descriptions'][$language_code]++;
  316. }
  317. }
  318. }
  319. return $language_totals;
  320. }
  321. private function escape_str($string = '') {
  322. //perform initial escape
  323. $string = addslashes(stripslashes($string));
  324. //swap \' as we don't need to escape those
  325. return preg_replace("/\\\'/", "'", $string);
  326. //escape " as we write our strings double quoted
  327. return preg_replace("/\"/", '\"', $string);
  328. }
  329. }
  330. ?>