text.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  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. //use the selected language
  92. $text[$key] = $value[$language_code];
  93. }
  94. elseif (isset($value['en-us'])) {
  95. //fallback to en-us
  96. $text[$key] = $value['en-us'];
  97. }
  98. else {
  99. $text[$key] = '';
  100. }
  101. }
  102. }
  103. }
  104. //return the array of translations
  105. return $text;
  106. }
  107. /**
  108. * reorganize an app_languages.php into a consistent format
  109. * @var string $app_path examples: app/exec or core/domains
  110. * @var string $no_sort don't sort the text label order
  111. */
  112. public function organize_language($app_path = null, $no_sort = false) {
  113. //clear $text ready for the import
  114. $text = array();
  115. //get the app_languages.php
  116. if ($app_path == null) {
  117. throw new Exception("\$app_path must be specified");
  118. }
  119. $lang_path = $_SERVER["PROJECT_ROOT"]."/$app_path/app_languages.php";
  120. if (!file_exists($lang_path)) {
  121. throw new Exception("could not find app_languages for '$app_path'");
  122. }
  123. require $lang_path;
  124. if (!is_array($text)) {
  125. throw new Exception("failed to import text data from '$app_path'");
  126. }
  127. //collect existing comments
  128. $comment = array();
  129. $file_handle = fopen($lang_path, "r");
  130. while (!feof($file_handle)) {
  131. if(preg_match('/\$text\[[\'"](.+)[\'"]\]\[[\'"](.+)[\'"]]\s+=\s+[\'"].*[\'"];\s+\/\/(.+)/', fgets($file_handle), $matches)){
  132. $comment[$matches[0]][$matches[1]] = $matches[2];
  133. }
  134. }
  135. fclose($file_handle);
  136. //open the language file for writing
  137. $lang_file = fopen($lang_path, 'w');
  138. date_default_timezone_set('UTC');
  139. fwrite($lang_file, "<?php\n#This file was last reorganized on " . date("jS \of F Y h:i:s A e") . "\n");
  140. if (!$no_sort) {
  141. if ($app_path == 'resources') {
  142. $temp_A['language-name'] = $text['language-name'];
  143. unset($text['language-name']);
  144. foreach($this->languages as $language) {
  145. $temp_B["language-$language"] = $text["language-$language"];
  146. unset($text["language-$language"]);
  147. }
  148. $temp_C["language-en-us"] = $temp_B["language-en-us"];
  149. unset($temp_B["language-en-us"]);
  150. ksort($temp_B);
  151. $temp_B = array_merge($temp_C, $temp_B);
  152. ksort($text);
  153. $text = array_merge($temp_A, $temp_B, $text);
  154. unset($temp_A, $temp_B, $temp_C);
  155. }
  156. else {
  157. ksort($text);
  158. }
  159. }
  160. else {
  161. if ($app_path == 'resources') {
  162. foreach($this->languages as $language) {
  163. $label = array_shift($text["language-$language"]);
  164. if (empty($label))
  165. $label = $language;
  166. $text["language-$language"]['en-us'] = $label;
  167. }
  168. }
  169. }
  170. $last_lang_label = "";
  171. foreach ($text as $lang_label => $lang_codes) {
  172. //behave differently if we are one of the special language-* tags
  173. if (preg_match('/\Alanguage-(\w{2}|\w{2}-\w{2})\z/', $lang_label, $lang_code)) {
  174. if ($lang_label == 'language-en-us')
  175. fwrite($lang_file, "\n");
  176. $target_lang = $lang_code[1];
  177. if (strlen($target_lang) == 2) {
  178. if (array_key_exists($target_lang, $this->legacy_map)) {
  179. $target_lang = $this->legacy_map[$target_lang];
  180. }
  181. }
  182. $spacer = "";
  183. if (strlen($target_lang) == 11)
  184. $spacer = " ";
  185. $language_name = $this->escape_str(array_shift($text[$lang_label]));
  186. if (empty($language_name))
  187. $language_name = $this->escape_str($target_lang);
  188. fwrite($lang_file, "\$text['language-$target_lang'$spacer]['en-us'] = \"$language_name\";\n");
  189. }
  190. else {
  191. //put a line break in between the last tag if it has changed
  192. if ($last_lang_label != $lang_label)
  193. fwrite($lang_file, "\n");
  194. foreach ($this->languages as $lang_code) {
  195. $value = "";
  196. $append = "";
  197. $spacer = "";
  198. $target_lang = $lang_code;
  199. if (strlen($lang_code) == 2) {
  200. if (array_key_exists($lang_code, $this->legacy_map)) {
  201. $target_lang = $this->legacy_map[$lang_code];
  202. }
  203. }
  204. if (strlen($target_lang) == 2)
  205. $spacer = " ";
  206. if (array_key_exists($lang_code, $text[$lang_label]))
  207. $value = $text[$lang_label][$lang_code];
  208. if (empty($value) and array_key_exists($target_lang, $this->legacy_map)) {
  209. $value = $text[$lang_label][$this->legacy_map[$target_lang]];
  210. }
  211. $base_code = substr($target_lang, 0, 2);
  212. if (!empty($value)
  213. and array_key_exists($base_code, $this->legacy_map )
  214. and $this->legacy_map[$base_code] != $target_lang
  215. and $value == $text[$lang_label][$this->legacy_map[$base_code]]
  216. ) {
  217. $append = " //copied from ".$this->legacy_map[$base_code];
  218. }
  219. if (empty($value)) {
  220. foreach($this->languages as $lang_code) {
  221. if (substr($lang_code, 0, 2) == $base_code and !empty($text[$lang_label][$lang_code])) {
  222. $value = $text[$lang_label][$lang_code];
  223. $append = " //copied from $lang_code";
  224. continue;
  225. }
  226. }
  227. }
  228. if(empty($append) && array_key_exists($comment, $lang_label) && array_key_exists($comment[$lang_label], $lang_code)) {
  229. $append = " //$comment[$lang_label][$lang_code]";
  230. }
  231. fwrite($lang_file, "\$text['$lang_label']['$target_lang'$spacer] = \"".$this->escape_str($value)."\";$append\n");
  232. }
  233. }
  234. $last_lang_label = $lang_label;
  235. }
  236. //close the language file
  237. fwrite($lang_file, "\n?>\n");
  238. fclose($lang_file);
  239. }
  240. public function detect_all_languages($no_sort = false) {
  241. //clear $text ready for the import
  242. $text = array();
  243. $languages = array();
  244. //retrieve all the languages
  245. $files = glob($_SERVER["PROJECT_ROOT"] . "/*/*/app_languages.php");
  246. foreach($files as $file) {
  247. include $file;
  248. }
  249. include $_SERVER["PROJECT_ROOT"] . "/resources/app_languages.php";
  250. //check every tag
  251. foreach($text as $lang_codes) {
  252. foreach($lang_codes as $language_code => $value) {
  253. if (strlen($language_code) == 2) {
  254. if (array_key_exists($language_code, $this->legacy_map)) {
  255. $language_code = $this->legacy_map[$language_code];
  256. }
  257. }
  258. $languages[$language_code] = 1;
  259. }
  260. }
  261. //set $this->languages up according to what we found
  262. unset($languages['en-us']);
  263. $languages = array_keys($languages);
  264. asort($languages);
  265. array_unshift($languages, 'en-us');
  266. //support legacy variable
  267. $_SESSION['app']['languages'] = $languages;
  268. $this->languages = $languages;
  269. //rewrite resources/app_languges
  270. $this->organize_language('resources', $no_sort);
  271. }
  272. public function language_totals() {
  273. //setup variables
  274. $language_totals = array();
  275. $language_totals['languages']['total'] = 0;
  276. $language_totals['menu_items']['total'] = 0;
  277. $language_totals['app_descriptions']['total'] = 0;
  278. foreach ($this->languages as $language_code) {
  279. $language_totals[$language_code] = 0;
  280. }
  281. //retrieve all the languages
  282. $text = array();
  283. $files = glob($_SERVER["PROJECT_ROOT"] . "/*/*/app_languages.php");
  284. foreach($files as $file) {
  285. include $file;
  286. }
  287. include $_SERVER["PROJECT_ROOT"] . "/resources/app_languages.php";
  288. //check every tag
  289. foreach($text as $label_name => $values) {
  290. $language_totals['languages']['total']++;
  291. foreach ($this->languages as $language_code) {
  292. if (!empty($values[$language_code]))
  293. $language_totals['languages'][$language_code]++;
  294. }
  295. }
  296. unset($text);
  297. //retrieve all the menus
  298. $x = 0;
  299. $files = glob($_SERVER["PROJECT_ROOT"] . "/*/*");
  300. foreach($files as $file) {
  301. if (file_exists($file . "/app_menu.php"))
  302. include $file . "/app_menu.php";
  303. if (file_exists($file . "/app_config.php"))
  304. include $file . "/app_config.php";
  305. $x++;
  306. }
  307. //check every tag
  308. foreach($apps as $app) {
  309. $language_totals['app_descriptions']['total']++;
  310. foreach($app['menu'] as $menu_item) {
  311. $language_totals['menu_items']['total']++;
  312. foreach ($this->languages as $language_code) {
  313. if (!empty($menu_item['title'][$language_code]))
  314. $language_totals['menu_items'][$language_code]++;
  315. }
  316. }
  317. foreach ($this->languages as $language_code) {
  318. if (!empty($app['description'][$language_code])) {
  319. $language_totals['app_descriptions'][$language_code]++;
  320. }
  321. }
  322. }
  323. return $language_totals;
  324. }
  325. private function escape_str($string = '') {
  326. //perform initial escape
  327. $string = addslashes(stripslashes($string));
  328. //swap \' as we don't need to escape those
  329. return preg_replace("/\\\'/", "'", $string);
  330. //escape " as we write our strings double quoted
  331. return preg_replace("/\"/", '\"', $string);
  332. }
  333. }
  334. ?>