/src/lib/i18n/ZLocale.php

https://github.com/ThiloWitt/core · PHP · 428 lines · 201 code · 37 blank · 190 comment · 11 complexity · 72301ead1f5ab3f12e348e3e5742b99a MD5 · raw file

  1. <?php
  2. /**
  3. * Copyright Zikula Foundation 2009 - Zikula Application Framework
  4. *
  5. * This work is contributed to the Zikula Foundation under one or more
  6. * Contributor Agreements and licensed to You under the following license:
  7. *
  8. * @license GNU/LGPLv3 (or at your option, any later version).
  9. * @package I18n
  10. *
  11. * Please see the NOTICE file distributed with this source code for further
  12. * information regarding copyright and licensing.
  13. */
  14. /**
  15. * ZLocale class
  16. */
  17. class ZLocale implements ArrayAccess
  18. {
  19. // public properties
  20. /**
  21. * Locale.
  22. *
  23. * @var string
  24. */
  25. private $locale;
  26. /**
  27. * Errors.
  28. *
  29. * @var array
  30. */
  31. private $errors = array();
  32. /**
  33. * Locale data.
  34. *
  35. * @var array
  36. */
  37. private $localeData = array(
  38. 'language_direction' => 'ltr',
  39. 'decimal_point' => '.',
  40. 'thousands_sep' => ',',
  41. 'int_curr_symbol' => 'EUR',
  42. 'currency_symbol' => '€',
  43. 'mon_decimal_point' => '.',
  44. 'mon_thousands_sep' => ',',
  45. 'positive_sign' => '',
  46. 'negative_sign' => '-',
  47. 'int_frac_digits' => '2',
  48. 'frac_digits' => '2',
  49. 'p_cs_precedes' => '1',
  50. 'p_sep_by_space' => '1',
  51. 'n_cs_precedes' => '1',
  52. 'n_sep_by_space' => '1',
  53. 'p_sign_posn' => '1',
  54. 'n_sign_posn' => '2',
  55. 'firstweekday' => '0',
  56. 'timeformat' => '24',
  57. 'grouping' => array(),
  58. 'mon_grouping' => array());
  59. /**
  60. * Constructor.
  61. *
  62. * @param string $locale Loacle.
  63. */
  64. public function __construct($locale)
  65. {
  66. $this->locale = $locale;
  67. $this->loadLocaleConfig();
  68. $this->detectErrors();
  69. }
  70. /**
  71. * Load locale config
  72. *
  73. * @return void
  74. */
  75. private function loadLocaleConfig()
  76. {
  77. $lang = ZLanguage::transformFS($this->locale);
  78. $override = "config/locale/$lang/locale.ini";
  79. $file = (file_exists($override) ? $override : "locale/$lang/locale.ini");
  80. if (is_readable($file)) {
  81. $array = parse_ini_file($file, false);
  82. foreach ($array as $k => $v) {
  83. $k = strtolower($k);
  84. if ($k == "grouping" || $k == "mon_grouping") {
  85. $v = explode(',', $v);
  86. }
  87. if (!is_array($v)) {
  88. $v = strtolower(trim(trim($v, '"'), "'"));
  89. }
  90. $this->localeData[$k] = $v;
  91. }
  92. $this->validateLocale($file);
  93. } else {
  94. $this->registerError(__f("Error! Could not load '%s'. Please check that it exists.", $file));
  95. }
  96. }
  97. /**
  98. * Validate the locale.
  99. *
  100. * @param string $file Locale file.
  101. *
  102. * @return void
  103. */
  104. private function validateLocale($file)
  105. {
  106. if (count($this->localeData) == 0) {
  107. $this->registerError(__f('Error! The locale file %s contains invalid data.', array($file)));
  108. return;
  109. }
  110. $validationArray = array('language_direction' => '#^(ltr|rtl)$#');
  111. foreach ($validationArray as $key => $validation) {
  112. if (!isset($this->localeData[$key])) {
  113. $this->registerError(__f('Error! %1$s is missing in %2$s.', array(
  114. $key,
  115. $file)));
  116. } else {
  117. if (!preg_match($validation, $this->localeData[$key])) {
  118. $this->registerError(__f('Error! There is an invalid value for %1$s in %2$s.', array(
  119. $key,
  120. $file)));
  121. }
  122. }
  123. }
  124. }
  125. /**
  126. * Register an error.
  127. *
  128. * @param string $msg Error message.
  129. *
  130. * @return void
  131. */
  132. private function registerError($msg)
  133. {
  134. $this->errors[] = $msg;
  135. }
  136. /**
  137. * Detect errors.
  138. *
  139. * @return boolean
  140. */
  141. private function detectErrors()
  142. {
  143. if (count($this->errors) == 0) {
  144. return true;
  145. }
  146. // fatal errors require 404
  147. header('HTTP/1.1 404 Not Found');
  148. foreach ($this->errors as $error) {
  149. LogUtil::registerError($error);
  150. }
  151. return false;
  152. }
  153. // getters
  154. /**
  155. * Get n_sign_posn.
  156. *
  157. * @return integer The $n_sign_posn.
  158. */
  159. public function getN_sign_posn()
  160. {
  161. return $this->localeData['n_sign_posn'];
  162. }
  163. /**
  164. * Get p_sign_posn.
  165. *
  166. * @return integer The $p_sign_posn.
  167. */
  168. public function getP_sign_posn()
  169. {
  170. return $this->localeData['p_sign_posn'];
  171. }
  172. /**
  173. * Get n_sep_by_space.
  174. *
  175. * @return integer The $n_sep_by_space
  176. */
  177. public function getN_sep_by_space()
  178. {
  179. return $this->localeData['n_sep_by_space'];
  180. }
  181. /**
  182. * Get n_cs_precedes.
  183. *
  184. * @return integer The $n_cs_precedes.
  185. */
  186. public function getN_cs_precedes()
  187. {
  188. return $this->localeData['n_cs_precedes'];
  189. }
  190. /**
  191. * Get p_sep_by_space.
  192. *
  193. * @return integer The $p_sep_by_space.
  194. */
  195. public function getP_sep_by_space()
  196. {
  197. return $this->localeData['p_sep_by_space'];
  198. }
  199. /**
  200. * Get p_cs_precedes.
  201. *
  202. * @return integer The $p_cs_precedes.
  203. */
  204. public function getP_cs_precedes()
  205. {
  206. return $this->localeData['p_cs_precedes'];
  207. }
  208. /**
  209. * Get frac_digets.
  210. *
  211. * @return integer The $frac_digits.
  212. */
  213. public function getFrac_digits()
  214. {
  215. return $this->localeData['frac_digits'];
  216. }
  217. /**
  218. * Get int_frac_digits.
  219. *
  220. * @return integer The $int_frac_digits.
  221. */
  222. public function getInt_frac_digits()
  223. {
  224. return $this->localeData['int_frac_digits'];
  225. }
  226. /**
  227. * Get negative_sign.
  228. *
  229. * @return string The $negative_sign.
  230. */
  231. public function getNegative_sign()
  232. {
  233. return $this->localeData['negative_sign'];
  234. }
  235. /**
  236. * Get positive_sign.
  237. *
  238. * @return string The $positive_sign.
  239. */
  240. public function getPositive_sign()
  241. {
  242. return $this->localeData['positive_sign'];
  243. }
  244. /**
  245. * Get mon_thousands_sep.
  246. *
  247. * @return string The $mon_thousands_sep.
  248. */
  249. public function getMon_thousands_sep()
  250. {
  251. return $this->localeData['mon_thousands_sep'];
  252. }
  253. /**
  254. * Get mon_decimal_point.
  255. *
  256. * @return string The $mon_decimal_point.
  257. */
  258. public function getMon_decimal_point()
  259. {
  260. return $this->localeData['mon_decimal_point'];
  261. }
  262. /**
  263. * Get currency_symbol.
  264. *
  265. * @return string The $currency_symbol.
  266. */
  267. public function getCurrency_symbol()
  268. {
  269. return $this->localeData['currency_symbol'];
  270. }
  271. /**
  272. * Get int_curr_symbol.
  273. *
  274. * @return string The $int_curr_symbol.
  275. */
  276. public function getInt_curr_symbol()
  277. {
  278. return $this->localeData['int_curr_symbol'];
  279. }
  280. /**
  281. * Get thousands_sep.
  282. *
  283. * @return string The $thousands_sep.
  284. */
  285. public function getThousands_sep()
  286. {
  287. return $this->localeData['thousands_sep'];
  288. }
  289. /**
  290. * Get decimal_point.
  291. *
  292. * @return string The $decimal_point.
  293. */
  294. public function getDecimal_point()
  295. {
  296. return $this->localeData['decimal_point'];
  297. }
  298. /**
  299. * Get language_direction.
  300. *
  301. * @return string The $language_direction.
  302. */
  303. public function getLanguage_direction()
  304. {
  305. return $this->localeData['language_direction'];
  306. }
  307. /**
  308. * Get firstweekday.
  309. *
  310. * @return string The $firstweekday.
  311. */
  312. public function getFirstweekday()
  313. {
  314. return $this->localeData['firstweekday'];
  315. }
  316. /**
  317. * Get timeformat.
  318. *
  319. * @return strng The $timeformat.
  320. */
  321. public function getTimeformat()
  322. {
  323. return $this->localeData['timeformat'];
  324. }
  325. /**
  326. * Get grouping.
  327. *
  328. * @return string The $grouping.
  329. */
  330. public function getGrouping()
  331. {
  332. return $this->localeData['grouping'];
  333. }
  334. /**
  335. * Get mon_grouping.
  336. *
  337. * @return string The $mon_grouping.
  338. */
  339. public function getMon_grouping()
  340. {
  341. return $this->localeData['mon_grouping'];
  342. }
  343. // automatic getters through ArrayAccess
  344. /**
  345. * Whether or not the offset exists.
  346. *
  347. * @param string $offset The offset.
  348. *
  349. * @return boolean
  350. */
  351. public function offsetExists($offset)
  352. {
  353. return (isset($this->$offset));
  354. }
  355. /**
  356. * Get by offset.
  357. *
  358. * @param string $offset The offset.
  359. *
  360. * @return mixed
  361. */
  362. public function offsetGet($offset)
  363. {
  364. return $this->localeData[$offset];
  365. }
  366. /**
  367. * Set by offset.
  368. *
  369. * @param string $offset The offset.
  370. * @param mixed $value The value.
  371. *
  372. * @return void
  373. */
  374. public function offsetSet($offset, $value)
  375. {
  376. $this->localeData[$offset] = $value;
  377. }
  378. /**
  379. * Unset by offset.
  380. *
  381. * @param string $offset The offset.
  382. *
  383. * @return void
  384. */
  385. public function offsetUnset($offset)
  386. {
  387. unset($this->localeData[$offset]);
  388. }
  389. }