date_timezone.module

Tracking 5.x-2.x branch
  1. drupal
    1. 5 contributions/date/date_timezone/date_timezone.module
    2. 6 contributions/date/date_timezone/date_timezone.module

This module will make the alter the user and site timezone forms to select a timezone name instead of a timezone offset.

This module won't be needed once core starts tracking timezone names instead of offsets.

Functions & methods

NameDescription
date_event_zonelist_by_nameHelper function to update Event module timezone information.
date_timezone_cronUpdate the site timezone offset when cron runs.
date_timezone_form_alterImplementation of hook_form_alter().
date_timezone_menuMake sure a timezone has been selected.
date_timezone_replacementCreate replacement values for deprecated timezone names.
date_timezone_site_formOverride form for the site timezone settings form. Display a list of timezone names instead of offsets and hide the offset value.
date_timezone_update_siteCallback from site timezone settings form to update site timezone info. When the timezone name is updated, update the offset as well.
date_timezone_update_userCallback from user timezone settings form to update user timezone info. When the timezone name is updated, update the offset as well.
date_timezone_userUpdate user timezone information at login.
date_timezone_user_formOverride form for the user timezone settings form. Display a list of timezone names instead of offsets and hide the offset value.
user_timezoneMenu callback; Retrieve a JSON object containing a suggested time zone name.

File

