PageRenderTime 41ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/oiclient/data/symfony/i18n/sfI18N.class.php

http://openirudi.googlecode.com/
PHP | 401 lines | 198 code | 46 blank | 157 comment | 14 complexity | c5c6056883c240b97430ac17a07e258f MD5 | raw file
Possible License(s): LGPL-2.1, AGPL-3.0
  1. <?php
  2. /*
  3. * This file is part of the symfony package.
  4. * (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
  5. *
  6. * For the full copyright and license information, please view the LICENSE
  7. * file that was distributed with this source code.
  8. */
  9. /**
  10. * sfI18N wraps the core i18n classes for a symfony context.
  11. *
  12. * @package symfony
  13. * @subpackage i18n
  14. * @author Fabien Potencier <fabien.potencier@symfony-project.com>
  15. * @version SVN: $Id: sfI18N.class.php 11700 2008-09-21 10:53:44Z fabien $
  16. */
  17. class sfI18N
  18. {
  19. protected
  20. $configuration = null,
  21. $dispatcher = null,
  22. $cache = null,
  23. $options = array(),
  24. $culture = 'en',
  25. $messageSource = null,
  26. $messageFormat = null;
  27. /**
  28. * Class constructor.
  29. *
  30. * @see initialize()
  31. */
  32. public function __construct(sfApplicationConfiguration $configuration, sfCache $cache = null, $options = array())
  33. {
  34. $this->initialize($configuration, $cache, $options);
  35. }
  36. /**
  37. * Initializes this class.
  38. *
  39. * Available options:
  40. *
  41. * * culture: The culture
  42. * * source: The i18n source (XLIFF by default)
  43. * * debug: Whether to enable debug or not (false by default)
  44. * * database: The database name (default by default)
  45. * * untranslated_prefix: The prefix to use when a message is not translated
  46. * * untranslated_suffix: The suffix to use when a message is not translated
  47. *
  48. * @param sfApplicationConfiguration $configuration A sfApplicationConfiguration instance
  49. * @param sfCache $cache A sfCache instance
  50. * @param array $options An array of options
  51. */
  52. public function initialize(sfApplicationConfiguration $configuration, sfCache $cache = null, $options = array())
  53. {
  54. $this->configuration = $configuration;
  55. $this->dispatcher = $configuration->getEventDispatcher();
  56. $this->cache = $cache;
  57. if (isset($options['culture']))
  58. {
  59. $this->culture = $options['culture'];
  60. unset($options['culture']);
  61. }
  62. $this->options = array_merge(array(
  63. 'source' => 'XLIFF',
  64. 'debug' => false,
  65. 'database' => 'default',
  66. 'untranslated_prefix' => '[T]',
  67. 'untranslated_suffix' => '[/T]',
  68. ), $options);
  69. $this->dispatcher->connect('user.change_culture', array($this, 'listenToChangeCultureEvent'));
  70. if($this->isMessageSourceFileBased($this->options['source']))
  71. {
  72. $this->dispatcher->connect('controller.change_action', array($this, 'listenToChangeActionEvent'));
  73. }
  74. }
  75. /**
  76. * Returns the initialization options
  77. *
  78. * @return array The options used to initialize sfI18n
  79. */
  80. public function getOptions()
  81. {
  82. return $this->options;
  83. }
  84. /**
  85. * Returns the configuration instance.
  86. *
  87. * @return sfApplicationConfiguration An sfApplicationConfiguration instance
  88. */
  89. public function getConfiguration()
  90. {
  91. return $this->configuration;
  92. }
  93. /**
  94. * Sets the message source.
  95. *
  96. * @param mixed $dirs An array of i18n directories if message source is a sfMessageSource_File subclass, null otherwise
  97. * @param string $culture The culture
  98. */
  99. public function setMessageSource($dirs, $culture = null)
  100. {
  101. if (is_null($dirs))
  102. {
  103. $this->messageSource = $this->createMessageSource();
  104. }
  105. else
  106. {
  107. $this->messageSource = sfMessageSource::factory('Aggregate', array_map(array($this, 'createMessageSource'), $dirs));
  108. }
  109. if (!is_null($this->cache))
  110. {
  111. $this->messageSource->setCache($this->cache);
  112. }
  113. if (!is_null($culture))
  114. {
  115. $this->setCulture($culture);
  116. }
  117. else
  118. {
  119. $this->messageSource->setCulture($this->culture);
  120. }
  121. $this->messageFormat = null;
  122. }
  123. /**
  124. * Returns a new message source.
  125. *
  126. * @param mixed $dir An array of i18n directories to create a XLIFF or gettext message source, null otherwise
  127. *
  128. * @return sfMessageSource A sfMessageSource object
  129. */
  130. public function createMessageSource($dir = null)
  131. {
  132. return sfMessageSource::factory($this->options['source'], self::isMessageSourceFileBased($this->options['source']) ? $dir : $this->options['database']);
  133. }
  134. /**
  135. * Gets the current culture for i18n format objects.
  136. *
  137. * @return string The culture
  138. */
  139. public function getCulture()
  140. {
  141. return $this->culture;
  142. }
  143. /**
  144. * Sets the current culture for i18n format objects.
  145. *
  146. * @param string $culture The culture
  147. */
  148. public function setCulture($culture)
  149. {
  150. $this->culture = $culture;
  151. // change user locale for formatting, collation, and internal error messages
  152. setlocale(LC_ALL, $culture.'.utf8');
  153. if ($this->messageSource)
  154. {
  155. $this->messageSource->setCulture($culture);
  156. $this->messageFormat = null;
  157. }
  158. }
  159. /**
  160. * Gets the message source.
  161. *
  162. * @return sfMessageSource A sfMessageSource object
  163. */
  164. public function getMessageSource()
  165. {
  166. if (!isset($this->messageSource))
  167. {
  168. $dirs = ($this->isMessageSourceFileBased($this->options['source'])) ? $this->configuration->getI18NGlobalDirs() : null;
  169. $this->setMessageSource($dirs, $this->culture);
  170. }
  171. return $this->messageSource;
  172. }
  173. /**
  174. * Gets the message format.
  175. *
  176. * @return sfMessageFormat A sfMessageFormat object
  177. */
  178. public function getMessageFormat()
  179. {
  180. if (!isset($this->messageFormat))
  181. {
  182. $this->messageFormat = new sfMessageFormat($this->getMessageSource(), sfConfig::get('sf_charset'));
  183. if ($this->options['debug'])
  184. {
  185. $this->messageFormat->setUntranslatedPS(array($this->options['untranslated_prefix'], $this->options['untranslated_suffix']));
  186. }
  187. }
  188. return $this->messageFormat;
  189. }
  190. /**
  191. * Gets the translation for the given string
  192. *
  193. * @param string $string The string to translate
  194. * @param array $args An array of arguments for the translation
  195. * @param string $catalogue The catalogue name
  196. *
  197. * @return string The translated string
  198. */
  199. public function __($string, $args = array(), $catalogue = 'messages')
  200. {
  201. return $this->getMessageFormat()->format($string, $args, $catalogue);
  202. }
  203. /**
  204. * Gets a country name.
  205. *
  206. * @param string $iso The ISO code
  207. * @param string $culture The culture for the translation
  208. *
  209. * @return string The country name
  210. */
  211. public function getCountry($iso, $culture = null)
  212. {
  213. $c = sfCultureInfo::getInstance(is_null($culture) ? $this->culture : $culture);
  214. $countries = $c->getCountries();
  215. return (array_key_exists($iso, $countries)) ? $countries[$iso] : '';
  216. }
  217. /**
  218. * Gets a native culture name.
  219. *
  220. * @param string $culture The culture
  221. *
  222. * @return string The culture name
  223. */
  224. public function getNativeName($culture)
  225. {
  226. return sfCultureInfo::getInstance($culture)->getNativeName();
  227. }
  228. /**
  229. * Returns a timestamp from a date with time formatted with a given culture.
  230. *
  231. * @param string $dateTime The formatted date with time as string
  232. * @param string $culture The culture
  233. *
  234. * @return integer The timestamp
  235. */
  236. public function getTimestampForCulture($dateTime, $culture = null)
  237. {
  238. list($day, $month, $year) = $this->getDateForCulture($dateTime, is_null($culture) ? $this->culture : $culture);
  239. list($hour, $minute) = $this->getTimeForCulture($dateTime, is_null($culture) ? $this->culture : $culture);
  240. return is_null($day) ? null : mktime($hour, $minute, 0, $month, $day, $year);
  241. }
  242. /**
  243. * Returns the day, month and year from a date formatted with a given culture.
  244. *
  245. * @param string $date The formatted date as string
  246. * @param string $culture The culture
  247. *
  248. * @return array An array with the day, month and year
  249. */
  250. public function getDateForCulture($date, $culture = null)
  251. {
  252. if (!$date)
  253. {
  254. return null;
  255. }
  256. $dateFormatInfo = @sfDateTimeFormatInfo::getInstance(is_null($culture) ? $this->culture : $culture);
  257. $dateFormat = $dateFormatInfo->getShortDatePattern();
  258. // We construct the regexp based on date format
  259. $dateRegexp = preg_replace('/[dmy]+/i', '(\d+)', $dateFormat);
  260. // We parse date format to see where things are (m, d, y)
  261. $a = array(
  262. 'd' => strpos($dateFormat, 'd'),
  263. 'm' => strpos($dateFormat, 'M'),
  264. 'y' => strpos($dateFormat, 'y'),
  265. );
  266. $tmp = array_flip($a);
  267. ksort($tmp);
  268. $i = 0;
  269. $c = array();
  270. foreach ($tmp as $value) $c[++$i] = $value;
  271. $datePositions = array_flip($c);
  272. // We find all elements
  273. if (preg_match("~$dateRegexp~", $date, $matches))
  274. {
  275. // We get matching timestamp
  276. return array($matches[$datePositions['d']], $matches[$datePositions['m']], $matches[$datePositions['y']]);
  277. }
  278. else
  279. {
  280. return null;
  281. }
  282. }
  283. /**
  284. * Returns the hour, minute from a date formatted with a given culture.
  285. *
  286. * @param string $date The formatted date as string
  287. * @param string $culture The culture
  288. *
  289. * @return array An array with the hour and minute
  290. */
  291. public function getTimeForCulture($time, $culture)
  292. {
  293. if (!$time) return 0;
  294. $culture = is_null($culture) ? $this->culture : $culture;
  295. $timeFormatInfo = @sfDateTimeFormatInfo::getInstance($culture);
  296. $timeFormat = $timeFormatInfo->getShortTimePattern();
  297. // We construct the regexp based on time format
  298. $timeRegexp = preg_replace(array('/[^hm:]+/i', '/[hm]+/i'), array('', '(\d+)'), $timeFormat);
  299. // We parse time format to see where things are (h, m)
  300. $a = array(
  301. 'h' => strpos($timeFormat, 'H') !== false ? strpos($timeFormat, 'H') : strpos($timeFormat, 'h'),
  302. 'm' => strpos($timeFormat, 'm')
  303. );
  304. $tmp = array_flip($a);
  305. ksort($tmp);
  306. $i = 0;
  307. $c = array();
  308. foreach ($tmp as $value) $c[++$i] = $value;
  309. $timePositions = array_flip($c);
  310. // We find all elements
  311. if (preg_match("~$timeRegexp~", $time, $matches))
  312. {
  313. // We get matching timestamp
  314. return array($matches[$timePositions['h']], $matches[$timePositions['m']]);
  315. }
  316. else
  317. {
  318. return null;
  319. }
  320. }
  321. /**
  322. * Returns true if messages are stored in a file.
  323. *
  324. * @param string $source The source name
  325. *
  326. * @return Boolean true if messages are stored in a file, false otherwise
  327. */
  328. static public function isMessageSourceFileBased($source)
  329. {
  330. $class = 'sfMessageSource_'.$source;
  331. return class_exists($class) && is_subclass_of($class, 'sfMessageSource_File');
  332. }
  333. /**
  334. * Listens to the user.change_culture event.
  335. *
  336. * @param sfEvent $event An sfEvent instance
  337. *
  338. */
  339. public function listenToChangeCultureEvent(sfEvent $event)
  340. {
  341. // change the message format object with the new culture
  342. $this->setCulture($event['culture']);
  343. }
  344. /**
  345. * Listens to the controller.change_action event.
  346. *
  347. * @param sfEvent $event An sfEvent instance
  348. *
  349. */
  350. public function listenToChangeActionEvent(sfEvent $event)
  351. {
  352. // change message source directory to our module
  353. $this->setMessageSource($this->configuration->getI18NDirs($event['module']));
  354. }
  355. }