22 import(
'lib.pkp.classes.i18n.LocaleFile');
24 if (!defined(
'LOCALE_REGISTRY_FILE')) {
25 define(
'LOCALE_REGISTRY_FILE',
'registry/locales.xml');
27 if (!defined(
'LOCALE_DEFAULT')) {
30 if (!defined(
'LOCALE_ENCODING')) {
31 define(
'LOCALE_ENCODING',
Config::getVar(
'i18n',
'client_charset'));
34 define(
'MASTER_LOCALE',
'en_US');
39 define(
'LOCALE_ERROR_MISSING_KEY',
'LOCALE_ERROR_MISSING_KEY');
40 define(
'LOCALE_ERROR_EXTRA_KEY',
'LOCALE_ERROR_EXTRA_KEY');
41 define(
'LOCALE_ERROR_DIFFERING_PARAMS',
'LOCALE_ERROR_DIFFERING_PARAMS');
42 define(
'LOCALE_ERROR_MISSING_FILE',
'LOCALE_ERROR_MISSING_FILE');
44 define(
'EMAIL_ERROR_MISSING_EMAIL',
'EMAIL_ERROR_MISSING_EMAIL');
45 define(
'EMAIL_ERROR_EXTRA_EMAIL',
'EMAIL_ERROR_EXTRA_EMAIL');
46 define(
'EMAIL_ERROR_DIFFERING_PARAMS',
'EMAIL_ERROR_DIFFERING_PARAMS');
49 define(
'LOCALE_COMPONENT_PKP_COMMON', 0x00000001);
50 define(
'LOCALE_COMPONENT_PKP_ADMIN', 0x00000002);
51 define(
'LOCALE_COMPONENT_PKP_INSTALLER', 0x00000003);
52 define(
'LOCALE_COMPONENT_PKP_MANAGER', 0x00000004);
53 define(
'LOCALE_COMPONENT_PKP_READER', 0x00000005);
54 define(
'LOCALE_COMPONENT_PKP_SUBMISSION', 0x00000006);
55 define(
'LOCALE_COMPONENT_PKP_USER', 0x00000007);
56 define(
'LOCALE_COMPONENT_PKP_GRID', 0x00000008);
57 define(
'LOCALE_COMPONENT_PKP_DEFAULT', 0x00000009);
58 define(
'LOCALE_COMPONENT_PKP_EDITOR', 0x0000000A);
59 define(
'LOCALE_COMPONENT_PKP_REVIEWER', 0x0000000B);
60 define(
'LOCALE_COMPONENT_PKP_API', 0x0000000C);
63 define(
'LOCALE_COMPONENT_APP_COMMON', 0x00000100);
64 define(
'LOCALE_COMPONENT_APP_MANAGER', 0x00000101);
65 define(
'LOCALE_COMPONENT_APP_SUBMISSION', 0x00000102);
66 define(
'LOCALE_COMPONENT_APP_AUTHOR', 0x00000103);
67 define(
'LOCALE_COMPONENT_APP_EDITOR', 0x00000104);
68 define(
'LOCALE_COMPONENT_APP_ADMIN', 0x00000105);
69 define(
'LOCALE_COMPONENT_APP_DEFAULT', 0x00000106);
70 define(
'LOCALE_COMPONENT_APP_API', 0x00000107);
71 define(
'LOCALE_COMPONENT_APP_EMAIL', 0x00000108);
81 static $supportedLocales;
82 if (!isset($supportedLocales)) {
83 if (defined(
'SESSION_DISABLE_INIT')) {
85 } elseif (($context = self::$request->getContext())) {
86 $supportedLocales = $context->getSupportedLocaleNames();
88 $site = self::$request->getSite();
89 $supportedLocales = $site->getSupportedLocaleNames();
92 return $supportedLocales;
100 static $supportedFormLocales;
101 if (!isset($supportedFormLocales)) {
102 if (defined(
'SESSION_DISABLE_INIT')) {
104 } elseif (($context = self::$request->getContext())) {
105 $supportedFormLocales = $context->getSupportedFormLocaleNames();
107 $site = self::$request->getSite();
108 $supportedFormLocales = $site->getSupportedLocaleNames();
111 return $supportedFormLocales;
120 static $currentLocale;
121 if (!isset($currentLocale)) {
122 if (defined(
'SESSION_DISABLE_INIT')) {
126 $locale = self::$request->getUserVar(
'setLocale');
130 $session = $sessionManager->getUserSession();
131 $locale = self::$request->getUserVar(
'uiLocale');
133 $context = self::$request->getContext();
134 $site = self::$request->getSite();
136 if (!isset($locale)) {
137 $locale = $session->getSessionVar(
'currentLocale');
140 if (!isset($locale)) {
141 $locale = self::$request->getCookieVar(
'currentLocale');
144 if (isset($locale)) {
146 if ($context !=
null) {
147 $locales = $context->getSupportedLocaleNames();
149 $locales = $site->getSupportedLocaleNames();
152 if (!in_array($locale, array_keys($locales))) {
157 if (!isset($locale)) {
159 if ($context !=
null) {
160 $locale = $context->getPrimaryLocale();
163 if (!isset($locale)) {
164 $locale = $site->getPrimaryLocale();
170 $locale = LOCALE_DEFAULT;
173 $currentLocale = $locale;
175 return $currentLocale;
183 static $localePrecedence;
184 if (!isset($localePrecedence)) {
187 $context = self::$request->getContext();
188 if ($context && !in_array($context->getPrimaryLocale(), $localePrecedence)) $localePrecedence[] = $context->getPrimaryLocale();
190 $site = self::$request->getSite();
191 if ($site && !in_array($site->getPrimaryLocale(), $localePrecedence)) $localePrecedence[] = $site->getPrimaryLocale();
193 return $localePrecedence;
202 if ($locale)
return $locale;
204 if (defined(
'SESSION_DISABLE_INIT'))
return $locale = LOCALE_DEFAULT;
206 $context = self::$request->getContext();
208 if (isset($context)) {
209 $locale = $context->getPrimaryLocale();
212 if (!isset($locale)) {
213 $site = self::$request->getSite();
214 $locale = $site->getPrimaryLocale();
218 $locale = LOCALE_DEFAULT;
231 if ($locale !==
null) {
232 if (!isset($localeFiles[$locale])) $localeFiles[$locale] = array();
233 return $localeFiles[$locale];
244 return '##' . htmlentities($key) .
'##';
257 static function translate($key, $params = array(), $locale =
null, $missingKeyHandler = array(__CLASS__,
'addOctothorpes')) {
259 if (($key = trim($key)) ==
'')
return '';
263 for ($i = count($localeFiles) - 1 ; $i >= 0 ; $i --) {
264 $value = $localeFiles[$i]->translate($key, $params);
265 if ($value !==
null)
return $value;
270 $notes[] = array(
'debug.notes.missingLocaleKey', array(
'key' => $key));
272 if (!
HookRegistry::call(
'PKPLocale::translate', array(&$key, &$params, &$locale, &$localeFiles, &$value))) {
274 return $missingKeyHandler($key);
289 setlocale(LC_ALL, $locale .
'.' . LOCALE_ENCODING, $locale);
290 putenv(
"LC_ALL=$locale");
299 date_default_timezone_set($timeZone);
304 $now =
new DateTime();
305 $mins = $now->getOffset() / 60;
306 $sgn = ($mins < 0 ? -1 : 1);
308 $hrs = floor($mins / 60);
310 $offset = sprintf(
'%+d:%02d', $hrs*$sgn, $mins);
313 $dbconn =& $conn->getDBConn();
314 switch($conn->getDriver()) {
317 $dbconn->execute(
'SET time_zone = \''.$offset.
'\'');
324 $dbconn->execute(
'SET TIME ZONE INTERVAL \''.$offset.
'\' HOUR TO MINUTE
');
326 default: assert(false);
337 static function makeComponentMap($locale) {
338 $baseDir = "lib/pkp/locale/$locale/";
341 LOCALE_COMPONENT_PKP_COMMON => $baseDir . 'common.po
',
342 LOCALE_COMPONENT_PKP_ADMIN => $baseDir . 'admin.po
',
343 LOCALE_COMPONENT_PKP_INSTALLER => $baseDir . 'installer.po
',
344 LOCALE_COMPONENT_PKP_MANAGER => $baseDir . 'manager.po
',
345 LOCALE_COMPONENT_PKP_READER => $baseDir . 'reader.po
',
346 LOCALE_COMPONENT_PKP_SUBMISSION => $baseDir . 'submission.po
',
347 LOCALE_COMPONENT_PKP_EDITOR => $baseDir . 'editor.po
',
348 LOCALE_COMPONENT_PKP_REVIEWER => $baseDir . 'reviewer.po
',
349 LOCALE_COMPONENT_PKP_USER => $baseDir . 'user.po
',
350 LOCALE_COMPONENT_PKP_GRID => $baseDir . 'grid.po
',
351 LOCALE_COMPONENT_PKP_DEFAULT => $baseDir . 'default.po
',
352 LOCALE_COMPONENT_PKP_API => $baseDir . 'api.po
',
361 static function getFilenameComponentMap($locale) {
362 $filenameComponentMap =& Registry::get('localeFilenameComponentMap
', true, array());
363 if (!isset($filenameComponentMap[$locale])) {
364 $filenameComponentMap[$locale] = AppLocale::makeComponentMap($locale);
366 return $filenameComponentMap[$locale];
374 static function requireComponents() {
375 $params = func_get_args();
377 $paramCount = count($params);
378 if ($paramCount === 0) return;
381 $lastParam = $params[$paramCount-1];
382 if (is_string($lastParam)) {
383 $locale = $lastParam;
386 $locale = AppLocale::getLocale();
389 // Backwards compatibility: the list used to be supplied
390 // as an array in the first parameter.
391 if (is_array($params[0])) {
392 $params = $params[0];
393 $paramCount = count($params);
396 // Go through and make sure each component is loaded if valid.
397 $loadedComponents =& Registry::get('loadedLocaleComponents
', true, array());
398 $filenameComponentMap = AppLocale::getFilenameComponentMap($locale);
399 for ($i=0; $i<$paramCount; $i++) {
400 $component = $params[$i];
402 // Don't load components twice
403 if (isset($loadedComponents[$locale][$component]))
continue;
406 if (!isset($filenameComponentMap[$component])) {
407 fatalError(
'Unknown locale component ' . $component);
410 $filename = $filenameComponentMap[$component];
412 $loadedComponents[$locale][$component] =
true;
425 $localeFile =
new LocaleFile($locale, $filename);
427 if (!
HookRegistry::call(
'PKPLocale::registerLocaleFile::isValidLocaleFile', array(&$localeFile))) {
428 if (!$localeFile->isValid())
return null;
432 array_unshift($localeFiles,
'');
433 $localeFiles[0] =& $localeFile;
435 $localeFiles[] =& $localeFile;
437 HookRegistry::call(
'PKPLocale::registerLocaleFile', array(&$locale, &$filename, &$addToTop));
448 if (isset($contents[$locale][
'stylesheet'])) {
449 return $contents[$locale][
'stylesheet'];
467 if (isset($contents[$locale][
'direction'])) {
468 return $contents[$locale][
'direction'];
480 if (!isset($contents[$locale]))
return false;
481 if (isset($contents[$locale][
'complete']) && $contents[$locale][
'complete'] ==
'false') {
494 if (isset($contents[$locale]) && isset($contents[$locale][
'familyFirst']) && $contents[$locale][
'familyFirst'] ==
'true') {
506 if (empty($locale))
return false;
508 if (!preg_match(
'/^[a-z][a-z]_[A-Z][A-Z](@([A-Za-z0-9]{5,8}|\d[A-Za-z0-9]{3}))?$/', $locale))
return false;
509 if (file_exists(
'locale/' . $locale))
return true;
520 $data = $xmlDao->parseStruct($filename, array(
'locale'));
521 $allLocales = array();
524 if (isset($data[
'locale'])) {
525 foreach ($data[
'locale'] as $localeData) {
526 $allLocales[$localeData[
'attributes'][
'key']] = $localeData[
'attributes'];
539 $allLocales = array();
541 foreach ($rawContents as $locale => $contents) {
542 $allLocales[$locale] = $contents[
'name'];
546 if (LOCALE_ENCODING ==
"iso-8859-1") {
547 $allLocales = array_map(
'utf8_decode', $allLocales);
559 import(
'lib.pkp.classes.db.DBDataXMLParser');
563 $emailTemplateDao->installEmailTemplateLocaleData($emailTemplateDao->getMainEmailTemplatesFilename(), array($locale));
567 foreach ($categories as $category) {
580 $emailTemplateDao->deleteEmailTemplatesByLocale($locale);
581 $emailTemplateDao->deleteDefaultEmailTemplatesByLocale($locale);
602 array_shift($matches);
603 if (isset($matches[0]))
return $matches[0];
615 assert(strlen($iso2Letter) == 2);
617 foreach($locales as $locale => $localeData) {
618 if (substr($locale, 0, 2) == $iso2Letter) {
619 assert(isset($localeData[
'iso639-2b']));
620 return $localeData[
'iso639-2b'];
634 assert(strlen($iso3Letter) == 3);
636 foreach($locales as $locale => $localeData) {
637 assert(isset($localeData[
'iso639-2b']));
638 if ($localeData[
'iso639-2b'] == $iso3Letter) {
639 return substr($locale, 0, 2);
652 assert(strlen($locale) >= 5);
653 $iso2Letter = substr($locale, 0, 2);
672 assert(strlen($iso3Letter) == 3);
675 $localeCandidates = array();
677 foreach($locales as $locale => $localeData) {
678 assert(isset($localeData[
'iso639-2b']));
679 if ($localeData[
'iso639-2b'] == $iso3Letter) {
680 if ($locale == $primaryLocale) {
683 return $primaryLocale;
685 $localeCandidates[] = $locale;
690 if (empty($localeCandidates))
return null;
692 if (count($localeCandidates) > 1) {
697 foreach($supportedLocales as $supportedLocale => $localeName) {
698 if (in_array($supportedLocale, $localeCandidates))
return $supportedLocale;
705 return array_shift($localeCandidates);
715 assert(strlen($iso1) == 2);
717 foreach($locales as $locale => $localeData) {
718 if (substr($locale, 0, 2) == $iso1) {
719 assert(isset($localeData[
'iso639-3']));
720 return $localeData[
'iso639-3'];
733 assert(strlen($iso3) == 3);
735 foreach($locales as $locale => $localeData) {
736 assert(isset($localeData[
'iso639-3']));
737 if ($localeData[
'iso639-3'] == $iso3) {
738 return substr($locale, 0, 2);
751 assert(strlen($locale) >= 5);
752 $iso1 = substr($locale, 0, 2);
763 assert(strlen($locale) >= 5);
764 return substr($locale, 0, 2);
782 assert(strlen($iso3) == 3);
785 $localeCandidates = array();
787 foreach($locales as $locale => $localeData) {
788 assert(isset($localeData[
'iso639-3']));
789 if ($localeData[
'iso639-3'] == $iso3) {
790 if ($locale == $primaryLocale) {
793 return $primaryLocale;
795 $localeCandidates[] = $locale;
800 if (empty($localeCandidates))
return null;
802 if (count($localeCandidates) > 1) {
807 foreach($supportedLocales as $supportedLocale => $localeName) {
808 if (in_array($supportedLocale, $localeCandidates))
return $supportedLocale;
815 return array_shift($localeCandidates);
826 static $contents =
false;
827 if ($contents ===
false) {
829 $contents = $allLocalesCache->getContents();
840 if ($cache ===
null) {
842 $cache = $cacheManager->getFileCache(
844 array(
'AppLocale',
'_allLocalesCacheMiss')
848 $cacheTime = $cache->getCacheTime();
849 if ($cacheTime !==
null && $cacheTime < filemtime(LOCALE_REGISTRY_FILE)) {
863 if ($allLocales ===
null) {
866 $notes[] = array(
'debug.notes.localeListLoad', array(
'localeList' => LOCALE_REGISTRY_FILE));
871 $cache->setEntireCache($allLocales);
886 $timeZoneList = $timeZoneDAO->getTimeZones();
887 foreach ($timeZoneList as $timeZoneKey => $timeZoneName) {
888 if (in_array($timeZoneConfig, array($timeZoneKey, $timeZoneName))) {
889 $timeZone = $timeZoneKey;
896 if (empty($timeZone)) $timeZone = ini_get(
'date.timezone');
899 if (empty($timeZone)) $timeZone =
'UTC';
923 function __($key, $params = array(), $locale =
null, $missingKeyHandler = array(
'PKPLocale',
'addOctothorpes')) {