Commit 3e914018 authored by Dries's avatar Dries

- Patch #880278 by RoboPhred: cleanup _locale_import_read_po().

parent 570dcc57
......@@ -1136,6 +1136,7 @@ function drupal_serve_page_from_cache(stdClass $cache) {
$etag = '"' . $cache->created . '-' . intval($return_compressed) . '"';
header('Etag: ' . $etag);
drupal_set_configured_timezone();
// See if the client has provided the required HTTP headers.
$if_modified_since = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) : FALSE;
$if_none_match = isset($_SERVER['HTTP_IF_NONE_MATCH']) ? stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) : FALSE;
......@@ -1943,9 +1944,26 @@ function drupal_get_user_timezone() {
return $user->timezone;
}
else {
// Ignore PHP strict notice if time zone has not yet been set in the php.ini
// configuration.
return variable_get('date_default_timezone', @date_default_timezone_get());
// Note that is no site-wide timezone is set, and date.timezone is not set
// in php.ini, then calling date functions will cause a system call and
// PHP will issue an E_STRICT or E_WARNING error depending on PHP version.
// @todo: consider always setting the date_default_timezone variable from
// the installer.
return variable_get('date_default_timezone');
}
}
/**
* Set the timezone for a request when configured.
*/
function drupal_set_configured_timezone() {
$configured_timezone = drupal_get_user_timezone();
$system_timezone = ini_get('date.timezone');
// There is no point setting the timezone if it is configured the same
// as date.timezone in php.ini. Also date_default_timezone_set() validates
// the timezone, which relies on a system call to get the timezone database.
if ($configured_timezone != $system_timezone) {
date_default_timezone_set($configured_timezone);
}
}
......@@ -2046,7 +2064,6 @@ function _drupal_bootstrap_page_cache() {
// Restore the metadata cached with the page.
$_GET['q'] = $cache->data['path'];
drupal_set_title($cache->data['title'], PASS_THROUGH);
date_default_timezone_set(drupal_get_user_timezone());
// If the skipping of the bootstrap hooks is not enforced, call
// hook_boot.
if (variable_get('page_cache_invoke_hooks', TRUE)) {
......
......@@ -586,159 +586,250 @@ function _locale_import_po($file, $langcode, $mode, $group = NULL) {
*/
function _locale_import_read_po($op, $file, $mode = NULL, $lang = NULL, $group = 'default') {
$fd = fopen($file->uri, "rb"); // File will get closed by PHP on return
// The file will get closed by PHP on returning from this function.
$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"; // Parser context: COMMENT, MSGID, MSGID_PLURAL, MSGSTR and MSGSTR_ARR
$current = array(); // Current entry being read
$plural = 0; // Current plural form
$lineno = 0; // Current line
/*
* The parser context. Can be:
* - 'COMMENT' (#)
* - 'MSGID' (msgid)
* - 'MSGID_PLURAL' (msgid_plural)
* - 'MSGCTXT' (msgctxt)
* - 'MSGSTR' (msgstr or msgstr[])
* - 'MSGSTR_ARR' (msgstr_arg)
*/
$context = 'COMMENT';
// Current entry being read.
$current = array();
// Current plurality for 'msgstr[]'.
$plural = 0;
// Current line.
$lineno = 0;
while (!feof($fd)) {
$line = fgets($fd, 10*1024); // A line should not be this long
// A line should not be longer than 10 * 1024.
$line = fgets($fd, 10 * 1024);
if ($lineno == 0) {
// The first line might come with a UTF-8 BOM, which should be removed.
$line = str_replace("\xEF\xBB\xBF", '', $line);
}
$lineno++;
// Trim away the linefeed.
$line = trim(strtr($line, array("\\\n" => "")));
if (!strncmp("#", $line, 1)) { // A comment
if ($context == "COMMENT") { // Already in comment context: add
$current["#"][] = substr($line, 1);
if (!strncmp('#', $line, 1)) {
// Lines starting with '#' are comments.
if ($context == 'COMMENT') {
// Already in comment token, insert the comment.
$current['#'][] = substr($line, 1);
}
elseif (($context == "MSGSTR") || ($context == "MSGSTR_ARR")) { // End current entry, start a new one
elseif (($context == 'MSGSTR') || ($context == 'MSGSTR_ARR')) {
// We are currently in string token, close it out.
_locale_import_one_string($op, $current, $mode, $lang, $file, $group);
// Start a new entry for the comment.
$current = array();
$current["#"][] = substr($line, 1);
$context = "COMMENT";
$current['#'][] = substr($line, 1);
$context = 'COMMENT';
}
else { // Parse error
else {
// A comment following any other token is a syntax error.
_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") { // Must be plural form for current entry
elseif (!strncmp('msgid_plural', $line, 12)) {
// A plural form for the current message.
if ($context != 'MSGID') {
// A plural form cannot be added to anything else but the id directly.
_locale_import_message('The translation file %filename contains an error: "msgid_plural" was expected but not found on line %line.', $file, $lineno);
return FALSE;
}
// Remove 'msgid_plural' and trim away whitespace.
$line = trim(substr($line, 12));
// At this point, $line should now contain only the plural form.
$quoted = _locale_import_parse_quoted($line);
if ($quoted === FALSE) {
// The plural form must be wrapped in quotes.
_locale_import_message('The translation file %filename contains a syntax error on line %line.', $file, $lineno);
return FALSE;
}
$current["msgid"] = $current["msgid"] . "\0" . $quoted;
$context = "MSGID_PLURAL";
// Append the plural form to the current entry.
$current['msgid'] .= "\0" . $quoted;
$context = 'MSGID_PLURAL';
}
elseif (!strncmp("msgid", $line, 5)) {
if (($context == "MSGSTR") || ($context == "MSGSTR_ARR")) { // End current entry, start a new one
elseif (!strncmp('msgid', $line, 5)) {
// Starting a new message.
if (($context == 'MSGSTR') || ($context == 'MSGSTR_ARR')) {
// We are currently in a message string, close it out.
_locale_import_one_string($op, $current, $mode, $lang, $file, $group);
// Start a new context for the id.
$current = array();
}
elseif ($context == "MSGID") { // Already in this context? Parse error
elseif ($context == 'MSGID') {
// We are currently already in the context, meaning we passed an id with no data.
_locale_import_message('The translation file %filename contains an error: "msgid" is unexpected on line %line.', $file, $lineno);
return FALSE;
}
// Remove 'msgid' and trim away whitespace.
$line = trim(substr($line, 5));
// At this point, $line should now contain only the message id.
$quoted = _locale_import_parse_quoted($line);
if ($quoted === FALSE) {
// The message id must be wrapped in quotes.
_locale_import_message('The translation file %filename contains a syntax error on line %line.', $file, $lineno);
return FALSE;
}
$current["msgid"] = $quoted;
$context = "MSGID";
$current['msgid'] = $quoted;
$context = 'MSGID';
}
elseif (!strncmp("msgctxt", $line, 7)) {
if (($context == "MSGSTR") || ($context == "MSGSTR_ARR")) { // End current entry, start a new one
elseif (!strncmp('msgctxt', $line, 7)) {
// Starting a new context.
if (($context == 'MSGSTR') || ($context == 'MSGSTR_ARR')) {
// We are currently in a message, start a new one.
_locale_import_one_string($op, $current, $mode, $lang, $file, $group);
$current = array();
}
elseif (!empty($current["msgctxt"])) { // Already in this context? Parse error
elseif (!empty($current['msgctxt'])) {
// A context cannot apply to another context.
_locale_import_message('The translation file %filename contains an error: "msgctxt" is unexpected on line %line.', $file, $lineno);
return FALSE;
}
// Remove 'msgctxt' and trim away whitespaces.
$line = trim(substr($line, 7));
// At this point, $line should now contain the context.
$quoted = _locale_import_parse_quoted($line);
if ($quoted === FALSE) {
// The context string must be quoted.
_locale_import_message('The translation file %filename contains a syntax error on line %line.', $file, $lineno);
return FALSE;
}
$current["msgctxt"] = $quoted;
$context = "MSGCTXT";
$current['msgctxt'] = $quoted;
$context = 'MSGCTXT';
}
elseif (!strncmp("msgstr[", $line, 7)) {
if (($context != "MSGID") && ($context != "MSGCTXT") && ($context != "MSGID_PLURAL") && ($context != "MSGSTR_ARR")) { // Must come after msgid, msgxtxt, msgid_plural, or msgstr[]
elseif (!strncmp('msgstr[', $line, 7)) {
// A message string for a specific plurality.
if (($context != 'MSGID') && ($context != 'MSGCTXT') && ($context != 'MSGID_PLURAL') && ($context != 'MSGSTR_ARR')) {
// Message strings must come after msgid, msgxtxt, msgid_plural, or other msgstr[] entries.
_locale_import_message('The translation file %filename contains an error: "msgstr[]" is unexpected on line %line.', $file, $lineno);
return FALSE;
}
if (strpos($line, "]") === FALSE) {
// Ensure the plurality is terminated.
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);
// Extract the plurality.
$frombracket = strstr($line, '[');
$plural = substr($frombracket, 1, strpos($frombracket, ']') - 1);
// Skip to the next whitespace and trim away any further whitespace, bringing $line to the message data.
$line = trim(strstr($line, " "));
$quoted = _locale_import_parse_quoted($line);
if ($quoted === FALSE) {
// The string must be quoted.
_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";
$current['msgstr'][$plural] = $quoted;
$context = 'MSGSTR_ARR';
}
elseif (!strncmp("msgstr", $line, 6)) {
if (($context != "MSGID") && ($context != "MSGCTXT")) { // Should come just after a msgid or msgctxt block
// A string for the an id or context.
if (($context != 'MSGID') && ($context != 'MSGCTXT')) {
// Strings are only valid within an id or context scope.
_locale_import_message('The translation file %filename contains an error: "msgstr" is unexpected on line %line.', $file, $lineno);
return FALSE;
}
// Remove 'msgstr' and trim away away whitespaces.
$line = trim(substr($line, 6));
// At this point, $line should now contain the message.
$quoted = _locale_import_parse_quoted($line);
if ($quoted === FALSE) {
// The string must be quoted.
_locale_import_message('The translation file %filename contains a syntax error on line %line.', $file, $lineno);
return FALSE;
}
$current["msgstr"] = $quoted;
$context = "MSGSTR";
$current['msgstr'] = $quoted;
$context = 'MSGSTR';
}
elseif ($line != "") {
elseif ($line != '') {
// Anything that is not a token may be a continuation of a previous token.
$quoted = _locale_import_parse_quoted($line);
if ($quoted === FALSE) {
// The string must be quoted.
_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;
// Append the string to the current context.
if (($context == 'MSGID') || ($context == 'MSGID_PLURAL')) {
$current['msgid'] .= $quoted;
}
elseif ($context == "MSGCTXT") {
$current["msgctxt"] .= $quoted;
elseif ($context == 'MSGCTXT') {
$current['msgctxt'] .= $quoted;
}
elseif ($context == "MSGSTR") {
$current["msgstr"] .= $quoted;
elseif ($context == 'MSGSTR') {
$current['msgstr'] .= $quoted;
}
elseif ($context == "MSGSTR_ARR") {
$current["msgstr"][$plural] .= $quoted;
elseif ($context == 'MSGSTR_ARR') {
$current['msgstr'][$plural] .= $quoted;
}
else {
// No valid context to append to.
_locale_import_message('The translation file %filename contains an error: there is an unexpected string on line %line.', $file, $lineno);
return FALSE;
}
}
}
// End of PO file, flush last entry.
if (($context == "MSGSTR") || ($context == "MSGSTR_ARR")) {
// End of PO file, closed out the last entry.
if (($context == 'MSGSTR') || ($context == 'MSGSTR_ARR')) {
_locale_import_one_string($op, $current, $mode, $lang, $file, $group);
}
elseif ($context != "COMMENT") {
elseif ($context != 'COMMENT') {
_locale_import_message('The translation file %filename ended unexpectedly at line %line.', $file, $lineno);
return FALSE;
}
}
/**
......
......@@ -259,7 +259,7 @@ function drupal_session_initialize() {
// a user becomes authenticated.
session_id(drupal_hash_base64(uniqid(mt_rand(), TRUE)));
}
date_default_timezone_set(drupal_get_user_timezone());
drupal_set_configured_timezone();
}
/**
......@@ -387,7 +387,7 @@ function drupal_session_regenerate() {
drupal_session_start();
$user = $account;
}
date_default_timezone_set(drupal_get_user_timezone());
drupal_set_configured_timezone();
}
/**
......
......@@ -2226,7 +2226,7 @@ class FormatDateUnitTest extends DrupalWebTestCase {
$real_language = $language->language;
$language->language = $user->language;
// Simulate a Drupal bootstrap with the logged-in user.
date_default_timezone_set(drupal_get_user_timezone());
drupal_set_configured_timezone();
$this->assertIdentical(format_date($timestamp, 'custom', 'l, d-M-y H:i:s T', 'America/Los_Angeles', 'en'), 'Sunday, 25-Mar-07 17:00:00 PDT', t('Test a different language.'));
$this->assertIdentical(format_date($timestamp, 'custom', 'l, d-M-y H:i:s T', 'Europe/London'), 'Monday, 26-Mar-07 01:00:00 BST', t('Test a different time zone.'));
......@@ -2240,7 +2240,7 @@ class FormatDateUnitTest extends DrupalWebTestCase {
$user = $real_user;
$language->language = $real_language;
// Restore default time zone.
date_default_timezone_set(drupal_get_user_timezone());
drupal_set_configured_timezone();
drupal_save_session(TRUE);
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment