1
0
mirror of https://github.com/e107inc/e107.git synced 2025-08-05 22:27:34 +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();
}
/*
* 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...)
*
* 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.
*
/**
* @addtogroup timezone
* @{
*/
$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;
@@ -1163,6 +1213,10 @@ if (isset($_COOKIE['e107_tzOffset']))
define('TIMEOFFSET', $e_deltaTime);
/**
* @} End of "addtogroup timezone".
*/
// ----------------------------------------------------------------------------
@@ -1723,6 +1777,33 @@ function init_session()
// New user model
$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('POST_REFERER', md5($user->getToken()));

View File

@@ -727,39 +727,11 @@ $text .= "
$text .= "
</td>
</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']))."
";
}
</tr>";
$timeZones = systemTimeZones();
$text .= "
</select>
<div class='smalltext field-help'>".PRFLAN_27."</div>
</td>
</tr>
<tr>
<td><label for='timezone'>".PRFLAN_56."</label></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. ==================

View File

@@ -14,121 +14,136 @@
* $Author$
*/
if (!defined('e107_INIT')) { exit; }
/*
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
if(!defined('e107_INIT'))
{
exit;
}
private $timezonesList = array(
'-12' => "International DateLine West",
'-11' => "Samoa",
'-10' => "Hawaii",
'-9' => "Alaska",
'-8' => "Pacific Time (US and Canada)",
'-7' => "Mountain Time (US and Canada)",
'-6' => "Central Time (US and Canada), Central America",
'-5' => "Eastern Time (US and Canada)",
'-4' => "Atlantic Time (Canada)",
'-3.30' => 'Newfoundland',
'-3' => "Greenland, Brasilia, Buenos Aires, Georgetown",
'-2' => "Mid-Atlantic",
'-1' => "Azores, Cape Verde Islands",
'+0' => "UK, Ireland, Lisbon",
'+1' => "West Central Africa, Western Europe",
'+2' => "Greece, Egypt, parts of Africa",
'+3' => "Russia, Baghdad, Kuwait, Nairobi",
'+3.30' => 'Tehran, Iran',
'+4' => "Abu Dhabi, Kabul",
'+4.30' => 'Afghanistan',
'+5' => "Islamabad, Karachi",
'+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;
/**
* @file
* 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.
*/
/**
* 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()
{
$this->isEOF = (FALSE === reset($this->timezonesList));
$this->bufferValid = TRUE;
$this->isEOF = (false === reset($this->timezonesList));
$this->bufferValid = true;
}
/**
* Return a formatted timezone value
*
* @param mixed $key - the key value to select
* @param string $formatSpec - defines format of return value
* @param mixed $key
* 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
* '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 = '')
{
if($formatSpec == 'next')
{
if (!$this->bufferValid) $this->pointerReset; // Make sure buffer is defined
if ($this->isEOF) return FALSE;
// Make sure buffer is defined.
if(!$this->bufferValid)
{
$this->pointerReset();
}
if($this->isEOF)
{
return false;
}
$key = key($this->timezonesList);
$val = current($this->timezonesList);
if (FALSE === $val)
if(false === $val)
{
$this->isEOF = TRUE;
return FALSE;
$this->isEOF = true;
return false;
}
$this->isEOF = (FALSE === next($this->timezonesList));
$this->isEOF = (false === next($this->timezonesList));
return array($key => $val);
}
$exists = isset($this->timezonesList[$key]);
if (!$exists) return FALSE;
if(!$exists)
{
return false;
}
$val = $this->timezonesList[$key];
if($formatSpec == 'array')
{
return array($key => $val);
}
// Default (as per earlier implementations) - can be specified with 'display' format
return 'GMT'.$key.' - '.$val;
// Default (as per earlier implementations) - can be specified with
// 'display' format.
return $val;
}
}
?>

View File

@@ -310,7 +310,6 @@ City, State, Country
<core name="subnews_resize"></core>
<core name="themecss">style.css</core>
<core name="thumbnail_quality">75</core>
<core name="time_offset">0</core>
<core name="timezone">UTC</core>
<core name="track_online">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);
}
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)
* @return string

View File

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