diff --git a/class2.php b/class2.php index e6da00ccd..3bc8d65ac 100644 --- a/class2.php +++ b/class2.php @@ -1127,27 +1127,77 @@ 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. -* -*/ - -$tz = vartrue($pref['timezone'], 'UTC'); //TODO Adjust on the front-end based on user timezone value. - -date_default_timezone_set($tz); // Must be set or PHP Warning thrown. - -unset($tz); -$e_deltaTime=0; +/** + * @addtogroup timezone + * @{ + */ + +/** + * 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(); + + // If Timezone list is not populated yet. + if(empty($zones)) + { + $zonelist = timezone_identifiers_list(); + $timeNow = date('m/d/Y H:i', $_SERVER['REQUEST_TIME']); + + 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; if (isset($_COOKIE['e107_tdOffset'])) { @@ -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())); diff --git a/e107_admin/prefs.php b/e107_admin/prefs.php index 6178bd11c..180588451 100644 --- a/e107_admin/prefs.php +++ b/e107_admin/prefs.php @@ -727,39 +727,11 @@ $text .= " $text .= " - - - - - ".$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 .= " - -
".PRFLAN_27."
- - @@ -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. ================== diff --git a/e107_core/sql/extended_timezones.php b/e107_core/sql/extended_timezones.php index 24955ade9..871aabc4c 100644 --- a/e107_core/sql/extended_timezones.php +++ b/e107_core/sql/extended_timezones.php @@ -14,121 +14,136 @@ * $Author$ */ -if (!defined('e107_INIT')) { exit; } +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'. +/** + * @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. + */ -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. + */ class extended_timezones { - 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; - + /** + * @var array + */ + private $timezonesList = array(); /** - * Call before using the 'next' format option, to ensure the array is indexed from the beginning + * @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 + * 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 - * '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 + * @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. */ public function getValue($key, $formatSpec = '') { - if ($formatSpec == 'next') + 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') + + 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; } } - - -?> \ No newline at end of file diff --git a/e107_core/xml/default_install.xml b/e107_core/xml/default_install.xml index cd1f717f1..18fd42cdf 100644 --- a/e107_core/xml/default_install.xml +++ b/e107_core/xml/default_install.xml @@ -310,7 +310,6 @@ City, State, Country style.css 75 - 0 UTC 1 1 diff --git a/e107_handlers/user_model.php b/e107_handlers/user_model.php index cad0e4f34..b0e9b2b78 100644 --- a/e107_handlers/user_model.php +++ b/e107_handlers/user_model.php @@ -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 diff --git a/e107_plugins/rss_menu/rss.php b/e107_plugins/rss_menu/rss.php index 3175f1881..42c345369 100644 --- a/e107_plugins/rss_menu/rss.php +++ b/e107_plugins/rss_menu/rss.php @@ -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 ".$tp->toRss($rss_title)." ".$pref['siteurl']." ".$tp->toRss($pref['sitedescription'])." - ".$itemdate = date("r", ($time + $this -> offset))." + ".$itemdate = date("r", ($time))." http://backend.userland.com/rss092\n"; foreach($this -> rssItems as $value) @@ -473,8 +471,8 @@ class rssCreate ".$tp->toRss(SITEDISCLAIMER)." ".$this->nospam($pref['siteadminemail'])." (".$pref['siteadmin'].") ".$this->nospam($pref['siteadminemail'])." (".$pref['siteadmin'].") - ".date("r",($time + $this -> offset))." - ".date("r",($time + $this -> offset))." + ".date("r",($time))." + ".date("r",($time))." http://backend.userland.com/rss e107 (http://e107.org) hourly @@ -549,7 +547,7 @@ class rssCreate echo "\n"; } - echo "".date("r", ($value['pubdate'] + $this -> offset))."\n"; + echo "".date("r", ($value['pubdate']))."\n"; if($link) { @@ -596,7 +594,7 @@ class rssCreate ".$pref['siteurl']." ".$tp->toRss($pref['sitedescription'])." ".CORE_LC.(defined("CORE_LC2") ? "-".CORE_LC2 : "")." - ".$this->get_iso_8601_date($time + $this -> offset). " + ".$this->get_iso_8601_date($time). " ".$this->nospam($pref['siteadminemail'])." nospam($pref['siteadminemail'])."\" /> @@ -629,7 +627,7 @@ class rssCreate ".$tp->toRss($value['title'])." ".$link." - ".$this->get_iso_8601_date($time + $this -> offset)." + ".$this->get_iso_8601_date($time)." ".$value['author']." ".$tp->toRss($value['category_name'])." ".$tp->toRss($value['description']). " @@ -653,7 +651,7 @@ class rssCreate echo " ".$pref['siteurl']."\n ".$tp->toRss($rss_title)."\n - ".$this->get_iso_8601_date($time + $this -> offset)."\n"; + ".$this->get_iso_8601_date($time)."\n"; // Recommended echo " @@ -689,7 +687,7 @@ class rssCreate echo " ".$value['link']."\n ".$tp->toRss($value['title'])."\n - ".$this->get_iso_8601_date($value['pubdate'] + $this -> offset)."\n"; + ".$this->get_iso_8601_date($value['pubdate'])."\n"; // Recommended $author = ($value['author']) ? $value['author'] : "unknown"; @@ -713,7 +711,7 @@ class rssCreate // // Jane Doe // - echo "".$this->get_iso_8601_date($value['pubdate'] + $this -> offset)."\n"; + echo "".$this->get_iso_8601_date($value['pubdate'])."\n"; // // http://example.org/ // Fourty-Two