text.php 11 KB

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