1. sfMessageSource.class.php
  2. /** * Abstract sfMessageSource class. * * The base class for all sfMessageSources. Message sources must be instantiated * using the factory method. The default valid sources are * * # XLIFF -- using XML XLIFF format to store the translation messages. * # SQLite -- Store the translation messages in a SQLite database. * # MySQL -- Using a MySQL database to store the messages. * # gettext -- Translated messages are stored in the gettext format. * * A custom message source can be instantiated by specifying the filename * parameter to point to the custom class file. E.g. * * $resource = '...'; //custom message source resource * $classfile = '../sfMessageSource_MySource.php'; //custom message source * $source = sfMessageSource::factory('MySource', $resource, $classfile); * * * If you are writting your own message sources, pay attention to the * loadCatalogue method. It details how the resources are loaded and cached. * See also the existing message source types as examples. * * The following example instantiates a MySQL message source, set the culture, * set the cache handler, and use the source in a message formatter. * The messages are store in a database named "messages". The source parameter * for the actory method is a PEAR DB style DSN. * * $dsn = 'mysql://username:password@localhost/messages'; * $source = sfMessageSource::factory('MySQL', $dsn); * * //set the culture and cache, store the cache in the /tmp directory. * $source->setCulture('en_AU')l * $source->setCache(new sfMessageCache(new sfFileCache(array('/tmp')))); * * $formatter = new sfMessageFormat($source); * * * @author Xiang Wei Zhuo * @version v1.0, last update on Fri Dec 24 19:55:49 EST 2004 * @package symfony * @subpackage i18n */
  3. abstract class sfMessageSource implements sfIMessageSource
  4. {
  5. /**
  6. * The culture name for this message source.
  7. * @var string
  8. */
  9. protected $culture;
  10. /**
  11. * Array of translation messages.
  12. * @var array
  13. */
  14. protected $messages = array();
  15. /**
  16. * The source of message translations.
  17. * @var string
  18. */
  19. protected $source;
  20. /**
  21. * The translation cache.
  22. * @var sfMessageCache
  23. */
  24. protected $cache;
  25. protected $untranslated = array();
  26. /**
  27. * Private constructor. sfMessageSource must be initialized using
  28. * the factory method.
  29. */
  30. private function __construct()
  31. {
  32. //throw new sfException('Please use the factory method to instantiate.');
  33. }
  34. /**
  35. * Factory method to instantiate a new sfMessageSource depending on the
  36. * source type. The built-in source types are 'XLIFF', 'SQLite',
  37. * 'MySQL', 'gettext', and 'Aggregate'.
  38. * The source parameter is dependent on the source type.
  39. * For 'gettext' and 'XLIFF', it should point to the directory
  40. * where the messages are stored. For database types, e.g. 'SQLite' and
  41. * 'MySQL', it should be a PEAR DB style DSN string.
  42. *
  43. * Custom message source are possible by supplying the a filename parameter
  44. * in the factory method.
  45. *
  46. * @param string $type the message source type.
  47. * @param string $source the location of the resource.
  48. * @param string $filename the filename of the custom message source.
  49. * @return sfMessageSource a new message source of the specified type.
  50. * @throws sfException
  51. */
  52. static function factory($type, $source = '.', $filename = '')
  53. {
  54. if ($filename)
  55. {
  56. if (!is_file($filename))
  57. {
  58. throw new sfException(sprintf("File %s not found.", $filename));
  59. }
  60. include_once($filename);
  61. }
  62. $class = 'sfMessageSource_'.$type;
  63. if (!class_exists($class))
  64. {
  65. throw new sfException(sprintf('Unable to find type "%s".', $type));
  66. }
  67. return new $class($source);
  68. }
  69. /**
  70. * Loads a particular message catalogue. Use read() to
  71. * to get the array of messages. The catalogue loading sequence
  72. * is as follows:
  73. *
  74. * # [1] Call getCatalogueList($catalogue) to get a list of variants for for the specified $catalogue.
  75. * # [2] For each of the variants, call getSource($variant) to get the resource, could be a file or catalogue ID.
  76. * # [3] Verify that this resource is valid by calling isValidSource($source)
  77. * # [4] Try to get the messages from the cache
  78. * # [5] If a cache miss, call load($source) to load the message array
  79. * # [6] Store the messages to cache.
  80. * # [7] Continue with the foreach loop, e.g. goto [2].
  81. *
  82. * @param string $catalogue a catalogue to load
  83. * @return boolean always true
  84. * @see read()
  85. */
  86. function load($catalogue = 'messages')
  87. {
  88. $variants = $this->getCatalogueList($catalogue);
  89. $this->messages = array();
  90. foreach ($variants as $variant)
  91. {
  92. $source = $this->getSource($variant);
  93. if ($this->isValidSource($source) == false)
  94. {
  95. continue;
  96. }
  97. $loadData = true;
  98. if ($this->cache)
  99. {
  100. $lastModified = $this->getLastModified($source);
  101. if ($lastModified >= 0 && $lastModified < $this->cache->getLastModified($variant.':'.$this->culture))
  102. {
  103. $data = unserialize($this->cache->get($variant.':'.$this->culture));
  104. if (is_array($data))
  105. {
  106. $this->messages[$variant] = $data;
  107. $loadData = false;
  108. }
  109. unset($data);
  110. }
  111. }
  112. if ($loadData)
  113. {
  114. $data = &$this->loadData($source);
  115. if (is_array($data))
  116. {
  117. $this->messages[$variant] = $data;
  118. if ($this->cache)
  119. {
  120. $this->cache->set($variant.':'.$this->culture, serialize($data));
  121. }
  122. }
  123. unset($data);
  124. }
  125. }
  126. return true;
  127. }
  128. /**
  129. * Gets the array of messages.
  130. *
  131. * @return array translation messages.
  132. */
  133. public function read()
  134. {
  135. return $this->messages;
  136. }
  137. /**
  138. * Gets the cache handler for this source.
  139. *
  140. * @return sfMessageCache cache handler
  141. */
  142. public function getCache()
  143. {
  144. return $this->cache;
  145. }
  146. /**
  147. * Sets the cache handler for caching the messages.
  148. *
  149. * @param sfCache $cache the cache handler.
  150. */
  151. public function setCache(sfCache $cache)
  152. {
  153. $this->cache = $cache;
  154. }
  155. /**
  156. * Adds a untranslated message to the source. Need to call save()
  157. * to save the messages to source.
  158. *
  159. * @param string $message message to add
  160. */
  161. public function append($message)
  162. {
  163. if (!in_array($message, $this->untranslated))
  164. {
  165. $this->untranslated[] = $message;
  166. }
  167. }
  168. /**
  169. * Sets the culture for this message source.
  170. *
  171. * @param string $culture culture name
  172. */
  173. public function setCulture($culture)
  174. {
  175. $this->culture = $culture;
  176. }
  177. /**
  178. * Gets the culture identifier for the source.
  179. *
  180. * @return string culture identifier.
  181. */
  182. public function getCulture()
  183. {
  184. return $this->culture;
  185. }
  186. /**
  187. * Gets the last modified unix-time for this particular catalogue+variant.
  188. *
  189. * @param string $source catalogue+variant
  190. * @return int last modified in unix-time format.
  191. */
  192. protected function getLastModified($source)
  193. {
  194. return 0;
  195. }
  196. /**
  197. * Loads the message for a particular catalogue+variant.
  198. * This methods needs to implemented by subclasses.
  199. *
  200. * @param string $variant catalogue+variant.
  201. * @return array of translation messages.
  202. */
  203. public function &loadData($variant)
  204. {
  205. return array();
  206. }
  207. /**
  208. * Gets the source, this could be a filename or database ID.
  209. *
  210. * @param string $variant catalogue+variant
  211. * @return string the resource key
  212. */
  213. public function getSource($variant)
  214. {
  215. return $variant;
  216. }
  217. /**
  218. * Determines if the source is valid.
  219. *
  220. * @param string $source catalogue+variant
  221. * @return boolean true if valid, false otherwise.
  222. */
  223. public function isValidSource($source)
  224. {
  225. return false;
  226. }
  227. /**
  228. * Gets all the variants of a particular catalogue.
  229. * This method must be implemented by subclasses.
  230. *
  231. * @param string $catalogue catalogue name
  232. * @return array list of all variants for this catalogue.
  233. */
  234. public function getCatalogueList($catalogue)
  235. {
  236. return array();
  237. }
  238. }

Debug toolbar