<?php
define('LOCALE_LANGUAGE_NEGOTIATION_URL', 'locale-url');
define('LOCALE_LANGUAGE_NEGOTIATION_BROWSER', 'locale-browser');
define('LOCALE_LANGUAGE_NEGOTIATION_INTERFACE', 'locale-interface');
define('LOCALE_LANGUAGE_NEGOTIATION_URL_FALLBACK', 'locale-url-fallback');
define('LOCALE_LANGUAGE_NEGOTIATION_USER', 'locale-user');
define('LOCALE_LANGUAGE_NEGOTIATION_SESSION', 'locale-session');
define('LOCALE_JS_STRING', '(?:(?:\'(?:\\\\\'|[^\'])*\'|"(?:\\\\"|[^"])*")(?:\\s*\\+\\s*)?)+');
define('LOCALE_JS_OBJECT', '\\{.*?\\}');
define('LOCALE_JS_OBJECT_CONTEXT', '
\\{ # match object literal start
.*? # match anything, non-greedy
(?: # match a form of "context"
\'context\'
|
"context"
|
context
)
\\s*:\\s* # match key-value separator ":"
(' . LOCALE_JS_STRING . ') # match context string
.*? # match anything, non-greedy
\\} # match end of object literal
');
define('LOCALE_IMPORT_OVERWRITE', 0);
define('LOCALE_IMPORT_KEEP', 1);
define('LOCALE_LANGUAGE_NEGOTIATION_URL_PREFIX', 0);
define('LOCALE_LANGUAGE_NEGOTIATION_URL_DOMAIN', 1);
function locale_language_from_interface() {
global $language;
return isset($language->language) ? $language->language : FALSE;
}
function locale_language_from_browser($languages) {
if (empty($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
return FALSE;
}
$browser_langcodes = array();
if (preg_match_all('@(?<=[, ]|^)([a-zA-Z-]+|\\*)(?:;q=([0-9.]+))?(?:$|\\s*,\\s*)@', trim($_SERVER['HTTP_ACCEPT_LANGUAGE']), $matches, PREG_SET_ORDER)) {
foreach ($matches as $match) {
$langcode = strtolower($match[1]);
$qvalue = isset($match[2]) ? (double) $match[2] : 1;
$browser_langcodes[$langcode] = (int) ($qvalue * 1000);
}
}
asort($browser_langcodes);
foreach ($browser_langcodes as $langcode => $qvalue) {
$generic_tag = strtok($langcode, '-');
if (!isset($browser_langcodes[$generic_tag])) {
$browser_langcodes[$generic_tag] = $qvalue;
}
}
$best_match_langcode = FALSE;
$max_qvalue = 0;
foreach ($languages as $langcode => $language) {
$langcode = strtolower($langcode);
$qvalue = isset($browser_langcodes['*']) ? $browser_langcodes['*'] : 0;
$prefix = $langcode;
do {
if (isset($browser_langcodes[$prefix])) {
$qvalue = $browser_langcodes[$prefix];
break;
}
} while ($prefix = substr($prefix, 0, strrpos($prefix, '-')));
if ($qvalue > $max_qvalue) {
$best_match_langcode = $language->language;
$max_qvalue = $qvalue;
}
}
return $best_match_langcode;
}
function locale_language_from_user($languages) {
global $user;
if ($user->uid) {
return $user->language;
}
return FALSE;
}
function locale_language_from_session($languages) {
$param = variable_get('locale_language_negotiation_session_param', 'language');
if (isset($_GET[$param]) && isset($languages[$langcode = $_GET[$param]])) {
global $user;
if ($user->uid) {
$_SESSION[$param] = $langcode;
}
return $langcode;
}
if (isset($_SESSION[$param])) {
return $_SESSION[$param];
}
return FALSE;
}
function locale_language_from_url($languages) {
$language_url = FALSE;
if (!language_negotiation_get_any(LOCALE_LANGUAGE_NEGOTIATION_URL)) {
return $language_url;
}
switch (variable_get('locale_language_negotiation_url_part', LOCALE_LANGUAGE_NEGOTIATION_URL_PREFIX)) {
case LOCALE_LANGUAGE_NEGOTIATION_URL_PREFIX:
list($language, $_GET['q']) = language_url_split_prefix(isset($_GET['q']) ? $_GET['q'] : NULL, $languages);
if ($language !== FALSE) {
$language_url = $language->language;
}
break;
case LOCALE_LANGUAGE_NEGOTIATION_URL_DOMAIN:
$http_host = $_SERVER['HTTP_HOST'];
if (strpos($http_host, ':') !== FALSE) {
$http_host_tmp = explode(':', $http_host);
$http_host = current($http_host_tmp);
}
foreach ($languages as $language) {
if ($language->domain) {
$host = 'http://' . str_replace(array(
'http://',
'https://',
), '', $language->domain);
$host = parse_url($host, PHP_URL_HOST);
if ($http_host == $host) {
$language_url = $language->language;
break;
}
}
}
break;
}
return $language_url;
}
function locale_language_url_fallback($language = NULL, $language_type = LANGUAGE_TYPE_INTERFACE) {
$default = language_default();
$prefix = variable_get('locale_language_negotiation_url_part', LOCALE_LANGUAGE_NEGOTIATION_URL_PREFIX) == LOCALE_LANGUAGE_NEGOTIATION_URL_PREFIX;
if ($prefix && empty($default->prefix) || !$prefix && empty($default->domain)) {
return $default->language;
}
else {
return $GLOBALS[$language_type]->language;
}
}
function locale_language_switcher_url($type, $path) {
$languages = language_list('enabled');
$links = array();
foreach ($languages[1] as $language) {
$links[$language->language] = array(
'href' => $path,
'title' => $language->native,
'language' => $language,
'attributes' => array(
'class' => array(
'language-link',
),
),
);
}
return $links;
}
function locale_language_switcher_session($type, $path) {
drupal_add_css(drupal_get_path('module', 'locale') . '/locale.css');
$param = variable_get('locale_language_negotiation_session_param', 'language');
$language_query = isset($_SESSION[$param]) ? $_SESSION[$param] : $GLOBALS[$type]->language;
$languages = language_list('enabled');
$links = array();
$query = $_GET;
unset($query['q']);
foreach ($languages[1] as $language) {
$langcode = $language->language;
$links[$langcode] = array(
'href' => $path,
'title' => $language->native,
'attributes' => array(
'class' => array(
'language-link',
),
),
'query' => $query,
);
if ($language_query != $langcode) {
$links[$langcode]['query'][$param] = $langcode;
}
else {
$links[$langcode]['attributes']['class'][] = 'session-active';
}
}
return $links;
}
function locale_language_url_rewrite_url(&$path, &$options) {
static $drupal_static_fast;
if (!isset($drupal_static_fast)) {
$drupal_static_fast['languages'] =& drupal_static(__FUNCTION__);
}
$languages =& $drupal_static_fast['languages'];
if (!isset($languages)) {
$languages = language_list('enabled');
$languages = array_flip(array_keys($languages[1]));
}
if (!isset($options['language'])) {
global $language_url;
$options['language'] = $language_url;
}
elseif (!isset($languages[$options['language']->language])) {
unset($options['language']);
return;
}
if (isset($options['language'])) {
switch (variable_get('locale_language_negotiation_url_part', LOCALE_LANGUAGE_NEGOTIATION_URL_PREFIX)) {
case LOCALE_LANGUAGE_NEGOTIATION_URL_DOMAIN:
if ($options['language']->domain) {
if (!empty($options['base_url'])) {
$normalized_base_url = str_replace(array(
'https://',
'http://',
), '', $options['base_url']);
}
global $is_https;
$url_scheme = $is_https ? 'https://' : 'http://';
$options['absolute'] = TRUE;
$host = 'http://' . str_replace(array(
'http://',
'https://',
), '', $options['language']->domain);
$host = parse_url($host, PHP_URL_HOST);
$options['base_url'] = $url_scheme . $host;
$http_host = $_SERVER['HTTP_HOST'];
if (isset($normalized_base_url) && strpos($normalized_base_url, ':') !== FALSE) {
list($host, $port) = explode(':', $normalized_base_url);
$options['base_url'] .= ':' . $port;
}
elseif (strpos($http_host, ':') !== FALSE) {
list($host, $port) = explode(':', $http_host);
$options['base_url'] .= ':' . $port;
}
if (isset($options['https']) && variable_get('https', FALSE)) {
if ($options['https'] === TRUE) {
$options['base_url'] = str_replace('http://', 'https://', $options['base_url']);
}
elseif ($options['https'] === FALSE) {
$options['base_url'] = str_replace('https://', 'http://', $options['base_url']);
}
}
}
break;
case LOCALE_LANGUAGE_NEGOTIATION_URL_PREFIX:
if (!empty($options['language']->prefix)) {
$options['prefix'] = $options['language']->prefix . '/';
}
break;
}
}
}
function locale_language_url_rewrite_session(&$path, &$options) {
static $query_rewrite, $query_param, $query_value;
if (!isset($query_rewrite)) {
global $user;
if (!$user->uid) {
$languages = language_list('enabled');
$languages = $languages[1];
$query_param = check_plain(variable_get('locale_language_negotiation_session_param', 'language'));
$query_value = isset($_GET[$query_param]) ? check_plain($_GET[$query_param]) : NULL;
$query_rewrite = isset($languages[$query_value]) && language_negotiation_get_any(LOCALE_LANGUAGE_NEGOTIATION_SESSION);
}
else {
$query_rewrite = FALSE;
}
}
if ($query_rewrite) {
if (is_string($options['query'])) {
$options['query'] = drupal_get_query_array($options['query']);
}
if (!isset($options['query'][$query_param])) {
$options['query'][$query_param] = $query_value;
}
}
}
function locale_string_is_safe($string) {
$string = preg_replace('/\\[[a-z0-9_-]+(:[a-z0-9_-]+)+\\]/i', '', $string);
return decode_entities($string) == decode_entities(filter_xss($string, array(
'a',
'abbr',
'acronym',
'address',
'b',
'bdo',
'big',
'blockquote',
'br',
'caption',
'cite',
'code',
'col',
'colgroup',
'dd',
'del',
'dfn',
'dl',
'dt',
'em',
'h1',
'h2',
'h3',
'h4',
'h5',
'h6',
'hr',
'i',
'ins',
'kbd',
'li',
'ol',
'p',
'pre',
'q',
'samp',
'small',
'span',
'strong',
'sub',
'sup',
'table',
'tbody',
'td',
'tfoot',
'th',
'thead',
'tr',
'tt',
'ul',
'var',
)));
}
function locale_add_language($langcode, $name = NULL, $native = NULL, $direction = LANGUAGE_LTR, $domain = '', $prefix = '', $enabled = TRUE, $default = FALSE) {
if (empty($prefix)) {
$prefix = $langcode;
}
if (!isset($name)) {
include_once DRUPAL_ROOT . '/includes/iso.inc';
$predefined = _locale_get_predefined_list();
$name = $predefined[$langcode][0];
$native = isset($predefined[$langcode][1]) ? $predefined[$langcode][1] : $predefined[$langcode][0];
$direction = isset($predefined[$langcode][2]) ? $predefined[$langcode][2] : LANGUAGE_LTR;
}
db_insert('languages')
->fields(array(
'language' => $langcode,
'name' => $name,
'native' => $native,
'direction' => $direction,
'domain' => $domain,
'prefix' => $prefix,
'enabled' => $enabled,
))
->execute();
if ($enabled && $default) {
variable_set('language_default', (object) array(
'language' => $langcode,
'name' => $name,
'native' => $native,
'direction' => $direction,
'enabled' => (int) $enabled,
'plurals' => 0,
'formula' => '',
'domain' => '',
'prefix' => $prefix,
'weight' => 0,
'javascript' => '',
));
}
if ($enabled) {
variable_set('language_count', variable_get('language_count', 1) + 1);
}
drupal_static_reset('language_list');
_locale_invalidate_js($langcode);
watchdog('locale', 'The %language language (%code) has been created.', array(
'%language' => $name,
'%code' => $langcode,
));
module_invoke_all('multilingual_settings_changed');
}
function _locale_import_po($file, $langcode, $mode, $group = NULL) {
if (!db_query("SELECT COUNT(language) FROM {languages} WHERE language = :language", array(
':language' => $langcode,
))
->fetchField()) {
drupal_set_message(t('The language selected for import is not supported.'), 'error');
return FALSE;
}
$status = _locale_import_read_po('db-store', $file, $mode, $langcode, $group);
if ($status === FALSE) {
return FALSE;
}
list($header_done, $additions, $updates, $deletes, $skips) = _locale_import_one_string('db-report');
if (!$header_done) {
drupal_set_message(t('The translation file %filename appears to have a missing or malformed header.', array(
'%filename' => $file->filename,
)), 'error');
}
_locale_invalidate_js($langcode);
cache_clear_all('locale:', 'cache', TRUE);
menu_rebuild();
drupal_set_message(t('The translation was successfully imported. There are %number newly created translated strings, %update strings were updated and %delete strings were removed.', array(
'%number' => $additions,
'%update' => $updates,
'%delete' => $deletes,
)));
watchdog('locale', 'Imported %file into %locale: %number new strings added, %update updated and %delete removed.', array(
'%file' => $file->filename,
'%locale' => $langcode,
'%number' => $additions,
'%update' => $updates,
'%delete' => $deletes,
));
if ($skips) {
$skip_message = format_plural($skips, 'One translation string was skipped because it contains disallowed HTML.', '@count translation strings were skipped because they contain disallowed HTML.');
drupal_set_message($skip_message);
watchdog('locale', '@count disallowed HTML string(s) in %file', array(
'@count' => $skips,
'%file' => $file->uri,
), WATCHDOG_WARNING);
}
return TRUE;
}
function _locale_import_read_po($op, $file, $mode = NULL, $lang = NULL, $group = 'default') {
$fd = fopen($file->uri, 'rb');
if (!$fd) {
_locale_import_message('The translation import failed, because the file %filename could not be read.', $file);
return FALSE;
}
$context = 'COMMENT';
$current = array();
$plural = 0;
$lineno = 0;
while (!feof($fd)) {
if (!($lineno % 10)) {
drupal_set_time_limit(30);
}
$line = fgets($fd, 10 * 1024);
if ($lineno == 0) {
$line = str_replace("", '', $line);
}
$lineno++;
$line = trim(strtr($line, array(
"\\\n" => "",
)));
if (!strncmp('#', $line, 1)) {
if ($context == 'COMMENT') {
$current['#'][] = substr($line, 1);
}
elseif ($context == 'MSGSTR' || $context == 'MSGSTR_ARR') {
_locale_import_one_string($op, $current, $mode, $lang, $file, $group);
$current = array();
$current['#'][] = substr($line, 1);
$context = 'COMMENT';
}
else {
_locale_import_message('The translation file %filename contains an error: "msgstr" was expected but not found on line %line.', $file, $lineno);
return FALSE;
}
}
elseif (!strncmp('msgid_plural', $line, 12)) {
if ($context != 'MSGID') {
_locale_import_message('The translation file %filename contains an error: "msgid_plural" was expected but not found on line %line.', $file, $lineno);
return FALSE;
}
$line = trim(substr($line, 12));
$quoted = _locale_import_parse_quoted($line);
if ($quoted === FALSE) {
_locale_import_message('The translation file %filename contains a syntax error on line %line.', $file, $lineno);
return FALSE;
}
$current['msgid'] .= "\0" . $quoted;
$context = 'MSGID_PLURAL';
}
elseif (!strncmp('msgid', $line, 5)) {
if ($context == 'MSGSTR' || $context == 'MSGSTR_ARR') {
_locale_import_one_string($op, $current, $mode, $lang, $file, $group);
$current = array();
}
elseif ($context == 'MSGID') {
_locale_import_message('The translation file %filename contains an error: "msgid" is unexpected on line %line.', $file, $lineno);
return FALSE;
}
$line = trim(substr($line, 5));
$quoted = _locale_import_parse_quoted($line);
if ($quoted === FALSE) {
_locale_import_message('The translation file %filename contains a syntax error on line %line.', $file, $lineno);
return FALSE;
}
$current['msgid'] = $quoted;
$context = 'MSGID';
}
elseif (!strncmp('msgctxt', $line, 7)) {
if ($context == 'MSGSTR' || $context == 'MSGSTR_ARR') {
_locale_import_one_string($op, $current, $mode, $lang, $file, $group);
$current = array();
}
elseif (!empty($current['msgctxt'])) {
_locale_import_message('The translation file %filename contains an error: "msgctxt" is unexpected on line %line.', $file, $lineno);
return FALSE;
}
$line = trim(substr($line, 7));
$quoted = _locale_import_parse_quoted($line);
if ($quoted === FALSE) {
_locale_import_message('The translation file %filename contains a syntax error on line %line.', $file, $lineno);
return FALSE;
}
$current['msgctxt'] = $quoted;
$context = 'MSGCTXT';
}
elseif (!strncmp('msgstr[', $line, 7)) {
if ($context != 'MSGID' && $context != 'MSGCTXT' && $context != 'MSGID_PLURAL' && $context != 'MSGSTR_ARR') {
_locale_import_message('The translation file %filename contains an error: "msgstr[]" is unexpected on line %line.', $file, $lineno);
return FALSE;
}
if (strpos($line, ']') === FALSE) {
_locale_import_message('The translation file %filename contains a syntax error on line %line.', $file, $lineno);
return FALSE;
}
$frombracket = strstr($line, '[');
$plural = substr($frombracket, 1, strpos($frombracket, ']') - 1);
$line = trim(strstr($line, " "));
$quoted = _locale_import_parse_quoted($line);
if ($quoted === FALSE) {
_locale_import_message('The translation file %filename contains a syntax error on line %line.', $file, $lineno);
return FALSE;
}
$current['msgstr'][$plural] = $quoted;
$context = 'MSGSTR_ARR';
}
elseif (!strncmp("msgstr", $line, 6)) {
if ($context != 'MSGID' && $context != 'MSGCTXT') {
_locale_import_message('The translation file %filename contains an error: "msgstr" is unexpected on line %line.', $file, $lineno);
return FALSE;
}
$line = trim(substr($line, 6));
$quoted = _locale_import_parse_quoted($line);
if ($quoted === FALSE) {
_locale_import_message('The translation file %filename contains a syntax error on line %line.', $file, $lineno);
return FALSE;
}
$current['msgstr'] = $quoted;
$context = 'MSGSTR';
}
elseif ($line != '') {
$quoted = _locale_import_parse_quoted($line);
if ($quoted === FALSE) {
_locale_import_message('The translation file %filename contains a syntax error on line %line.', $file, $lineno);
return FALSE;
}
if ($context == 'MSGID' || $context == 'MSGID_PLURAL') {
$current['msgid'] .= $quoted;
}
elseif ($context == 'MSGCTXT') {
$current['msgctxt'] .= $quoted;
}
elseif ($context == 'MSGSTR') {
$current['msgstr'] .= $quoted;
}
elseif ($context == 'MSGSTR_ARR') {
$current['msgstr'][$plural] .= $quoted;
}
else {
_locale_import_message('The translation file %filename contains an error: there is an unexpected string on line %line.', $file, $lineno);
return FALSE;
}
}
}
if ($context == 'MSGSTR' || $context == 'MSGSTR_ARR') {
_locale_import_one_string($op, $current, $mode, $lang, $file, $group);
}
elseif ($context != 'COMMENT') {
_locale_import_message('The translation file %filename ended unexpectedly at line %line.', $file, $lineno);
return FALSE;
}
}
function _locale_import_message($message, $file, $lineno = NULL) {
$vars = array(
'%filename' => $file->filename,
);
if (isset($lineno)) {
$vars['%line'] = $lineno;
}
$t = get_t();
drupal_set_message($t($message, $vars), 'error');
}
function _locale_import_one_string($op, $value = NULL, $mode = NULL, $lang = NULL, $file = NULL, $group = 'default') {
$report =& drupal_static(__FUNCTION__, array(
'additions' => 0,
'updates' => 0,
'deletes' => 0,
'skips' => 0,
));
$header_done =& drupal_static(__FUNCTION__ . ':header_done', FALSE);
$strings =& drupal_static(__FUNCTION__ . ':strings', array());
switch ($op) {
case 'mem-report':
return $strings;
case 'mem-store':
$strings[isset($value['msgctxt']) ? $value['msgctxt'] : ''][$value['msgid']] = $value['msgstr'];
return;
case 'db-report':
return array(
$header_done,
$report['additions'],
$report['updates'],
$report['deletes'],
$report['skips'],
);
case 'db-store':
if ($value['msgid'] == '') {
$languages = language_list();
if ($mode != LOCALE_IMPORT_KEEP || empty($languages[$lang]->plurals)) {
$header = _locale_import_parse_header($value['msgstr']);
if (isset($header["Plural-Forms"]) && ($p = _locale_import_parse_plural_forms($header["Plural-Forms"], $file->uri))) {
list($nplurals, $plural) = $p;
db_update('languages')
->fields(array(
'plurals' => $nplurals,
'formula' => $plural,
))
->condition('language', $lang)
->execute();
}
}
$header_done = TRUE;
}
else {
$comments = _locale_import_shorten_comments(empty($value['#']) ? array() : $value['#']);
if (strpos($value['msgid'], "\0")) {
$english = explode("\0", $value['msgid'], 2);
$entries = array_keys($value['msgstr']);
for ($i = 3; $i <= count($entries); $i++) {
$english[] = $english[1];
}
$translation = array_map('_locale_import_append_plural', $value['msgstr'], $entries);
$english = array_map('_locale_import_append_plural', $english, $entries);
foreach ($translation as $key => $trans) {
if ($key == 0) {
$plid = 0;
}
$plid = _locale_import_one_string_db($report, $lang, isset($value['msgctxt']) ? $value['msgctxt'] : '', $english[$key], $trans, $group, $comments, $mode, $plid, $key);
}
}
else {
$english = $value['msgid'];
$translation = $value['msgstr'];
_locale_import_one_string_db($report, $lang, isset($value['msgctxt']) ? $value['msgctxt'] : '', $english, $translation, $group, $comments, $mode);
}
}
}
}
function _locale_import_one_string_db(&$report, $langcode, $context, $source, $translation, $textgroup, $location, $mode, $plid = 0, $plural = 0) {
$lid = db_query("SELECT lid FROM {locales_source} WHERE source = :source AND context = :context AND textgroup = :textgroup", array(
':source' => $source,
':context' => $context,
':textgroup' => $textgroup,
))
->fetchField();
if (!empty($translation)) {
if ($textgroup == "default" && !locale_string_is_safe($translation)) {
$report['skips']++;
$lid = 0;
}
elseif ($lid) {
db_update('locales_source')
->fields(array(
'location' => $location,
))
->condition('lid', $lid)
->execute();
$exists = db_query("SELECT COUNT(lid) FROM {locales_target} WHERE lid = :lid AND language = :language", array(
':lid' => $lid,
':language' => $langcode,
))
->fetchField();
if (!$exists) {
db_insert('locales_target')
->fields(array(
'lid' => $lid,
'language' => $langcode,
'translation' => $translation,
'plid' => $plid,
'plural' => $plural,
))
->execute();
$report['additions']++;
}
elseif ($mode == LOCALE_IMPORT_OVERWRITE) {
db_update('locales_target')
->fields(array(
'translation' => $translation,
'plid' => $plid,
'plural' => $plural,
))
->condition('language', $langcode)
->condition('lid', $lid)
->execute();
$report['updates']++;
}
}
else {
$lid = db_insert('locales_source')
->fields(array(
'location' => $location,
'source' => $source,
'context' => (string) $context,
'textgroup' => $textgroup,
))
->execute();
db_insert('locales_target')
->fields(array(
'lid' => $lid,
'language' => $langcode,
'translation' => $translation,
'plid' => $plid,
'plural' => $plural,
))
->execute();
$report['additions']++;
}
}
elseif ($mode == LOCALE_IMPORT_OVERWRITE) {
db_delete('locales_target')
->condition('language', $langcode)
->condition('lid', $lid)
->condition('plid', $plid)
->condition('plural', $plural)
->execute();
$report['deletes']++;
}
return $lid;
}
function _locale_import_parse_header($header) {
$header_parsed = array();
$lines = array_map('trim', explode("\n", $header));
foreach ($lines as $line) {
if ($line) {
list($tag, $contents) = explode(":", $line, 2);
$header_parsed[trim($tag)] = trim($contents);
}
}
return $header_parsed;
}
function _locale_import_parse_plural_forms($pluralforms, $filepath) {
$pluralforms = strtr($pluralforms, array(
" " => "",
"\t" => "",
));
$nplurals = strstr($pluralforms, "nplurals=");
if (strpos($nplurals, ";")) {
$nplurals = substr($nplurals, 9, strpos($nplurals, ";") - 9);
}
else {
return FALSE;
}
$plural = strstr($pluralforms, "plural=");
if (strpos($plural, ";")) {
$plural = substr($plural, 7, strpos($plural, ";") - 7);
}
else {
return FALSE;
}
$plural = _locale_import_parse_arithmetic($plural);
if ($plural !== FALSE) {
return array(
$nplurals,
$plural,
);
}
else {
drupal_set_message(t('The translation file %filepath contains an error: the plural formula could not be parsed.', array(
'%filepath' => $filepath,
)), 'error');
return FALSE;
}
}
function _locale_import_parse_arithmetic($string) {
$precedence = array(
"(" => -1,
")" => -1,
"?" => 1,
":" => 1,
"||" => 3,
"&&" => 4,
"==" => 5,
"!=" => 5,
"<" => 6,
">" => 6,
"<=" => 6,
">=" => 6,
"+" => 7,
"-" => 7,
"*" => 8,
"/" => 8,
"%" => 8,
);
$right_associativity = array(
"?" => 1,
":" => 1,
);
$tokens = _locale_import_tokenize_formula($string);
$operator_stack = array();
$element_stack = array();
foreach ($tokens as $token) {
$current_token = $token;
if (is_numeric($token)) {
$element_stack[] = $current_token;
}
elseif ($current_token == "n") {
$element_stack[] = '$n';
}
elseif ($current_token == "(") {
$operator_stack[] = $current_token;
}
elseif ($current_token == ")") {
$topop = array_pop($operator_stack);
while (isset($topop) && $topop != "(") {
$element_stack[] = $topop;
$topop = array_pop($operator_stack);
}
}
elseif (!empty($precedence[$current_token])) {
$topop = array_pop($operator_stack);
while (isset($topop) && $precedence[$topop] >= $precedence[$current_token] && !($precedence[$topop] == $precedence[$current_token] && !empty($right_associativity[$topop]) && !empty($right_associativity[$current_token]))) {
$element_stack[] = $topop;
$topop = array_pop($operator_stack);
}
if ($topop) {
$operator_stack[] = $topop;
}
$operator_stack[] = $current_token;
}
else {
return FALSE;
}
}
$topop = array_pop($operator_stack);
while ($topop != NULL) {
$element_stack[] = $topop;
$topop = array_pop($operator_stack);
}
$previous_size = count($element_stack) + 1;
while (count($element_stack) < $previous_size) {
$previous_size = count($element_stack);
for ($i = 2; $i < count($element_stack); $i++) {
$op = $element_stack[$i];
if (!empty($precedence[$op])) {
$f = "";
if ($op == ":") {
$f = $element_stack[$i - 2] . "):" . $element_stack[$i - 1] . ")";
}
elseif ($op == "?") {
$f = "(" . $element_stack[$i - 2] . "?(" . $element_stack[$i - 1];
}
else {
$f = "(" . $element_stack[$i - 2] . $op . $element_stack[$i - 1] . ")";
}
array_splice($element_stack, $i - 2, 3, $f);
break;
}
}
}
if (count($element_stack) == 1) {
return $element_stack[0];
}
else {
return FALSE;
}
}
function _locale_import_tokenize_formula($formula) {
$formula = str_replace(" ", "", $formula);
$tokens = array();
for ($i = 0; $i < strlen($formula); $i++) {
if (is_numeric($formula[$i])) {
$num = $formula[$i];
$j = $i + 1;
while ($j < strlen($formula) && is_numeric($formula[$j])) {
$num .= $formula[$j];
$j++;
}
$i = $j - 1;
$tokens[] = $num;
}
elseif ($pos = strpos(" =<>!&|", $formula[$i])) {
$next = $formula[$i + 1];
switch ($pos) {
case 1:
case 2:
case 3:
case 4:
if ($next == '=') {
$tokens[] = $formula[$i] . '=';
$i++;
}
else {
$tokens[] = $formula[$i];
}
break;
case 5:
if ($next == '&') {
$tokens[] = '&&';
$i++;
}
else {
$tokens[] = $formula[$i];
}
break;
case 6:
if ($next == '|') {
$tokens[] = '||';
$i++;
}
else {
$tokens[] = $formula[$i];
}
break;
}
}
else {
$tokens[] = $formula[$i];
}
}
return $tokens;
}
function _locale_import_append_plural($entry, $key) {
if ($key == 0 || $key == 1) {
return $entry;
}
$entry = preg_replace('/(@count)\\[[0-9]\\]/', '\\1', $entry);
return preg_replace('/(@count)/', "\\1[{$key}]", $entry);
}
function _locale_import_shorten_comments($comment) {
$comm = '';
while (count($comment)) {
$test = $comm . substr(array_shift($comment), 1) . ', ';
if (strlen($comm) < 130) {
$comm = $test;
}
else {
break;
}
}
return trim(substr($comm, 0, -2));
}
function _locale_import_parse_quoted($string) {
if (substr($string, 0, 1) != substr($string, -1, 1)) {
return FALSE;
}
$quote = substr($string, 0, 1);
$string = substr($string, 1, -1);
if ($quote == '"') {
return stripcslashes($string);
}
elseif ($quote == "'") {
return $string;
}
else {
return FALSE;
}
}
function _locale_parse_js_file($filepath) {
global $language;
$parsed_url = drupal_parse_url($filepath);
$filepath = $parsed_url['path'];
$file = file_get_contents($filepath);
preg_match_all('~
[^\\w]Drupal\\s*\\.\\s*t\\s* # match "Drupal.t" with whitespace
\\(\\s* # match "(" argument list start
(' . LOCALE_JS_STRING . ')\\s* # capture string argument
(?:,\\s*' . LOCALE_JS_OBJECT . '\\s* # optionally capture str args
(?:,\\s*' . LOCALE_JS_OBJECT_CONTEXT . '\\s*) # optionally capture context
?)? # close optional args
[,\\)] # match ")" or "," to finish
~sx', $file, $t_matches);
preg_match_all('~
[^\\w]Drupal\\s*\\.\\s*formatPlural\\s* # match "Drupal.formatPlural" with whitespace
\\( # match "(" argument list start
\\s*.+?\\s*,\\s* # match count argument
(' . LOCALE_JS_STRING . ')\\s*,\\s* # match singular string argument
( # capture plural string argument
(?: # non-capturing group to repeat string pieces
(?:
\' # match start of single-quoted string
(?:\\\\\'|[^\'])* # match any character except unescaped single-quote
@count # match "@count"
(?:\\\\\'|[^\'])* # match any character except unescaped single-quote
\' # match end of single-quoted string
|
" # match start of double-quoted string
(?:\\\\"|[^"])* # match any character except unescaped double-quote
@count # match "@count"
(?:\\\\"|[^"])* # match any character except unescaped double-quote
" # match end of double-quoted string
)
(?:\\s*\\+\\s*)? # match "+" with possible whitespace, for str concat
)+ # match multiple because we supports concatenating strs
)\\s* # end capturing of plural string argument
(?:,\\s*' . LOCALE_JS_OBJECT . '\\s* # optionally capture string args
(?:,\\s*' . LOCALE_JS_OBJECT_CONTEXT . '\\s*)? # optionally capture context
)?
[,\\)]
~sx', $file, $plural_matches);
$matches = array();
foreach ($t_matches[1] as $key => $string) {
$matches[] = array(
'string' => $string,
'context' => $t_matches[2][$key],
);
}
foreach ($plural_matches[1] as $key => $string) {
$matches[] = array(
'string' => $string,
'context' => $plural_matches[3][$key],
);
if (isset($plural_matches[2][$key])) {
$matches[] = array(
'string' => $plural_matches[2][$key],
'context' => $plural_matches[3][$key],
);
}
}
foreach ($matches as $key => $match) {
$string = implode('', preg_split('~(?<!\\\\)[\'"]\\s*\\+\\s*[\'"]~s', substr($match['string'], 1, -1)));
$context = implode('', preg_split('~(?<!\\\\)[\'"]\\s*\\+\\s*[\'"]~s', substr($match['context'], 1, -1)));
$source = db_query("SELECT lid, location FROM {locales_source} WHERE source = :source AND context = :context AND textgroup = 'default'", array(
':source' => $string,
':context' => $context,
))
->fetchObject();
if ($source) {
$locations = preg_split('~\\s*;\\s*~', $source->location);
if (!in_array($filepath, $locations)) {
$locations[] = $filepath;
$locations = implode('; ', $locations);
db_update('locales_source')
->fields(array(
'location' => $locations,
))
->condition('lid', $source->lid)
->execute();
}
}
else {
db_insert('locales_source')
->fields(array(
'location' => $filepath,
'source' => $string,
'context' => $context,
'textgroup' => 'default',
))
->execute();
}
}
}
function _locale_export_get_strings($language = NULL, $group = 'default') {
if (isset($language)) {
$result = db_query("SELECT s.lid, s.source, s.context, s.location, t.translation, t.plid, t.plural FROM {locales_source} s LEFT JOIN {locales_target} t ON s.lid = t.lid AND t.language = :language WHERE s.textgroup = :textgroup ORDER BY t.plid, t.plural", array(
':language' => $language->language,
':textgroup' => $group,
));
}
else {
$result = db_query("SELECT s.lid, s.source, s.context, s.location, t.plid, t.plural FROM {locales_source} s LEFT JOIN {locales_target} t ON s.lid = t.lid WHERE s.textgroup = :textgroup ORDER BY t.plid, t.plural", array(
':textgroup' => $group,
));
}
$strings = array();
foreach ($result as $child) {
$string = array(
'comment' => $child->location,
'source' => $child->source,
'context' => $child->context,
'translation' => isset($child->translation) ? $child->translation : '',
);
if ($child->plid) {
$string['child'] = TRUE;
$strings[$child->plid]['plural'] = $child->lid;
}
$strings[$child->lid] = $string;
}
return $strings;
}
function _locale_export_po_generate($language = NULL, $strings = array(), $header = NULL) {
global $user;
if (!isset($header)) {
if (isset($language)) {
$header = '# ' . $language->name . ' translation of ' . variable_get('site_name', 'Drupal') . "\n";
$header .= '# Generated by ' . $user->name . ' <' . $user->mail . ">\n";
$header .= "#\n";
$header .= "msgid \"\"\n";
$header .= "msgstr \"\"\n";
$header .= "\"Project-Id-Version: PROJECT VERSION\\n\"\n";
$header .= "\"POT-Creation-Date: " . date("Y-m-d H:iO") . "\\n\"\n";
$header .= "\"PO-Revision-Date: " . date("Y-m-d H:iO") . "\\n\"\n";
$header .= "\"Last-Translator: NAME <EMAIL@ADDRESS>\\n\"\n";
$header .= "\"Language-Team: LANGUAGE <EMAIL@ADDRESS>\\n\"\n";
$header .= "\"MIME-Version: 1.0\\n\"\n";
$header .= "\"Content-Type: text/plain; charset=utf-8\\n\"\n";
$header .= "\"Content-Transfer-Encoding: 8bit\\n\"\n";
if ($language->formula && $language->plurals) {
$header .= "\"Plural-Forms: nplurals=" . $language->plurals . "; plural=" . strtr($language->formula, array(
'$' => '',
)) . ";\\n\"\n";
}
}
else {
$header = "# LANGUAGE translation of PROJECT\n";
$header .= "# Copyright (c) YEAR NAME <EMAIL@ADDRESS>\n";
$header .= "#\n";
$header .= "msgid \"\"\n";
$header .= "msgstr \"\"\n";
$header .= "\"Project-Id-Version: PROJECT VERSION\\n\"\n";
$header .= "\"POT-Creation-Date: " . date("Y-m-d H:iO") . "\\n\"\n";
$header .= "\"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\\n\"\n";
$header .= "\"Last-Translator: NAME <EMAIL@ADDRESS>\\n\"\n";
$header .= "\"Language-Team: LANGUAGE <EMAIL@ADDRESS>\\n\"\n";
$header .= "\"MIME-Version: 1.0\\n\"\n";
$header .= "\"Content-Type: text/plain; charset=utf-8\\n\"\n";
$header .= "\"Content-Transfer-Encoding: 8bit\\n\"\n";
$header .= "\"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\\n\"\n";
}
}
$output = $header . "\n";
foreach ($strings as $lid => $string) {
if (!isset($string['child'])) {
if ($string['comment']) {
$output .= '#: ' . $string['comment'] . "\n";
}
if (!empty($string['context'])) {
$output .= 'msgctxt ' . _locale_export_string($string['context']);
}
$output .= 'msgid ' . _locale_export_string($string['source']);
if (!empty($string['plural'])) {
$plural = $string['plural'];
$output .= 'msgid_plural ' . _locale_export_string($strings[$plural]['source']);
if (isset($language)) {
$translation = $string['translation'];
for ($i = 0; $i < $language->plurals; $i++) {
$output .= 'msgstr[' . $i . '] ' . _locale_export_string($translation);
if ($plural) {
$translation = _locale_export_remove_plural($strings[$plural]['translation']);
$plural = isset($strings[$plural]['plural']) ? $strings[$plural]['plural'] : 0;
}
else {
$translation = '';
}
}
}
else {
$output .= 'msgstr[0] ""' . "\n";
$output .= 'msgstr[1] ""' . "\n";
}
}
else {
$output .= 'msgstr ' . _locale_export_string($string['translation']);
}
$output .= "\n";
}
}
return $output;
}
function _locale_export_po($language = NULL, $output = NULL) {
if (isset($language)) {
$filename = $language->language . '.po';
watchdog('locale', 'Exported %locale translation file: %filename.', array(
'%locale' => $language->name,
'%filename' => $filename,
));
}
else {
$filename = 'drupal.pot';
watchdog('locale', 'Exported translation file: %filename.', array(
'%filename' => $filename,
));
}
header("Content-Disposition: attachment; filename={$filename}");
header("Content-Type: text/plain; charset=utf-8");
print $output;
drupal_exit();
}
function _locale_export_string($str) {
$stri = addcslashes($str, "\0..\37\\\"");
$parts = array();
while ($stri != "") {
$i = strpos($stri, "\\n");
if ($i === FALSE) {
$curstr = $stri;
$stri = "";
}
else {
$curstr = substr($stri, 0, $i + 2);
$stri = substr($stri, $i + 2);
}
$curparts = explode("\n", _locale_export_wrap($curstr, 70));
$parts = array_merge($parts, $curparts);
}
if (count($parts) > 1) {
return "\"\"\n\"" . implode("\"\n\"", $parts) . "\"\n";
}
elseif (count($parts) == 1) {
return "\"{$parts[0]}\"\n";
}
else {
return "\"\"\n";
}
}
function _locale_export_wrap($str, $len) {
$words = explode(' ', $str);
$return = array();
$cur = "";
$nstr = 1;
while (count($words)) {
$word = array_shift($words);
if ($nstr) {
$cur = $word;
$nstr = 0;
}
elseif (strlen("{$cur} {$word}") > $len) {
$return[] = $cur . " ";
$cur = $word;
}
else {
$cur = "{$cur} {$word}";
}
}
$return[] = $cur;
return implode("\n", $return);
}
function _locale_export_remove_plural($entry) {
return preg_replace('/(@count)\\[[0-9]\\]/', '\\1', $entry);
}
function _locale_translate_seek() {
$output = '';
if (!($query = _locale_translate_seek_query())) {
$query = array(
'translation' => 'all',
'group' => 'all',
'language' => 'all',
'string' => '',
);
}
$sql_query = db_select('locales_source', 's');
$limit_language = NULL;
if ($query['language'] != 'en' && $query['language'] != 'all') {
$sql_query
->leftJoin('locales_target', 't', "t.lid = s.lid AND t.language = :langcode", array(
':langcode' => $query['language'],
));
$limit_language = $query['language'];
}
else {
$sql_query
->leftJoin('locales_target', 't', 't.lid = s.lid');
}
$sql_query
->fields('s', array(
'source',
'location',
'context',
'lid',
'textgroup',
));
$sql_query
->fields('t', array(
'translation',
'language',
));
switch ($query['translation']) {
case 'translated':
$sql_query
->condition('t.translation', '%' . db_like($query['string']) . '%', 'LIKE');
$sql_query
->orderBy('t.translation', 'DESC');
break;
case 'untranslated':
$sql_query
->condition(db_and()
->condition('s.source', '%' . db_like($query['string']) . '%', 'LIKE')
->isNull('t.translation'));
$sql_query
->orderBy('s.source');
break;
case 'all':
default:
$condition = db_or()
->condition('s.source', '%' . db_like($query['string']) . '%', 'LIKE');
if ($query['language'] != 'en') {
$condition
->condition('t.translation', '%' . db_like($query['string']) . '%', 'LIKE');
}
$sql_query
->condition($condition);
break;
}
if (!empty($query['group']) && $query['group'] != 'all') {
$sql_query
->condition('s.textgroup', $query['group']);
}
$sql_query = $sql_query
->extend('PagerDefault')
->limit(50);
$locales = $sql_query
->execute();
$groups = module_invoke_all('locale', 'groups');
$header = array(
t('Text group'),
t('String'),
t('Context'),
$limit_language ? t('Language') : t('Languages'),
array(
'data' => t('Operations'),
'colspan' => '2',
),
);
$strings = array();
foreach ($locales as $locale) {
if (!isset($strings[$locale->lid])) {
$strings[$locale->lid] = array(
'group' => $locale->textgroup,
'languages' => array(),
'location' => $locale->location,
'source' => $locale->source,
'context' => $locale->context,
);
}
if (isset($locale->language)) {
$strings[$locale->lid]['languages'][$locale->language] = $locale->translation;
}
}
$rows = array();
foreach ($strings as $lid => $string) {
$rows[] = array(
$groups[$string['group']],
array(
'data' => check_plain(truncate_utf8($string['source'], 150, FALSE, TRUE)) . '<br /><small>' . $string['location'] . '</small>',
),
$string['context'],
array(
'data' => _locale_translate_language_list($string, $limit_language),
'align' => 'center',
),
array(
'data' => l(t('edit'), "admin/config/regional/translate/edit/{$lid}", array(
'query' => drupal_get_destination(),
)),
'class' => array(
'nowrap',
),
),
array(
'data' => l(t('delete'), "admin/config/regional/translate/delete/{$lid}", array(
'query' => drupal_get_destination(),
)),
'class' => array(
'nowrap',
),
),
);
}
$output .= theme('table', array(
'header' => $header,
'rows' => $rows,
'empty' => t('No strings available.'),
));
$output .= theme('pager');
return $output;
}
function _locale_translate_seek_query() {
$query =& drupal_static(__FUNCTION__);
if (!isset($query)) {
$query = array();
$fields = array(
'string',
'language',
'translation',
'group',
);
foreach ($fields as $field) {
if (isset($_SESSION['locale_translation_filter'][$field])) {
$query[$field] = $_SESSION['locale_translation_filter'][$field];
}
}
}
return $query;
}
function _locale_invalidate_js($langcode = NULL) {
$parsed = variable_get('javascript_parsed', array());
if (empty($langcode)) {
$languages = language_list();
unset($languages['en']);
foreach ($languages as $lcode => $data) {
$parsed['refresh:' . $lcode] = 'waiting';
}
}
else {
$parsed['refresh:' . $langcode] = 'waiting';
}
variable_set('javascript_parsed', $parsed);
return $parsed;
}
function _locale_rebuild_js($langcode = NULL) {
if (!isset($langcode)) {
global $language;
}
else {
$languages = language_list();
$language = $languages[$langcode];
}
$result = db_query("SELECT s.lid, s.source, s.context, t.translation FROM {locales_source} s INNER JOIN {locales_target} t ON s.lid = t.lid AND t.language = :language WHERE s.location LIKE '%.js%' AND s.textgroup = :textgroup", array(
':language' => $language->language,
':textgroup' => 'default',
));
$translations = array();
foreach ($result as $data) {
$translations[$data->context][$data->source] = $data->translation;
}
$data_hash = NULL;
$data = $status = '';
if (!empty($translations)) {
$data = "Drupal.locale = { ";
if (!empty($language->formula)) {
$data .= "'pluralFormula': function (\$n) { return Number({$language->formula}); }, ";
}
$data .= "'strings': " . drupal_json_encode($translations) . " };";
$data_hash = drupal_hash_base64($data);
}
$dir = 'public://' . variable_get('locale_js_directory', 'languages');
$changed_hash = $language->javascript != $data_hash;
if (!empty($language->javascript) && (!$data || $changed_hash)) {
file_unmanaged_delete($dir . '/' . $language->language . '_' . $language->javascript . '.js');
$language->javascript = '';
$status = 'deleted';
}
$dest = $dir . '/' . $language->language . '_' . $data_hash . '.js';
if ($data && ($changed_hash || !file_exists($dest))) {
file_prepare_directory($dir, FILE_CREATE_DIRECTORY);
if (file_unmanaged_save_data($data, $dest)) {
$language->javascript = $data_hash;
if ($status == 'deleted') {
$status = 'updated';
}
elseif ($changed_hash) {
$status = 'created';
}
else {
$status = 'rebuilt';
}
}
else {
$language->javascript = '';
$status = 'error';
}
}
if ($status && $changed_hash) {
db_update('languages')
->fields(array(
'javascript' => $language->javascript,
))
->condition('language', $language->language)
->execute();
$default_langcode = language_default('language');
if ($default_langcode == $language->language) {
$default = db_query("SELECT * FROM {languages} WHERE language = :language", array(
':language' => $default_langcode,
))
->fetchObject();
variable_set('language_default', $default);
}
}
switch ($status) {
case 'updated':
watchdog('locale', 'Updated JavaScript translation file for the language %language.', array(
'%language' => t($language->name),
));
return TRUE;
case 'rebuilt':
watchdog('locale', 'JavaScript translation file %file.js was lost.', array(
'%file' => $language->javascript,
), WATCHDOG_WARNING);
case 'created':
watchdog('locale', 'Created JavaScript translation file for the language %language.', array(
'%language' => t($language->name),
));
return TRUE;
case 'deleted':
watchdog('locale', 'Removed JavaScript translation file for the language %language, because no translations currently exist for that language.', array(
'%language' => t($language->name),
));
return TRUE;
case 'error':
watchdog('locale', 'An error occurred during creation of the JavaScript translation file for the language %language.', array(
'%language' => t($language->name),
), WATCHDOG_ERROR);
return FALSE;
default:
return TRUE;
}
}
function _locale_translate_language_list($string, $limit_language) {
drupal_add_css(drupal_get_path('module', 'locale') . '/locale.css');
$languages = language_list();
$default = language_default();
$omit = $string['group'] == 'default' ? 'en' : $default->language;
unset($languages[$omit]);
$output = '';
foreach ($languages as $langcode => $language) {
if (!$limit_language || $limit_language == $langcode) {
$output .= !empty($string['languages'][$langcode]) ? $langcode . ' ' : "<em class=\"locale-untranslated\">{$langcode}</em> ";
}
}
return $output;
}
function _locale_prepare_predefined_list() {
include_once DRUPAL_ROOT . '/includes/iso.inc';
$languages = language_list();
$predefined = _locale_get_predefined_list();
foreach ($predefined as $key => $value) {
if (isset($languages[$key])) {
unset($predefined[$key]);
continue;
}
if (count($value) > 1) {
$tname = t($value[0]);
$predefined[$key] = $tname == $value[1] ? $tname : "{$tname} ({$value[1]})";
}
else {
$predefined[$key] = t($value[0]);
}
}
asort($predefined);
return $predefined;
}
function locale_batch_by_language($langcode, $finished = NULL, $skip = array()) {
$files = array();
$components = array();
$query = db_select('system', 's');
$query
->fields('s', array(
'name',
'filename',
));
$query
->condition('s.status', 1);
if (count($skip)) {
$query
->condition('name', $skip, 'NOT IN');
}
$result = $query
->execute();
foreach ($result as $component) {
$files = array_merge($files, file_scan_directory(dirname($component->filename) . '/translations', '/(^|\\.)' . $langcode . '\\.po$/', array(
'recurse' => FALSE,
)));
$components[] = $component->name;
}
return _locale_batch_build($files, $finished, $components);
}
function locale_batch_by_component($components, $finished = '_locale_batch_system_finished') {
$files = array();
$languages = language_list('enabled');
unset($languages[1]['en']);
if (count($languages[1])) {
$language_list = join('|', array_keys($languages[1]));
$result = db_query("SELECT name, filename FROM {system} WHERE status = 1");
foreach ($result as $component) {
if (in_array($component->name, $components)) {
$files = array_merge($files, file_scan_directory(dirname($component->filename) . '/translations', '/(^|\\.)(' . $language_list . ')\\.po$/', array(
'recurse' => FALSE,
)));
}
}
return _locale_batch_build($files, $finished);
}
return FALSE;
}
function _locale_batch_build($files, $finished = NULL, $components = array()) {
$t = get_t();
if (count($files)) {
$operations = array();
foreach ($files as $file) {
$operations[] = array(
'_locale_batch_import',
array(
$file->uri,
),
);
}
$batch = array(
'operations' => $operations,
'title' => $t('Importing interface translations'),
'init_message' => $t('Starting import'),
'error_message' => $t('Error importing interface translations'),
'file' => 'includes/locale.inc',
'#components' => $components,
);
if (isset($finished)) {
$batch['finished'] = $finished;
}
return $batch;
}
return FALSE;
}
function _locale_batch_import($filepath, &$context) {
if (preg_match('!(/|\\.)([^\\./]+)\\.po$!', $filepath, $langcode)) {
$file = (object) array(
'filename' => drupal_basename($filepath),
'uri' => $filepath,
);
_locale_import_read_po('db-store', $file, LOCALE_IMPORT_KEEP, $langcode[2]);
$context['results'][] = $filepath;
}
}
function _locale_batch_system_finished($success, $results) {
if ($success) {
drupal_set_message(format_plural(count($results), 'One translation file imported for the newly installed modules.', '@count translation files imported for the newly installed modules.'));
}
}
function _locale_batch_language_finished($success, $results) {
if ($success) {
drupal_set_message(format_plural(count($results), 'One translation file imported for the enabled modules.', '@count translation files imported for the enabled modules.'));
}
}
function country_get_list() {
include_once DRUPAL_ROOT . '/includes/iso.inc';
$countries = _country_get_predefined_list();
drupal_alter('countries', $countries);
return $countries;
}
function locale_date_format_save($langcode, $type, $format) {
$locale_format = array();
$locale_format['language'] = $langcode;
$locale_format['type'] = $type;
$locale_format['format'] = $format;
$is_existing = (bool) db_query_range('SELECT 1 FROM {date_format_locale} WHERE language = :langcode AND type = :type', 0, 1, array(
':langcode' => $langcode,
':type' => $type,
))
->fetchField();
if ($is_existing) {
$keys = array(
'type',
'language',
);
drupal_write_record('date_format_locale', $locale_format, $keys);
}
else {
drupal_write_record('date_format_locale', $locale_format);
}
}
function locale_get_localized_date_format($languages) {
$formats = array();
$format_types = system_get_date_types();
$short_default = variable_get('date_format_short', 'm/d/Y - H:i');
foreach ($languages as $language) {
$date_formats = system_date_format_locale($language);
if (!empty($date_formats)) {
foreach ($format_types as $type => $type_info) {
if (!empty($date_formats[$type])) {
$formats['date_format_' . $type] = $date_formats[$type];
}
else {
$formats['date_format_' . $type] = variable_get('date_format_' . $type, $short_default);
}
}
return $formats;
}
}
$system_types = array(
'short',
'medium',
'long',
);
$formats['date_format_short'] = $short_default;
$formats['date_format_medium'] = variable_get('date_format_medium', 'D, m/d/Y - H:i');
$formats['date_format_long'] = variable_get('date_format_long', 'l, F j, Y - H:i');
foreach ($format_types as $type => $type_info) {
if (!in_array($type, $system_types)) {
$formats['date_format_' . $type] = variable_get('date_format_' . $type, $short_default);
}
}
return $formats;
}