View source
  1. <?php
  2. /**
  3. * @file
  4. * This module will make the alter the user and site timezone forms to
  5. * select a timezone name instead of a timezone offset.
  6. *
  7. * This module won't be needed once core starts tracking timezone names
  8. * instead of offsets.
  9. */
  10. /**
  11. * Make sure a timezone has been selected.
  12. */
  13. function date_timezone_menu($may_cache) {
  14. global $user;
  15. $items = array();
  16. if (!$may_cache) {
  17. $tz_name = variable_get('date_default_timezone_name', NULL);
  18. if (!empty($user->uid) && $_GET['q'] != 'admin/settings/date-time' && (empty($tz_name))) {
  19. drupal_set_message(t('The Date Timezone module requires you to !link.', array('!link' => l(t('set the site timezone name'), 'admin/settings/date-time'))), 'error');
  20. }
  21. $items[] = array(
  22. 'path' => 'user/timezone',
  23. 'title' => 'User timezone',
  24. 'callback' => 'user_timezone',
  25. 'access' => TRUE,
  26. 'type' => MENU_CALLBACK,
  27. );
  28. }
  29. return $items;
  30. }
  31. /**
  32. * Implementation of hook_form_alter().
  33. *
  34. * Override system handling of user and site timezone selection.
  35. */
  36. function date_timezone_form_alter($form_id, &$form) {
  37. if ($form_id == 'system_date_time_settings') {
  38. $form['#process'] = array('date_timezone_site_form' => array());
  39. }
  40. elseif ($form_id == 'user_edit' && variable_get('configurable_timezones', 1) && isset($form['timezone'])) {
  41. $form['#process'] = array('date_timezone_user_form' => array());
  42. }
  43. }
  44. /**
  45. * Override form for the site timezone settings form.
  46. * Display a list of timezone names instead of offsets
  47. * and hide the offset value.
  48. */
  49. function date_timezone_site_form(&$form) {
  50. drupal_add_js(drupal_get_path('module', 'date_timezone') .'/date_timezone.js');
  51. $timezone = variable_get('date_default_timezone_name', NULL);
  52. $form['date_default_timezone'] = array(
  53. '#type' => 'select',
  54. '#title' => t('Default time zone'),
  55. '#default_value' => $timezone,
  56. '#options' => date_timezone_names(FALSE, TRUE), // Force an update before setting a site default.
  57. '#description' => t('Select the default site time zone. If in doubt, choose the timezone that is closest to your location which has the same rules for daylight saving time.'),
  58. '#weight' => -10,
  59. '#validate' => array('date_timezone_update_site' => array()),
  60. '#offset' => variable_get('date_default_timezone', 0),
  61. );
  62. // Add the JavaScript callback to automatically set the timezone.
  63. if (empty($timezone)) {
  64. drupal_add_js('
  65. // Global Killswitch
  66. if (Drupal.jsEnabled) {
  67. $(document).ready(function() {
  68. Drupal.setDefaultTimezone();
  69. });
  70. }', 'inline');
  71. }
  72. return $form;
  73. }
  74. /**
  75. * Override form for the user timezone settings form.
  76. * Display a list of timezone names instead of offsets
  77. * and hide the offset value.
  78. */
  79. function date_timezone_user_form(&$form) {
  80. drupal_add_js(drupal_get_path('module', 'date_timezone') .'/date_timezone.js');
  81. $account = $form['_account']['#value'];
  82. $form['timezone']['#validate'] = array('date_timezone_update_user' => array());
  83. $form['timezone']['#uid'] = $account->uid;
  84. $form['timezone']['timezone']['#type'] = 'hidden';
  85. $form['timezone']['timezone']['#value'] = $form['timezone']['timezone']['#default_value'];
  86. $timezone = $account->timezone_name ? $account->timezone_name : NULL;
  87. $form['timezone']['timezone_name'] = array(
  88. '#type' => 'select',
  89. '#title' => t('Default time zone'),
  90. '#default_value' => $timezone,
  91. '#options' => date_timezone_names(),
  92. '#description' => t('Select your current local time. If in doubt, choose the timezone that is closest to your location which has the same rules for daylight saving time. Dates and times throughout this site will be displayed using this time zone.'),
  93. );
  94. // Add the JavaScript callback to automatically set the timezone.
  95. if (empty($timezone)) {
  96. drupal_add_js('
  97. // Global Killswitch
  98. if (Drupal.jsEnabled) {
  99. $(document).ready(function() {
  100. Drupal.setDefaultTimezone();
  101. });
  102. }', 'inline');
  103. }
  104. return $form;
  105. }
  106. /**
  107. * Callback from site timezone settings form to update site timezone info.
  108. * When the timezone name is updated, update the offset as well.
  109. */
  110. function date_timezone_update_site($element) {
  111. $timezone = $element['#value'];
  112. if (empty($timezone)) {
  113. $offset = $element['#offset'];
  114. }
  115. else {
  116. variable_set('date_default_timezone_name', $timezone);
  117. $date = date_now($timezone);
  118. $offset = date_offset_get($date);
  119. }
  120. // We overrode the event module's form handling, give it back
  121. // the values it expected to find in its submission handler.
  122. if (module_exists('event') && db_table_exists('event_timezones')) {
  123. $event_zone = date_event_zonelist_by_name(str_replace('_', ' ', $timezone));
  124. // The Event module will set its own variable.
  125. if (!empty($event_zone['timezone'])) {
  126. form_set_value($element, $event_zone['timezone'] .'|'. $offset);
  127. } else {
  128. form_set_value($element, $offset);
  129. }
  130. }
  131. // Otherwise set the value the system form handler expects.
  132. else {
  133. form_set_value($element, $offset);
  134. }
  135. }
  136. /**
  137. * Callback from user timezone settings form to update user timezone info.
  138. * When the timezone name is updated, update the offset as well.
  139. */
  140. function date_timezone_update_user($element) {
  141. $timezone = $element['timezone_name']['#value'];
  142. if (!empty($timezone)) {
  143. $date = date_now($timezone);
  144. $offset = date_offset_get($date);
  145. }
  146. else {
  147. $offset = NULL;
  148. }
  149. // We overrode the event module's form handling, give it back
  150. // the values it expected to find in its submission handler.
  151. if (module_exists('event') && db_table_exists('event_timezones')) {
  152. $event_zone = date_event_zonelist_by_name(str_replace('_', ' ', $timezone));
  153. // The Event module will update the user record with the timezone id.
  154. if (!empty($event_zone['timezone'])) {
  155. form_set_value($element['timezone'], $event_zone['timezone'] .'|'. $offset);
  156. } else {
  157. form_set_value($element['timezone'], $offset);
  158. }
  159. }
  160. // Otherwise set the value the system form handler expects.
  161. else {
  162. form_set_value($element['timezone'], $offset);
  163. }
  164. }
  165. /**
  166. * Update the site timezone offset when cron runs.
  167. *
  168. * This is to make sure that modules that rely on the timezone offset
  169. * have current information to process.
  170. */
  171. function date_timezone_cron() {
  172. $date = date_now(variable_get('date_default_timezone_name', NULL));
  173. $offset = date_offset_get($date);
  174. if ($offset != variable_get('date_default_timezone', 0)) {
  175. variable_set('date_default_timezone', $offset);
  176. }
  177. }
  178. /**
  179. * Update user timezone information at login.
  180. *
  181. * This is to make sure that modules that rely on the timezone offset
  182. * have current information to process.
  183. */
  184. function date_timezone_user($op, &$edit, &$account, $category = NULL) {
  185. if ($account->uid && $op == 'login' && variable_get('configurable_timezones', 1)) {
  186. if (strlen($account->timezone_name)) {
  187. $date = date_now($account->timezone_name);
  188. $offset = date_offset_get($date);
  189. if ($offset != $account->timezone) {
  190. $account->timezone = $offset;
  191. db_query("UPDATE {users} SET timezone='%s' WHERE uid = %d", $offset, $account->uid);
  192. }
  193. }
  194. else {
  195. // If the user doesn't already have a timezone name selected,
  196. // default it to the site timezone name and offset.
  197. $timezone = variable_get('date_default_timezone_name', NULL);
  198. if (!empty($timezone)) {
  199. $date = date_now($timezone);
  200. $offset = date_offset_get($date);
  201. db_query("UPDATE {users} SET timezone_name = '%s', timezone='%s' WHERE uid = %d", $timezone, $offset, $account->uid);
  202. }
  203. }
  204. }
  205. }
  206. /**
  207. * Menu callback; Retrieve a JSON object containing a suggested time
  208. * zone name.
  209. */
  210. function user_timezone($abbreviation = '', $offset = -1, $is_daylight_saving_time = NULL) {
  211. // An abbreviation of "0" passed in the callback arguments should be
  212. // interpreted as the empty string.
  213. $abbreviation = $abbreviation ? $abbreviation : '';
  214. $timezone = timezone_name_from_abbr($abbreviation, intval($offset), $is_daylight_saving_time);
  215. // The client date is passed in for debugging purposes.
  216. $date = isset($_GET['date']) ? $_GET['date'] : '';
  217. // Log a debug message.
  218. watchdog('timezone', t('Detected time zone: %timezone; client date: %date; abbreviation: %abbreviation; offset: %offset; daylight saving time: %is_daylight_saving_time.', array('%timezone' => $timezone, '%date' => $date, '%abbreviation' => $abbreviation, '%offset' => $offset, '%is_daylight_saving_time' => $is_daylight_saving_time)));
  219. date_api_json($timezone);
  220. }
  221. /**
  222. * Create replacement values for deprecated timezone names.
  223. */
  224. function date_timezone_replacement($old) {
  225. require_once('./'. drupal_get_path('module', 'date_timezone') .'/date_timezone.install');
  226. return _date_timezone_replacement($old);
  227. }
  228. /**
  229. * Helper function to update Event module timezone information.
  230. */
  231. function date_event_zonelist_by_name($name) {
  232. if (!module_exists('event') || !db_table_exists('event_timezones')) {
  233. return array();
  234. }
  235. static $zone_names = array();
  236. if (!isset($zone_names[$name])) {
  237. $zone = db_fetch_array(db_query("SELECT * FROM {event_timezones} WHERE name = '%s'", $name));
  238. $zone_names[$name] = $zone;
  239. }
  240. return $zone_names[$name];
  241. }