1
0
mirror of https://github.com/e107inc/e107.git synced 2025-08-06 14:46:56 +02:00

Merge pull request #2144 from lonalore/timezone

Timezone fixes
This commit is contained in:
Cameron
2016-12-13 13:26:40 -08:00
committed by GitHub
6 changed files with 215 additions and 174 deletions

View File

@@ -1127,25 +1127,75 @@ if (($_SERVER['QUERY_STRING'] == 'logout')/* || (($pref['user_tracking'] == 'ses
exit(); exit();
} }
/*
* Calculate time zone offset, based on session cookie set in e107.js.
* (Buyer beware: this may be wrong for the first pageview in a session, /**
* which is while the user is logged out, so not a problem...) * @addtogroup timezone
* * @{
* Time offset is SECONDS. Seconds is much better than hours as a base,
* as some places have 30 and 45 minute time zones.
* It matches user clock time, instead of only time zones.
* Add the offset to MySQL/server time to get user time.
* Subtract the offset from user time to get server time.
*
*/ */
$tz = vartrue($pref['timezone'], 'UTC'); //TODO Adjust on the front-end based on user timezone value. /**
* Generate an array of time zones.
*
* @return array
* Array of time zones.
*/
function systemTimeZones()
{
// Never do something time consuming twice if you can hold onto the results
// and re-use them. So we re-use the statically cached value to save time
// and memory.
static $zones = array();
date_default_timezone_set($tz); // Must be set or PHP Warning thrown. // If Timezone list is not populated yet.
if(empty($zones))
{
$zonelist = timezone_identifiers_list();
$timeNow = date('m/d/Y H:i', $_SERVER['REQUEST_TIME']);
unset($tz); foreach($zonelist as $zone)
{
// Because many time zones exist in PHP only for backward compatibility
// reasons and should not be used, the list is filtered by a regular
// expression.
if(preg_match('!^((Africa|America|Antarctica|Arctic|Asia|Atlantic|Australia|Europe|Indian|Pacific)/|UTC$)!', $zone))
{
$dateTimeZone = new DateTimeZone($zone);
$dateTime = new DateTime($timeNow, $dateTimeZone);
$offset = $dateTime->format('O');
$offset = chunk_split($offset, 3, ':');
$zones[$zone] = str_replace('_', ' ', $zone) . ' (' . rtrim($offset, ':') . ')';
}
}
// Sort time zones alphabetically.
asort($zones);
}
return $zones;
}
/**
* Validate a timezone.
*
* @param string $zone
* Timezone.
*
* @return bool
*/
function systemTimeZoneIsValid($zone = '')
{
$zones = systemTimeZones();
$zoneKeys = array_keys($zones);
if(in_array($zone, $zoneKeys))
{
return true;
}
return false;
}
$e_deltaTime = 0; $e_deltaTime = 0;
@@ -1163,6 +1213,10 @@ if (isset($_COOKIE['e107_tzOffset']))
define('TIMEOFFSET', $e_deltaTime); define('TIMEOFFSET', $e_deltaTime);
/**
* @} End of "addtogroup timezone".
*/
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -1723,6 +1777,33 @@ function init_session()
// New user model // New user model
$user = e107::getUser(); $user = e107::getUser();
// Get user timezone.
$tzUser = $user->getTimezone();
// If user timezone is valid.
if (varset($tzUser, false) && systemTimeZoneIsValid($tzUser))
{
// Sets the default timezone used by all date/time functions.
date_default_timezone_set($tzUser);
// Save timezone for later use.
define('USERTIMEZONE', $tzUser);
unset($tzUser);
}
else
{
// Use system default timezone.
$pref = e107::getPref();
$tz = vartrue($pref['timezone'], 'UTC');
// Sets the default timezone used by all date/time functions.
date_default_timezone_set($tz);
// Save timezone for later use.
define('USERTIMEZONE', $tz);
unset($tz);
}
define('USERIP', e107::getIPHandler()->getIP(FALSE)); define('USERIP', e107::getIPHandler()->getIP(FALSE));
define('POST_REFERER', md5($user->getToken())); define('POST_REFERER', md5($user->getToken()));

View File

@@ -727,39 +727,11 @@ $text .= "
$text .= " $text .= "
</td> </td>
</tr> </tr>";
<tr>
<td><label for='time-offset'>".PRFLAN_26."</label></td>
<td>
".$frm->select_open('time_offset', 'class=tbox select time-offset');//use form handler because of the tabindex
$toffset = array("-12", "-11", "-10", "-9", "-8", "-7", "-6", "-5", "-4", "-3", "-2", "-1", "0", "+1", "+2", "+3", "+4", "+5", "+6", "+7", "+8", "+9", "+10", "+11", "+12", "+13", "+14", "+15", "+16");
if(! isset($pref['time_offset']))
{
$pref['time_offset'] = "0";
}
//XXX TODO FIXME - Do we still need this?
foreach($toffset as $o)
{
$text .= "
".$frm->option($o, $o, ($o == $pref['time_offset']))."
";
}
$timeZones = systemTimeZones(); $timeZones = systemTimeZones();
$text .= " $text .= "
</select>
<div class='smalltext field-help'>".PRFLAN_27."</div>
</td>
</tr>
<tr> <tr>
<td><label for='timezone'>".PRFLAN_56."</label></td> <td><label for='timezone'>".PRFLAN_56."</label></td>
<td> <td>
@@ -773,37 +745,6 @@ $text .= "
"; ";
/**
* Generate an array of time zones.
*/
function systemTimeZones()
{
$zonelist = timezone_identifiers_list();
$timeNow = date('m/d/Y H:i', $_SERVER['REQUEST_TIME']);
$zones = array();
foreach($zonelist as $zone)
{
// Because many time zones exist in PHP only for backward compatibility
// reasons and should not be used, the list is filtered by a regular
// expression.
if(preg_match('!^((Africa|America|Antarctica|Arctic|Asia|Atlantic|Australia|Europe|Indian|Pacific)/|UTC$)!', $zone))
{
$dateTimeZone = new DateTimeZone($zone);
$dateTime = new DateTime($timeNow, $dateTimeZone);
$offset = $dateTime->format('O');
$offset = chunk_split($offset, 3, ':');
$zones[$zone] = str_replace('_', ' ', $zone) . ' (' . rtrim($offset, ':') . ')';
}
}
// Sort time zones alphabetically.
asort($zones);
return $zones;
}
// =========== Registration Preferences. ================== // =========== Registration Preferences. ==================

View File

@@ -14,121 +14,136 @@
* $Author$ * $Author$
*/ */
if (!defined('e107_INIT')) { exit; } if(!defined('e107_INIT'))
/*
This file is used with the extended user field 'predefined list' type. It is invoked when the value field is 'timezones'.
It is an example of an extended user field which access a predetermined list of key-pair values. In this example all the data is loaded
into memory; for other applications the data may be read from a database, possibly with caching.
The objective is to provide a uniform interface to such data.
The class name must be the same as the file name - i.e. the list name prefixed with 'extended_'.
The variable name must be 'timezones_list', and is an array of possible values, each of which is a value => text pair
The text is displayed in a drop-down; the value is returned.
If function timezones_value() exists, it is called to create the displayed text
*/
class extended_timezones
{ {
exit;
}
private $timezonesList = array( /**
'-12' => "International DateLine West", * @file
'-11' => "Samoa", * This file is used with the extended user field 'predefined list' type. It is
'-10' => "Hawaii", * invoked when the value field is 'timezones'.
'-9' => "Alaska", *
'-8' => "Pacific Time (US and Canada)", * It is an example of an extended user field which access a predetermined list
'-7' => "Mountain Time (US and Canada)", * of key-pair values. In this example all the data is loaded into memory; for
'-6' => "Central Time (US and Canada), Central America", * other applications the data may be read from a database, possibly with
'-5' => "Eastern Time (US and Canada)", * caching.
'-4' => "Atlantic Time (Canada)", *
'-3.30' => 'Newfoundland', * The objective is to provide a uniform interface to such data.
'-3' => "Greenland, Brasilia, Buenos Aires, Georgetown", *
'-2' => "Mid-Atlantic", * The class name must be the same as the file name - i.e. the list name
'-1' => "Azores, Cape Verde Islands", * prefixed with 'extended_'.
'+0' => "UK, Ireland, Lisbon", *
'+1' => "West Central Africa, Western Europe", * The variable name must be 'timezones_list', and is an array of possible
'+2' => "Greece, Egypt, parts of Africa", * values, each of which is a value => text pair.
'+3' => "Russia, Baghdad, Kuwait, Nairobi", *
'+3.30' => 'Tehran, Iran', * The text is displayed in a drop-down; the value is returned.
'+4' => "Abu Dhabi, Kabul", *
'+4.30' => 'Afghanistan', * If function timezones_value() exists, it is called to create the displayed
'+5' => "Islamabad, Karachi", * text.
'+5.30' => "Mumbai, Delhi, Calcutta", */
'+5.45' => 'Kathmandu',
'+6' => "Astana, Dhaka",
'+7' => "Bangkok, Rangoon",
'+8' => "Hong Kong, Singapore, Perth, Beijing",
'+9' => "Tokyo, Seoul",
'+9.30' => 'Darwin, Adelaide',
'+10' => "Brisbane, Canberra, Sydney, Melbourne",
'+10.30' => 'Lord Howe Island',
'+11' => "Soloman Islands",
'+11.30' => 'Norfolk Island',
'+12' => "New Zealand, Fiji, Marshall Islands",
'+13' => "Tonga, Nuku'alofa, Rawaki Islands",
'+13.45' => 'Chatham Island',
'+14' => 'Kiribati: Line Islands'
);
private $isEOF = FALSE; // True if at last element of list
private $bufferValid = FALSE;
/** /**
* Call before using the 'next' format option, to ensure the array is indexed from the beginning * Class extended_timezones.
*/
class extended_timezones
{
/**
* @var array
*/
private $timezonesList = array();
/**
* @var bool
*/
private $isEOF = false; // True if at last element of list.
/**
* @var bool
*/
private $bufferValid = false;
/**
* Constructor.
*/
public function __construct()
{
$this->timezonesList = systemTimeZones();
}
/**
* Call before using the 'next' format option, to ensure the array is
* indexed from the beginning.
*/ */
public function pointerReset() public function pointerReset()
{ {
$this->isEOF = (FALSE === reset($this->timezonesList)); $this->isEOF = (false === reset($this->timezonesList));
$this->bufferValid = TRUE; $this->bufferValid = true;
} }
/** /**
* Return a formatted timezone value * Return a formatted timezone value
* *
* @param mixed $key - the key value to select * @param mixed $key
* @param string $formatSpec - defines format of return value * The key value to select.
* @param string $formatSpec
* Defines format of return value.
* *
* @return mixed (according to $formatSpec). FALSE if no value available * @return mixed
* (according to $formatSpec).
* false - if no value available.
* 'array' - a single-element array; key as passed, and value to match key * 'array' - a single-element array; key as passed, and value to match key
* 'next' - as 'array', but ignores the passed $key and moves to next value. * 'next' - as 'array', but ignores the passed $key and moves to next value.
* default - a string usable for display * 'default' - a string usable for display.
*/ */
public function getValue($key, $formatSpec = '') public function getValue($key, $formatSpec = '')
{ {
if($formatSpec == 'next') if($formatSpec == 'next')
{ {
if (!$this->bufferValid) $this->pointerReset; // Make sure buffer is defined // Make sure buffer is defined.
if ($this->isEOF) return FALSE; if(!$this->bufferValid)
{
$this->pointerReset();
}
if($this->isEOF)
{
return false;
}
$key = key($this->timezonesList); $key = key($this->timezonesList);
$val = current($this->timezonesList); $val = current($this->timezonesList);
if (FALSE === $val)
if(false === $val)
{ {
$this->isEOF = TRUE; $this->isEOF = true;
return FALSE; return false;
} }
$this->isEOF = (FALSE === next($this->timezonesList));
$this->isEOF = (false === next($this->timezonesList));
return array($key => $val); return array($key => $val);
} }
$exists = isset($this->timezonesList[$key]); $exists = isset($this->timezonesList[$key]);
if (!$exists) return FALSE;
if(!$exists)
{
return false;
}
$val = $this->timezonesList[$key]; $val = $this->timezonesList[$key];
if($formatSpec == 'array') if($formatSpec == 'array')
{ {
return array($key => $val); return array($key => $val);
} }
// Default (as per earlier implementations) - can be specified with 'display' format // Default (as per earlier implementations) - can be specified with
return 'GMT'.$key.' - '.$val; // 'display' format.
return $val;
} }
} }
?>

View File

@@ -310,7 +310,6 @@ City, State, Country
<core name="subnews_resize"></core> <core name="subnews_resize"></core>
<core name="themecss">style.css</core> <core name="themecss">style.css</core>
<core name="thumbnail_quality">75</core> <core name="thumbnail_quality">75</core>
<core name="time_offset">0</core>
<core name="timezone">UTC</core> <core name="timezone">UTC</core>
<core name="track_online">1</core> <core name="track_online">1</core>
<core name="ue_upgrade">1</core> <core name="ue_upgrade">1</core>

View File

@@ -219,6 +219,13 @@ class e_user_model extends e_admin_model
return ($this->isAdmin() ? $this->get('user_perms') : false); return ($this->isAdmin() ? $this->get('user_perms') : false);
} }
final public function getTimezone()
{
// If timezone is not set, we return an empty string in order to use the
// default timezone is set for e107.
return ($this->get('user_timezone') ? $this->get('user_timezone') : '');
}
/** /**
* DEPRECATED - will be removed or changed soon (see e_session) * DEPRECATED - will be removed or changed soon (see e_session)
* @return string * @return string

View File

@@ -199,7 +199,6 @@ class rssCreate
$sql_rs = new db; $sql_rs = new db;
global $rssgen; global $rssgen;
$sql = e107::getDb(); $sql = e107::getDb();
$pref = e107::getPref();
$tp = e107::getParser(); $tp = e107::getParser();
$this->e107 = e107::getInstance(); $this->e107 = e107::getInstance();
@@ -207,7 +206,6 @@ class rssCreate
$this -> path = e_PLUGIN."rss_menu/"; $this -> path = e_PLUGIN."rss_menu/";
$this -> rssType = $rss_type; $this -> rssType = $rss_type;
$this -> topicid = $topic_id; $this -> topicid = $topic_id;
$this -> offset = $pref['time_offset'] * 3600;
$this -> limit = $row['rss_limit']; $this -> limit = $row['rss_limit'];
$this -> contentType = $row['rss_name']; $this -> contentType = $row['rss_name'];
@@ -422,7 +420,7 @@ class rssCreate
<title>".$tp->toRss($rss_title)."</title> <title>".$tp->toRss($rss_title)."</title>
<link>".$pref['siteurl']."</link> <link>".$pref['siteurl']."</link>
<description>".$tp->toRss($pref['sitedescription'])."</description> <description>".$tp->toRss($pref['sitedescription'])."</description>
<lastBuildDate>".$itemdate = date("r", ($time + $this -> offset))."</lastBuildDate> <lastBuildDate>".$itemdate = date("r", ($time))."</lastBuildDate>
<docs>http://backend.userland.com/rss092</docs>\n"; <docs>http://backend.userland.com/rss092</docs>\n";
foreach($this -> rssItems as $value) foreach($this -> rssItems as $value)
@@ -473,8 +471,8 @@ class rssCreate
<copyright>".$tp->toRss(SITEDISCLAIMER)."</copyright> <copyright>".$tp->toRss(SITEDISCLAIMER)."</copyright>
<managingEditor>".$this->nospam($pref['siteadminemail'])." (".$pref['siteadmin'].")</managingEditor> <managingEditor>".$this->nospam($pref['siteadminemail'])." (".$pref['siteadmin'].")</managingEditor>
<webMaster>".$this->nospam($pref['siteadminemail'])." (".$pref['siteadmin'].")</webMaster> <webMaster>".$this->nospam($pref['siteadminemail'])." (".$pref['siteadmin'].")</webMaster>
<pubDate>".date("r",($time + $this -> offset))."</pubDate> <pubDate>".date("r",($time))."</pubDate>
<lastBuildDate>".date("r",($time + $this -> offset))."</lastBuildDate> <lastBuildDate>".date("r",($time))."</lastBuildDate>
<docs>http://backend.userland.com/rss</docs> <docs>http://backend.userland.com/rss</docs>
<generator>e107 (http://e107.org)</generator> <generator>e107 (http://e107.org)</generator>
<sy:updatePeriod>hourly</sy:updatePeriod> <sy:updatePeriod>hourly</sy:updatePeriod>
@@ -549,7 +547,7 @@ class rssCreate
echo "<enclosure url=\"".$value['enc_url']."\" length=\"".$value['enc_leng']."\" type=\"".$value['enc_type']."\" />\n"; echo "<enclosure url=\"".$value['enc_url']."\" length=\"".$value['enc_leng']."\" type=\"".$value['enc_type']."\" />\n";
} }
echo "<pubDate>".date("r", ($value['pubdate'] + $this -> offset))."</pubDate>\n"; echo "<pubDate>".date("r", ($value['pubdate']))."</pubDate>\n";
if($link) if($link)
{ {
@@ -596,7 +594,7 @@ class rssCreate
<link>".$pref['siteurl']."</link> <link>".$pref['siteurl']."</link>
<description>".$tp->toRss($pref['sitedescription'])."</description> <description>".$tp->toRss($pref['sitedescription'])."</description>
<dc:language>".CORE_LC.(defined("CORE_LC2") ? "-".CORE_LC2 : "")."</dc:language> <dc:language>".CORE_LC.(defined("CORE_LC2") ? "-".CORE_LC2 : "")."</dc:language>
<dc:date>".$this->get_iso_8601_date($time + $this -> offset). "</dc:date> <dc:date>".$this->get_iso_8601_date($time). "</dc:date>
<dc:creator>".$this->nospam($pref['siteadminemail'])."</dc:creator> <dc:creator>".$this->nospam($pref['siteadminemail'])."</dc:creator>
<admin:generatorAgent rdf:resource=\"http://e107.org\" /> <admin:generatorAgent rdf:resource=\"http://e107.org\" />
<admin:errorReportsTo rdf:resource=\"mailto:".$this->nospam($pref['siteadminemail'])."\" /> <admin:errorReportsTo rdf:resource=\"mailto:".$this->nospam($pref['siteadminemail'])."\" />
@@ -629,7 +627,7 @@ class rssCreate
<item rdf:about=\"".$link."\"> <item rdf:about=\"".$link."\">
<title>".$tp->toRss($value['title'])."</title> <title>".$tp->toRss($value['title'])."</title>
<link>".$link."</link> <link>".$link."</link>
<dc:date>".$this->get_iso_8601_date($time + $this -> offset)."</dc:date> <dc:date>".$this->get_iso_8601_date($time)."</dc:date>
<dc:creator>".$value['author']."</dc:creator> <dc:creator>".$value['author']."</dc:creator>
<dc:subject>".$tp->toRss($value['category_name'])."</dc:subject> <dc:subject>".$tp->toRss($value['category_name'])."</dc:subject>
<description>".$tp->toRss($value['description']). "</description> <description>".$tp->toRss($value['description']). "</description>
@@ -653,7 +651,7 @@ class rssCreate
echo " echo "
<id>".$pref['siteurl']."</id>\n <id>".$pref['siteurl']."</id>\n
<title type='text'>".$tp->toRss($rss_title)."</title>\n <title type='text'>".$tp->toRss($rss_title)."</title>\n
<updated>".$this->get_iso_8601_date($time + $this -> offset)."</updated>\n"; <updated>".$this->get_iso_8601_date($time)."</updated>\n";
// Recommended // Recommended
echo " echo "
@@ -689,7 +687,7 @@ class rssCreate
echo " echo "
<id>".$value['link']."</id>\n <id>".$value['link']."</id>\n
<title type='text'>".$tp->toRss($value['title'])."</title>\n <title type='text'>".$tp->toRss($value['title'])."</title>\n
<updated>".$this->get_iso_8601_date($value['pubdate'] + $this -> offset)."</updated>\n"; <updated>".$this->get_iso_8601_date($value['pubdate'])."</updated>\n";
// Recommended // Recommended
$author = ($value['author']) ? $value['author'] : "unknown"; $author = ($value['author']) ? $value['author'] : "unknown";
@@ -713,7 +711,7 @@ class rssCreate
//<contributor> //<contributor>
// <name>Jane Doe</name> // <name>Jane Doe</name>
//</contributor> //</contributor>
echo "<published>".$this->get_iso_8601_date($value['pubdate'] + $this -> offset)."</published>\n"; echo "<published>".$this->get_iso_8601_date($value['pubdate'])."</published>\n";
//<source> //<source>
// <id>http://example.org/</id> // <id>http://example.org/</id>
// <title>Fourty-Two</title> // <title>Fourty-Two</title>