Source for file LanguageLocalizer.class.php

Documentation is available at LanguageLocalizer.class.php

  1. <?php
  2.  
  3. /**
  4. * The LanguageLocalizer is a class that handles the organization or strings
  5. * and other data for multiple languages.
  6. *
  7. * @package harmoni.languages
  8. *
  9. * @copyright Copyright &copy; 2005, Middlebury College
  10. * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License (GPL)
  11. *
  12. * @version $Id: LanguageLocalizer.class.php,v 1.22 2007/09/04 20:25:35 adamfranco Exp $
  13. */
  14. class LanguageLocalizer {
  15. /**
  16. * @access private
  17. * @var string $_lang The current language.
  18. ***/
  19. var $_lang;
  20. /**
  21. * @access private
  22. * @var string $_langDir The directory in which all the languages reside.
  23. ***/
  24. var $_langDir;
  25. /**
  26. * @access private
  27. * @var array $_strings A hash table of strings for this language.
  28. ***/
  29. var $_strings;
  30.  
  31. /**
  32. * @access private
  33. * @var string $_application The "app" we are bound to.
  34. ***/
  35. var $_application;
  36.  
  37. /**
  38. * The constructor.
  39. * @param optional string $langDir The directory in which language files reside.
  40. * @param optional string $application The name of the application to use (for *.mo files)
  41. * @param optional string $defaultLanguage The default language to use.
  42. * @access public
  43. * @return void
  44. * @todo -cLanguageLocalizer Implement LanguageLocalizer.constructor - use gettext functionality.
  45. ***/
  46. function LanguageLocalizer() {
  47. // Get the current Language encoding from the session if it exists.
  48. if (isset($_SESSION['__CurrentLanguageCodeset'])) {
  49. $this->_codeset = $_SESSION['__CurrentLanguageCodeset'];
  50. } else {
  51. // Use UTF-8 by default.
  52. $this->_codeset = "UTF-8";
  53. }
  54. }
  55. /**
  56. * Assign the configuration of this Manager. Valid configuration options are as
  57. * follows:
  58. * default_language string (ex: 'en_US')
  59. * applications array of strings (
  60. * application_name => language_file_directory,
  61. * ...,
  62. * ...,
  63. * )
  64. *
  65. *
  66. * @param object Properties $configuration (original type: java.util.Properties)
  67. *
  68. * @throws object OsidException An exception with one of the following
  69. * messages defined in org.osid.OsidException: {@link }
  70. * org.osid.OsidException#OPERATION_FAILED OPERATION_FAILED},
  71. * {@link org.osid.OsidException#PERMISSION_DENIED}
  72. * PERMISSION_DENIED}, {@link }
  73. * org.osid.OsidException#CONFIGURATION_ERROR
  74. * CONFIGURATION_ERROR}, {@link }
  75. * org.osid.OsidException#UNIMPLEMENTED UNIMPLEMENTED}, {@link }
  76. * org.osid.OsidException#NULL_ARGUMENT NULL_ARGUMENT}
  77. *
  78. * @access public
  79. */
  80. function assignConfiguration ( $configuration ) {
  81. $this->_configuration =$configuration;
  82. ArgumentValidator::validate($configuration->getProperty('default_language'),
  83. StringValidatorRule::getRule(), true);
  84. ArgumentValidator::validate($configuration->getProperty('applications'),
  85. ArrayValidatorRule::getRule(), true);
  86. // Get the current Language settings from the session if they exist.
  87. if (isset($_SESSION['__CurrentLanguage'])) {
  88. $this->setLanguage( $_SESSION['__CurrentLanguage'] );
  89. } else {
  90. $this->setLanguage( $configuration->getProperty('default_language') );
  91. }
  92. foreach ($configuration->getProperty('applications')
  93. as $application => $languageDir)
  94. {
  95. ArgumentValidator::validate($application, StringValidatorRule::getRule(), true);
  96. ArgumentValidator::validate($languageDir, StringValidatorRule::getRule(), true);
  97. $this->addApplication($application, $languageDir);
  98. }
  99. }
  100.  
  101. /**
  102. * Return context of this OsidManager.
  103. *
  104. * @return object OsidContext
  105. *
  106. * @throws object OsidException
  107. *
  108. * @access public
  109. */
  110. function getOsidContext () {
  111. return $this->_osidContext;
  112. }
  113.  
  114. /**
  115. * Assign the context of this OsidManager.
  116. *
  117. * @param object OsidContext $context
  118. *
  119. * @throws object OsidException An exception with one of the following
  120. * messages defined in org.osid.OsidException: {@link }
  121. * org.osid.OsidException#NULL_ARGUMENT NULL_ARGUMENT}
  122. *
  123. * @access public
  124. */
  125. function assignOsidContext ( $context ) {
  126. $this->_osidContext =$context;
  127. }
  128. /**
  129. * Add a new application to the LanguageLocalizer.
  130. * The first application added will be the default textdomain.
  131. * To use language files in other textdomains use the PHP textdomain()
  132. * function as follows:
  133. *
  134. * < ?
  135. * $defaultTextDomain = textdomain();
  136. * textdomain("myAppName");
  137. *
  138. * ...
  139. * print _("My nice string");
  140. * print _("Some other stuff.");
  141. * ...
  142. *
  143. * textdomain($defaultTextDomain);
  144. * ? >
  145. *
  146. * To create the localized binary hashes, the following steps need to be
  147. * followed:
  148. *
  149. * 1. use xgettext to create the .po translation files:
  150. * find /www/afranco/polyphony/ -iname "*.php" -exec xgettext -C -j -o /www/afranco/polyphony/main/languages/en_US/LC_MESSAGES/polyphony.po --keyword=_ {} \;
  151. *
  152. * 2. translate the .po files
  153. * 3. use msgfmt to create the binary hashes
  154. * msgfmt -vf /www/afranco/polyphony/main/languages/es_ES/LC_MESSAGES/polyphony.po -o /www/afranco/polyphony/main/languages/es_ES/LC_MESSAGES/polyphony.mo
  155. *
  156. * @param string $application The application name to add.
  157. * @param string $langDir The directory where language files for the
  158. * application are stored.
  159. * @return void
  160. */
  161. function addApplication ($application, $langDir) {
  162. if (!file_exists($langDir)) {
  163. throwError(new Error("LanguageLocalizer - could not find language folder '$langDir'.","LanguageLocalizer",true));
  164. return false;
  165. }
  166. $this->_applications[$application] = $langDir;
  167. // If gettext support is availible, use it.
  168. if (hasGettext()) {
  169. bindtextdomain($application, $langDir);
  170. bind_textdomain_codeset ($application, $this->_codeset);
  171. // The first application added will be the default textdomain.
  172. if (count($this->_applications) == 1)
  173. textdomain($application);
  174. }
  175. }
  176. /**
  177. * Sets the language to use for getting data to $language.
  178. * @param string $language The language code (eg, "en_US") to use.
  179. * @access public
  180. * @return void
  181. * @todo -cLanguageLocalizer Implement LanguageLocalizer.setLanguage - use gettext functionality.
  182. ***/
  183. function setLanguage($language) {
  184. if (!ereg("^[a-z]{2}_[A-Z]{2}",$language)) {
  185. throwError(new Error("LanguageLocalizer::setLanguage($language) - language must start with 'xx_XX' (where x/X is any letter). Example: 'en_US'.","LanguageLocalizer",true));
  186. return false;
  187. }
  188. // foreach ($this->_applications as $application => $langDir) {
  189. // $file = $langDir . DIRECTORY_SEPARATOR
  190. // . $language . DIRECTORY_SEPARATOR
  191. // . "LC_MESSAGES" . DIRECTORY_SEPARATOR
  192. // . $application . ".mo";
  193. //
  194. // if (! file_exists($file) ) {
  195. // throwError(new Error("LanguageLocalizer::setLanguage($language) - could not set language. The translation file '$file' does not exist!","LanguageLocalizer", true));
  196. // return false;
  197. // }
  198. // }
  199. $this->_lang = $language;
  200. $_SESSION['__CurrentLanguage'] = $this->_lang;
  201. // If gettext support is availible, use it.
  202. if (hasGettext()) {
  203. $result = setlocale(LC_ALL, $this->_lang);
  204. debug::output( "Setting Lang to ".$this->_lang." => '$result'.",DEBUG_SYS5,"LanguageLocalizer");
  205. }
  206. }
  207. /**
  208. * Return the code of the current language.
  209. * @return string
  210. */
  211. function getLanguage() {
  212. return $this->_lang;
  213. }
  214. /**
  215. * Sets the codeset to use for charactor encoding. UTF-8 is used by default.
  216. * @param string $codeset The codeset to use (eg, "UTF-8", "ISO-8859-8",
  217. * "SHIFT_JIS", etc).
  218. * @return void
  219. */
  220. function setCodeset($codeset) {
  221. $this->_codeset = $codeset;
  222. $_SESSION['__CurrentLanguageCodeset'] = $this->_codeset;
  223. // If gettext support is availible, use it.
  224. if (hasGettext()) {
  225. foreach ($this->_applications as $application => $langDir) {
  226. bind_textdomain_codeset ($application, $codeset);
  227. }
  228. }
  229. }
  230. /**
  231. * Return an array of availible languages. The keys are the language codes
  232. * and the values are a UTF-8 encoded string representation of the language
  233. * name (eg. "en_US" => "English - US", "es_ES" => "Espa–ol - Espa–a",
  234. * "es_MX" => "Espa–ol - Mˇxico")
  235. * @param boolean $includeCountries Include the countries of the language
  236. * codes. Default is TRUE.
  237. * @return array
  238. */
  239. function getLanguages($includeCountries = TRUE) {
  240. if (!isset($_SESSION['__AvailibleLanguages'])) {
  241. $langfile = HARMONI.'languageLocalizer/iso639-utf8.txt';
  242. $countryfile = HARMONI.'languageLocalizer/countries.txt';
  243. // Compile an array of all languages
  244. $languages = array();
  245. $inputArray = file($langfile);
  246. foreach ($inputArray as $line) {
  247. $line = rtrim($line);
  248. $parts = explode(';',$line);
  249. if ($parts[2])
  250. $languages[$parts[2]] = $parts[3];
  251. }
  252. // Compile an array of all countries
  253. if ($includeCountries) {
  254. $countries = array();
  255. $inputArray = file($countryfile);
  256. foreach ($inputArray as $line) {
  257. $line = rtrim($line);
  258. $parts = explode(';',$line);
  259. $countries[$parts[1]] = $parts[0];
  260. }
  261. }
  262. $_SESSION['__AvailibleLanguages'] = array();
  263. // If gettext is availible, return all of the languages availble
  264. if (hasGettext()) {
  265. foreach ($this->_applications as $application => $langDir) {
  266. $handle = opendir($langDir);
  267. while (($file = readdir($handle)) !== FALSE) {
  268. if (ereg("([a-z]{2})_([A-Z]{2})", $file, $parts)) {
  269. if ($includeCountries)
  270. $_SESSION['__AvailibleLanguages'][$file] = $languages[$parts[1]].
  271. " - ".$countries[$parts[2]];
  272. else
  273. $_SESSION['__AvailibleLanguages'][$file] = $languages[$parts[1]];
  274. }
  275. }
  276. }
  277. }
  278. // if we don't have gettext support, just show the default language
  279. else {
  280. ereg("([a-z]{2})_([A-Z]{2})", $this->_lang, $parts);
  281. $_SESSION['__AvailibleLanguages'][$this->_lang] = $languages[$parts[1]].
  282. " - ".$countries[$parts[2]];
  283. }
  284. }
  285. return $_SESSION['__AvailibleLanguages'];
  286. }
  287. }
  288.  
  289. /**
  290. * For systems that don't have gettext installed, we want to define a "_" function
  291. * so that harmoni will still operate, if only in English
  292. */
  293. if (!function_exists("gettext")) {
  294. /**
  295. * Return The status of REAL gettext support
  296. *
  297. * @return boolean
  298. * @access public
  299. * @since 11/17/04
  300. *
  301. */
  302. function hasGettext () {
  303. return FALSE;
  304. }
  305. /**
  306. * Returns the passed string to emulate untranslated language support for
  307. * systems on which gettext isn't availible
  308. *
  309. * @param string $string
  310. * @return string
  311. * @access public
  312. * @since 11/16/04
  313. *
  314. */
  315. function _ ( $string ) {
  316. return $string;
  317. }
  318.  
  319. /**
  320. * Returns the passed string to emulate untranslated language support for
  321. * systems on which gettext isn't availible
  322. *
  323. * @param string $string
  324. * @return string
  325. * @access public
  326. * @since 11/16/04
  327. *
  328. */
  329. function gettext ( $string ) {
  330. return $string;
  331. }
  332. /**
  333. * Returns the passed string unchanged.
  334. * @param string $domain
  335. * @param string $string
  336. * @access public
  337. * @return string
  338. */
  339. function dgettext ($domain, $string) {
  340. return $string;
  341. }
  342. /**
  343. * Does nothing. Here to emulate untranslated language support for
  344. * systems on which gettext isn't availible
  345. *
  346. * @param string $string
  347. * @return string
  348. * @access public
  349. * @since 11/16/04
  350. *
  351. */
  352. function textdomain ( $string ) {
  353. if ($string) {
  354. $_SESSION['__fake_text_domain'] = $string;
  355. }
  356. if (isset($_SESSION['__fake_text_domain']))
  357. return $_SESSION['__fake_text_domain'];
  358. else
  359. return "en_US";
  360. }
  361. } else {
  362.  
  363. /**
  364. * Return The status of REAL gettext support
  365. *
  366. * @return boolean
  367. * @access public
  368. * @since 11/17/04
  369. *
  370. */
  371. function hasGettext () {
  372. return TRUE;
  373. }
  374. }
  375.  
  376. ?>

Documentation generated on Wed, 19 Sep 2007 10:24:47 -0400 by phpDocumentor 1.3.0RC3