00001 <?php
00002
00019
00020
00021
00022 import('i18n.LocaleFile');
00023
00024 define('LOCALE_REGISTRY_FILE', Config::getVar('general', 'registry_dir') . DIRECTORY_SEPARATOR . 'locales.xml');
00025 define('LOCALE_DEFAULT', Config::getVar('i18n', 'locale'));
00026 define('LOCALE_ENCODING', Config::getVar('i18n', 'client_charset'));
00027
00028 define('MASTER_LOCALE', 'en_US');
00029
00030
00031
00032
00033 define('LOCALE_ERROR_MISSING_KEY', 'LOCALE_ERROR_MISSING_KEY');
00034 define('LOCALE_ERROR_EXTRA_KEY', 'LOCALE_ERROR_EXTRA_KEY');
00035 define('LOCALE_ERROR_SUSPICIOUS_LENGTH', 'LOCALE_ERROR_SUSPICIOUS_LENGTH');
00036 define('LOCALE_ERROR_DIFFERING_PARAMS', 'LOCALE_ERROR_DIFFERING_PARAMS');
00037 define('LOCALE_ERROR_MISSING_FILE', 'LOCALE_ERROR_MISSING_FILE');
00038
00039 define('EMAIL_ERROR_MISSING_EMAIL', 'EMAIL_ERROR_MISSING_EMAIL');
00040 define('EMAIL_ERROR_EXTRA_EMAIL', 'EMAIL_ERROR_EXTRA_EMAIL');
00041 define('EMAIL_ERROR_DIFFERING_PARAMS', 'EMAIL_ERROR_DIFFERING_PARAMS');
00042
00043 class Locale {
00049 function &getLocaleFiles($locale = null) {
00050 static $localeFiles;
00051 if (!isset($localeFiles)) {
00052 $localeFiles = array();
00053 }
00054
00055 if ($locale !== null) {
00056 if (!isset($localeFiles[$locale])) $localeFiles[$locale] = array();
00057 return $localeFiles[$locale];
00058 }
00059 return $localeFiles;
00060 }
00061
00071 function translate($key, $params = array(), $locale = null) {
00072 if (!isset($locale)) $locale = Locale::getLocale();
00073 if (($key = trim($key)) == '') return '';
00074
00075 $localeFiles =& Locale::getLocaleFiles($locale);
00076 $value = '';
00077 for ($i = 0; $i < count($localeFiles); $i++) {
00078 $value = $localeFiles[$i]->translate($key, $params);
00079 if ($value !== null) return $value;
00080 }
00081
00082
00083 $notes =& Registry::get('system.debug.notes');
00084 $notes[] = array('debug.notes.missingLocaleKey', array('key' => $key));
00085
00086
00087 return '##' . $key . '##';
00088 }
00089
00093 function getMainLocaleFilename($locale) {
00094 return "locale/$locale/locale.xml";
00095 }
00096
00100 function initialize() {
00101
00102 $locale = Locale::getLocale();
00103 $localeFile = Locale::getMainLocaleFilename($locale);
00104
00105 $sysLocale = $locale . '.' . LOCALE_ENCODING;
00106 if (!@setlocale(LC_ALL, $sysLocale, $locale)) {
00107
00108 if(setlocale(LC_ALL, $sysLocale) != $sysLocale) {
00109 setlocale(LC_ALL, $locale);
00110 }
00111 }
00112
00113 Locale::registerLocaleFile($locale, $localeFile);
00114 }
00115
00123 function ®isterLocaleFile ($locale, $filename, $addToTop = false) {
00124 $localeFiles =& Locale::getLocaleFiles($locale);
00125 $localeFile =& new LocaleFile($locale, $filename);
00126 if (!$localeFile->isValid()) {
00127 $localeFile = null;
00128 return $localeFile;
00129 }
00130 if ($addToTop) {
00131
00132 array_unshift($localeFiles, '');
00133 $localeFiles[0] =& $localeFile;
00134 } else {
00135 $localeFiles[] =& $localeFile;
00136 }
00137 return $localeFile;
00138 }
00139
00144 function getSupportedLocales() {
00145 static $supportedLocales;
00146 if (!isset($supportedLocales)) {
00147 if (defined('SESSION_DISABLE_INIT') || !Config::getVar('general', 'installed')) {
00148 $supportedLocales = Locale::getAllLocales();
00149 } elseif (($journal =& Request::getJournal())) {
00150 $supportedLocales = $journal->getSupportedLocaleNames();
00151 } else {
00152 $site =& Request::getSite();
00153 $supportedLocales = $site->getSupportedLocaleNames();
00154 }
00155 }
00156 return $supportedLocales;
00157 }
00158
00164 function getLocale() {
00165 static $currentLocale;
00166 if (!isset($currentLocale)) {
00167 if (defined('SESSION_DISABLE_INIT') || !Config::getVar('general', 'installed')) {
00168
00169
00170
00171 $locale = Request::getUserVar('setLocale');
00172 if (empty($locale) || !in_array($locale, Locale::getSupportedLocales())) $locale = Request::getCookieVar('currentLocale');
00173 } else {
00174 $sessionManager = &SessionManager::getManager();
00175 $session = &$sessionManager->getUserSession();
00176 $locale = $session->getSessionVar('currentLocale');
00177
00178 $journal = &Request::getJournal();
00179 $site = &Request::getSite();
00180
00181 if (!isset($locale)) {
00182 $locale = Request::getCookieVar('currentLocale');
00183 }
00184
00185 if (isset($locale)) {
00186
00187 if ($journal != null) {
00188 $locales = &$journal->getSupportedLocaleNames();
00189 } else {
00190 $locales = &$site->getSupportedLocaleNames();
00191 }
00192
00193 if (!in_array($locale, array_keys($locales))) {
00194 unset($locale);
00195 }
00196 }
00197
00198 if (!isset($locale)) {
00199
00200 if ($journal != null) {
00201 $locale = $journal->getPrimaryLocale();
00202 }
00203
00204 if (!isset($locale)) {
00205 $locale = $site->getPrimaryLocale();
00206 }
00207 }
00208 }
00209
00210 if (!Locale::isLocaleValid($locale)) {
00211 $locale = LOCALE_DEFAULT;
00212 }
00213
00214 $currentLocale = $locale;
00215 }
00216 return $currentLocale;
00217 }
00218
00219 function getLocaleStyleSheet($locale) {
00220 $allLocales =& Locale::_getAllLocalesCache();
00221 $contents = $allLocales->getContents();
00222 if (isset($contents[$locale]['stylesheet'])) {
00223 return $contents[$locale]['stylesheet'];
00224 }
00225 return null;
00226 }
00227
00233 function isLocaleValid($locale) {
00234 if (empty($locale)) return false;
00235 if (!preg_match('/^[a-z][a-z]_[A-Z][A-Z]$/', $locale)) return false;
00236 if (file_exists(Locale::getMainLocaleFilename($locale))) return true;
00237 return false;
00238 }
00239
00244 function getLocalePrecedence() {
00245 static $localePrecedence;
00246 if (!isset($localePrecedence)) {
00247 $localePrecedence = array(Locale::getLocale());
00248
00249 $journal =& Request::getJournal();
00250 if ($journal && !in_array($journal->getPrimaryLocale(), $localePrecedence)) $localePrecedence[] = $journal->getPrimaryLocale();
00251
00252 $site =& Request::getSite();
00253 if ($site && !in_array($site->getPrimaryLocale(), $localePrecedence)) $localePrecedence[] = $site->getPrimaryLocale();
00254 }
00255 return $localePrecedence;
00256 }
00257
00262 function getPrimaryLocale() {
00263 $journal = &Request::getJournal();
00264
00265 if (isset($journal)) {
00266 $locale = $journal->getPrimaryLocale();
00267 }
00268
00269 if (!isset($locale)) {
00270 $site = &Request::getSite();
00271 $locale = $site->getPrimaryLocale();
00272 }
00273
00274 if (!isset($locale) || !Locale::isLocaleValid($locale)) {
00275 $locale = LOCALE_DEFAULT;
00276 }
00277
00278 return $locale;
00279 }
00280
00284 function &_getAllLocalesCache() {
00285 static $cache;
00286 if (!isset($cache)) {
00287 import('cache.CacheManager');
00288 $cacheManager =& CacheManager::getManager();
00289 $cache = $cacheManager->getFileCache(
00290 'locale', 'list',
00291 array('Locale', '_allLocalesCacheMiss')
00292 );
00293
00294
00295 $cacheTime = $cache->getCacheTime();
00296 if ($cacheTime !== null && $cacheTime < filemtime(LOCALE_REGISTRY_FILE)) {
00297 $cache->flush();
00298 }
00299 }
00300 return $cache;
00301 }
00302
00308 function &loadLocaleList($filename) {
00309 $xmlDao = &new XMLDAO();
00310 $data = $xmlDao->parseStruct($filename, array('locale'));
00311 $allLocales = array();
00312
00313
00314 if (isset($data['locale'])) {
00315 foreach ($data['locale'] as $localeData) {
00316 $allLocales[$localeData['attributes']['key']] = $localeData['attributes'];
00317 }
00318 }
00319
00320 return $allLocales;
00321 }
00322
00323 function _allLocalesCacheMiss(&$cache, $id) {
00324 static $allLocales;
00325 if (!isset($allLocales)) {
00326
00327 $notes =& Registry::get('system.debug.notes');
00328 $notes[] = array('debug.notes.localeListLoad', array('localeList' => LOCALE_REGISTRY_FILE));
00329
00330
00331 $allLocales = Locale::loadLocaleList(LOCALE_REGISTRY_FILE);
00332 asort($allLocales);
00333 $cache->setEntireCache($allLocales);
00334 }
00335 return null;
00336 }
00337
00342 function &getAllLocales() {
00343 $cache =& Locale::_getAllLocalesCache();
00344 $rawContents = $cache->getContents();
00345 $allLocales = array();
00346
00347 foreach ($rawContents as $locale => $contents) {
00348 $allLocales[$locale] = $contents['name'];
00349 }
00350
00351
00352 if (LOCALE_ENCODING == "iso-8859-1") {
00353 $allLocales = array_map('utf8_decode', $allLocales);
00354 }
00355
00356 return $allLocales;
00357 }
00358
00365 function getEmailTemplateFilename($locale) {
00366 return 'dbscripts/xml/data/locale/' . $locale . '/email_templates_data.xml';
00367 }
00368
00369 function getFilesToInstall($locale) {
00370 return array(
00371 Locale::getEmailTemplateFilename($locale)
00372 );
00373 }
00374
00379 function installLocale($locale) {
00380
00381 import('db.DBDataXMLParser');
00382
00383 $filesToInstall = Locale::getFilesToInstall($locale);
00384
00385 $dataXMLParser = &new DBDataXMLParser();
00386 foreach ($filesToInstall as $fileName) {
00387 if (file_exists($fileName)) {
00388 $sql = $dataXMLParser->parseData($fileName);
00389 $dataXMLParser->executeData();
00390 }
00391 }
00392 $dataXMLParser->destroy();
00393 }
00394
00399 function uninstallLocale($locale) {
00400
00401 $emailTemplateDao = &DAORegistry::getDAO('EmailTemplateDAO');
00402 $emailTemplateDao->deleteEmailTemplatesByLocale($locale);
00403 $emailTemplateDao->deleteDefaultEmailTemplatesByLocale($locale);
00404 }
00405
00410 function reloadLocale($locale) {
00411 Locale::uninstallLocale($locale);
00412 Locale::installLocale($locale);
00413 }
00414
00422 function testLocale($locale, $referenceLocale) {
00423 $localeFile =& new LocaleFile($locale, Locale::getMainLocaleFilename($locale));
00424 $referenceLocaleFile =& new LocaleFile($referenceLocale, Locale::getMainLocaleFilename($referenceLocale));
00425
00426 $errors = $localeFile->testLocale($referenceLocaleFile);
00427 unset($localeFile);
00428 unset($referenceLocaleFile);
00429
00430 $plugins =& PluginRegistry::loadAllPlugins();
00431 foreach (array_keys($plugins) as $key) {
00432 $plugin =& $plugins[$key];
00433 $referenceLocaleFilename = $plugin->getLocaleFilename($referenceLocale);
00434 if ($referenceLocaleFilename) {
00435 $localeFile =& new LocaleFile($locale, $plugin->getLocaleFilename($locale));
00436 $referenceLocaleFile =& new LocaleFile($referenceLocale, $referenceLocaleFilename);
00437 $errors = array_merge_recursive($errors, $localeFile->testLocale($referenceLocaleFile));
00438 unset($localeFile);
00439 unset($referenceLocaleFile);
00440 }
00441 unset($plugin);
00442 }
00443 return $errors;
00444 }
00445
00453 function testEmails($locale, $referenceLocale) {
00454 $errors = array(
00455 );
00456
00457 $xmlParser =& new XMLParser();
00458 $referenceEmails =& $xmlParser->parse(Locale::getEmailTemplateFilename($referenceLocale));
00459 $emails =& $xmlParser->parse(Locale::getEmailTemplateFilename($locale));
00460 $emailsTable =& $emails->getChildByName('table');
00461 $referenceEmailsTable =& $referenceEmails->getChildByName('table');
00462 $matchedReferenceEmails = array();
00463
00464
00465
00466 for ($emailIndex = 0; ($email =& $emailsTable->getChildByName('row', $emailIndex)) !== null; $emailIndex++) {
00467
00468 $fields = Locale::extractFields($email);
00469
00470
00471 for ($referenceEmailIndex = 0; ($referenceEmail =& $referenceEmailsTable->getChildByName('row', $referenceEmailIndex)) !== null; $referenceEmailIndex++) {
00472 $referenceFields = Locale::extractFields($referenceEmail);
00473 if ($referenceFields['email_key'] == $fields['email_key']) break;
00474 }
00475
00476
00477 if (!isset($referenceEmail) || $referenceEmail === null) {
00478 $errors[EMAIL_ERROR_EXTRA_EMAIL][] = array(
00479 'key' => $fields['email_key']
00480 );
00481 continue;
00482 }
00483
00484
00485
00486 $bodyParams = Locale::getParameterNames($fields['body']);
00487 $referenceBodyParams = Locale::getParameterNames($referenceFields['body']);
00488 $diff = array_diff($bodyParams, $referenceBodyParams);
00489 if (!empty($diff)) {
00490 $errors[EMAIL_ERROR_DIFFERING_PARAMS][] = array(
00491 'key' => $fields['email_key'],
00492 'mismatch' => $diff
00493 );
00494 }
00495
00496 $subjectParams = Locale::getParameterNames($fields['subject']);
00497 $referenceSubjectParams = Locale::getParameterNames($referenceFields['subject']);
00498
00499 $diff = array_diff($subjectParams, $referenceSubjectParams);
00500 if (!empty($diff)) {
00501 $errors[EMAIL_ERROR_DIFFERING_PARAMS][] = array(
00502 'key' => $fields['email_key'],
00503 'mismatch' => $diff
00504 );
00505 }
00506
00507 $matchedReferenceEmails[] = $fields['email_key'];
00508
00509 unset($email);
00510 unset($referenceEmail);
00511 }
00512
00513
00514 for ($referenceEmailIndex = 0; ($referenceEmail =& $referenceEmailsTable->getChildByName('row', $referenceEmailIndex)) !== null; $referenceEmailIndex++) {
00515
00516 $referenceFields = Locale::extractFields($referenceEmail);
00517 if (!in_array($referenceFields['email_key'], $matchedReferenceEmails)) {
00518 $errors[EMAIL_ERROR_MISSING_EMAIL][] = array(
00519 'key' => $referenceFields['email_key']
00520 );
00521 }
00522 }
00523
00524 return $errors;
00525 }
00526
00534 function extractFields(&$node) {
00535 $returner = array();
00536 foreach ($node->getChildren() as $field) if ($field->getName() === 'field') {
00537 $returner[$field->getAttribute('name')] = $field->getValue();
00538 }
00539 return $returner;
00540 }
00541
00549 function checkLengths($reference, $value) {
00550 $referenceLength = String::strlen($reference);
00551 $length = String::strlen($value);
00552 $lengthDifference = abs($referenceLength - $length);
00553 if ($referenceLength == 0) return ($length == 0);
00554 if ($lengthDifference / $referenceLength > 1 && $lengthDifference > 10) return false;
00555 return true;
00556 }
00557
00564 function getParameterNames($source) {
00565 $matches = null;
00566 String::regexp_match_all('/({\$[^}]+})/' , $source, $matches);
00567 array_shift($matches);
00568 return $matches;
00569 }
00570 }
00571
00572 ?>