diff --git a/clock.js b/clock.js index 4bd74aa..f187d24 100644 --- a/clock.js +++ b/clock.js @@ -18,18 +18,24 @@ Drupal.behaviors.clockDisplay = { // Whether or not to update the clock continuously. var update = Drupal.settings['update']; // Whether or not to use the user's local time zone. - var local = Drupal.settings['local'] - // Creates a JavaScript date object, from a specially formatted date string. - // Note that due to JavaScript's inferior time zone handling, time zone - // related date formatters will return the time zone of the Drupal site, not - // the visiting user if the time zone is set to 'Local'. - var date = (Drupal.settings['local'] == 1) ? new Date() : new Date(Drupal.settings['time']); + var local = Drupal.settings['local']; // The name of the offset, e.g. 'GMT'. var offsetName = Drupal.settings['offset_name']; // The time zone offset in seconds. var offsetSeconds = Drupal.settings['offset_seconds']; // Daylight Savings Time information. '1' for yes, '0' for no. var daylightSavingsTime = Drupal.settings['daylight_savings_time']; + // Creates a JavaScript date object, by calculating the difference between + // the target offset and the current offset and adding that to the current + // time. + // Note that due to JavaScript's inferior time zone handling, time zone + // related date formatters will return the time zone of the Drupal site, not + // the visiting user if the time zone is set to 'Local'. + var date = new Date(); + // JavaScript returns the time zone offset reversely signed as PHP, + // therefore we calculate the difference in the absolute values, by adding + // the two numbers. + date = new Date(date.getTime() + (offsetSeconds/60 + date.getTimezoneOffset())*60000); // Create an array containing month names. var monthNames = new Array(); diff --git a/clock.module b/clock.module index e7bb5a3..0e14b16 100755 --- a/clock.module +++ b/clock.module @@ -1,276 +1,275 @@ -' . t('About') . ''; - $output .= '

' . t('Clock module allows the display of a clock on your site.') . '

'; - $output .= '

' . t('Uses') . '

'; - $output .= '
'; - $output .= '
' . t('Administering the clock') . '
'; - $output .= '
' . t('Since the clock is a block, it can be administered via its block settings page which is accessible from the block administration page. In addition to the usual block configuration options there are a number of options.', array( - '@clock-settings' => url('admin/structure/block/manage/clock/clock/configure'), - '@block-admin' => url('admin/structure/block'), - )) . '
'; - $output .= '
'; - $output .= '
' . t('Time zone') . '
'; - $output .= '
' . t('The time zone of the clock.') . '
'; - $output .= '
'; - $output .= '
' . t('Site time zone') . '
'; - $output .= '
' . t('The time zone that has been set on the regional settings page.', array( - '@regional-admin' => url('admin/config/regional/settings'), - )) . '
'; - $output .= '
' . t('User time zone') . '
'; - $output .= '
' . t('This option will only show up, if user-configurable time zones are enabled. The time zone the user has selected.') . '
'; - $output .= '
' . t('Local time zone') . '
'; - $output .= '
' . t('The local time zone on the computer of the visiting user (anonymous and authenticated). Since JavaScript is used to calculate this time, it falls back to the site time zone if the visitor has JavaScript disabled.'); - $output .= '
' . t('Custom time zone') . '
'; - $output .= '
' . t('A custom time zone that can be selected in the select box below the radio buttons.') . '
'; - $output .= '
'; - $output .= '
' . t('Date format') . '
'; - $output .= '
' . t('The date format that the clock is to be displayed in. All of the date types that have been set on the date and time settings page are available here.', array( - '@format-admin' => url('admin/config/regional/date-time'), - )) . '
'; - $output .= '
' . t('JavaScript updating') . '
'; - $output .= '
' . t('Whether or not the clock should be updated continuously via JavaScript. This is especially useful if seconds are displayed. It only works if the visitor has JavaScript enabled.') . '
'; - $output .= '
'; - $output .= '
'; - return $output; - } -} - -/** - * Implements hook_block_info(). - */ -function clock_block_info() { - $blocks['clock'] = array( - 'info' => t('Clock'), - // The clock needs to be updated continuously and should not be cached. - 'cache' => DRUPAL_NO_CACHE, - ); - return $blocks; -} - -/** - * Implement hook_block_configure(). - */ -function clock_block_configure($delta = '') { - if ($delta == 'clock') { - - // Time zone options. - $time_zone = variable_get('clock_time_zone', 2); - // If the time zone is not set to the integer values 1, 2 or 3 corresponding - // to 'Site time zone', 'User time zone' and 'Local time zone' it contains - // the name of a custom time zone, so the time zone type must be set to - // integer value 4. - $time_zone_type = ($time_zone === 1 || $time_zone === 2 || $time_zone === 3) ? $time_zone : 4; - $custom_time_zone = ($time_zone_type === 4) ? $time_zone : 'UTC'; - $form['time_zone_type'] = array( - '#type' => 'radios', - '#title' => t('Time zone settings'), - '#description' => t('Local time zone is the time zone on the operating system of the person visiting (regardless of anonymous or authenticated).'), - '#options' => array( - 1 => t('Site time zone'), - 3 => t('Local time zone'), - 4 => t('Custom time zone'), - ), - '#default_value' => $time_zone_type, - ); - // In case of user-configurable timezones show it as an option. - if (variable_get('configurable_timezones', 1) == 1) { - $form['time_zone_type']['#options'][2] = t('User time zone'); - $form['time_zone_type']['#description'] = t('User time zone is the time zone the Drupal user has selected on his or her profile page. Local time zone is the time zone on the operating system of the person visiting (regardless of anonymous or authenticated).'); - // Make the "User time zone" option appear second. - ksort($form['time_zone_type']['#options']); - } - // date_timezone_names() returns an empty first row. - $time_zone_names = date_timezone_names(); - array_shift($time_zone_names); - $form['time_zone_custom'] = array( - '#type' => 'select', - '#options' => $time_zone_names, - '#default_value' => $custom_time_zone, - // Show the select list only if "Custom time zone" is selected. - '#states' => array( - 'visible' => array( - ':input[name="time_zone_type"]' => array('value' => "4"), - ), - ), - ); - - // Date type options. - // Format the current time with each date type for display in the form. If - // the user has changed the time zone since the last page load, - // the formatted time is displayed in the wrong, old time zone. - $date_types = array(); - foreach (system_get_date_types() as $date_type => $info) { - // Each date format type has a corresponding variable. If it is not set, - // get the list of date formats for that type and use the first one. - $date_format = variable_get('date_format_' . $date_type, key(system_get_date_formats($date_type))); - $date_types[$date_type] = $info['title'] . ' (' . date_format_date(date_now(_clock_get_timezone()), 'custom', $date_format) . ')'; - } - $form['date_type'] = array( - '#type' => 'radios', - '#title' => t('Date type'), - '#description' => t('You can configure these date types on the date and time configuration page.', array('@date-and-time-admin' => url('admin/config/regional/date-time'))), - '#weight' => 3, - '#default_value' => variable_get('clock_date_type', 'long'), - '#options' => $date_types, - ); - - // Update options. - $form['update'] = array( - '#type' => 'checkbox', - '#title' => t('Update the clock every second'), - '#description' => t('This only works with JavaScript enabled.'), - '#weight' => 5, - '#default_value' => variable_get('clock_update', '1'), - ); - - return $form; - } -} - -/** - * Implements hook_block_save(). - */ -function clock_block_save($delta = '', $edit = array()) { - if ($delta == 'clock') { - // If the time zone type is 'Custom time zone' store the name of the custom - // time zone in $time_zone. Otherwise, store the value of the time zone - // type. - $time_zone = ($edit['time_zone_type'] == 4) ? $edit['time_zone_custom'] : $edit['time_zone_type']; - variable_set('clock_time_zone', $time_zone); - variable_set('clock_date_type', $edit['date_type']); - variable_set('clock_update', $edit['update']); - return; - } -} - -/** - * Implements hook_block_view(). - */ -function clock_block_view($delta = '') { - if ($delta == 'clock') { - $block = array(); - $block['subject'] = t('Clock'); - $block['content'] = array( - '#theme' => 'clock', - '#time_zone' => _clock_get_timezone(), - '#date_format' => _clock_get_date_format(), - '#update' => variable_get('clock_update', 1), - ); - return $block; - } -} - -/** - * Gets the correct timezone to display. - * - * @return - * The name of the timezone, NULL if the user's time zone is to be used or - * 'Local' if the user's local time is to be used. - */ -function _clock_get_timezone() { - $time_zone = variable_get('clock_time_zone', 2); - switch ($time_zone) { - // Site time zone. - case 1: - $time_zone = variable_get('date_default_timezone', 'UTC'); - break; - // User time zone. - case 2: - $time_zone = NULL; - break; - // Local time zone. - case 3: - $time_zone = 'Local'; - break; - } - // If the time zone type is 'Custom time zone', $time_zone directly contains - // the name of the time zone. - return $time_zone; -} - -/** - * Gets the correct date format. - * - * @return - * The date format of the date type used for the clock. - */ -function _clock_get_date_format() { - $date_type = variable_get('clock_date_type', 'long'); - // Each date format type has a corresponding variable. If it is not set, get - // the list of date formats for that type and use the first one. - $date_format = variable_get('date_format_' . $date_type, key(system_get_date_formats($date_type))); - return $date_format; -} - -/** - * Implements hook_theme. - */ -function clock_theme() { - return array( - 'clock' => array( - 'variables' => array( - 'time_zone' => NULL, - 'date_format' => '', - 'update' => 1, - ), - ), - ); -} - -/* - * Provide a default implementation of theme_clock(). - */ -function theme_clock($variables) { - // Initialize the variables. - $time_zone = $variables['time_zone']; - $date_format = $variables['date_format']; - $update = $variables['update']; - - if ($time_zone == 'Local' || $update == 1) { - - $local = 0; - if ($time_zone == 'Local') { - $local = 1; - // Use the site time zone as a fallback for non-JavaScript users. - $time_zone = variable_get('date_default_timezone', 'UTC'); - } - - drupal_add_js(drupal_get_path('module', 'clock') . '/clock.js'); - - // Pass the needed variables to JavaScript. - // Create a time string, from which JavaScript can create a date. The time - // string contains the month name, which needs to be in English. - $time = date_format_date(date_now($time_zone), 'custom', 'F j, Y H:i:s', 'en'); - // Get the name of the offset, e.g. 'GMT'. - $offset_name = date_format_date(date_now($time_zone), 'custom', 'T'); - // Get the time zone offset in seconds. - $offset_seconds = date_format_date(date_now($time_zone), 'custom', 'Z'); - // Get Daylight Savings Time information. '1' for yes, '0' for no. - $daylight_savings_time = date_format_date(date_now($time_zone), 'custom', 'I'); - drupal_add_js(array( - 'time_zone' => $time_zone, - 'date_format' => $date_format, - 'update' => $update, - 'local' => $local, - 'time' => $time, - 'offset_name' => $offset_name, - 'offset_seconds' => $offset_seconds, - 'daylight_savings_time' => $daylight_savings_time, - ), 'setting'); - - } - - // Create a date object with the correct timezone and format it with the correct date format. - $clock = date_format_date(date_now($time_zone), 'custom', $date_format); - - return '
' . $clock . '
'; -} - +' . t('About') . ''; + $output .= '

' . t('Clock module allows the display of a clock on your site.') . '

'; + $output .= '

' . t('Uses') . '

'; + $output .= '
'; + $output .= '
' . t('Administering the clock') . '
'; + $output .= '
' . t('Since the clock is a block, it can be administered via its block settings page which is accessible from the block administration page. In addition to the usual block configuration options there are a number of options.', array( + '@clock-settings' => url('admin/structure/block/manage/clock/clock/configure'), + '@block-admin' => url('admin/structure/block'), + )) . '
'; + $output .= '
'; + $output .= '
' . t('Time zone') . '
'; + $output .= '
' . t('The time zone of the clock.') . '
'; + $output .= '
'; + $output .= '
' . t('Site time zone') . '
'; + $output .= '
' . t('The time zone that has been set on the regional settings page.', array( + '@regional-admin' => url('admin/config/regional/settings'), + )) . '
'; + $output .= '
' . t('User time zone') . '
'; + $output .= '
' . t('This option will only show up, if user-configurable time zones are enabled. The time zone the user has selected.') . '
'; + $output .= '
' . t('Local time zone') . '
'; + $output .= '
' . t('The local time zone on the computer of the visiting user (anonymous and authenticated). Since JavaScript is used to calculate this time, it falls back to the site time zone if the visitor has JavaScript disabled.'); + $output .= '
' . t('Custom time zone') . '
'; + $output .= '
' . t('A custom time zone that can be selected in the select box below the radio buttons.') . '
'; + $output .= '
'; + $output .= '
' . t('Date format') . '
'; + $output .= '
' . t('The date format that the clock is to be displayed in. All of the date types that have been set on the date and time settings page are available here.', array( + '@format-admin' => url('admin/config/regional/date-time'), + )) . '
'; + $output .= '
' . t('JavaScript updating') . '
'; + $output .= '
' . t('Whether or not the clock should be updated continuously via JavaScript. This is especially useful if seconds are displayed. It only works if the visitor has JavaScript enabled.') . '
'; + $output .= '
'; + $output .= '
'; + return $output; + } +} + +/** + * Implements hook_block_info(). + */ +function clock_block_info() { + $blocks['clock'] = array( + 'info' => t('Clock'), + // The clock needs to be updated continuously and should not be cached. + 'cache' => DRUPAL_NO_CACHE, + ); + return $blocks; +} + +/** + * Implement hook_block_configure(). + */ +function clock_block_configure($delta = '') { + if ($delta == 'clock') { + + // Time zone options. + $time_zone = variable_get('clock_time_zone', 2); + // If the time zone is not set to the integer values 1, 2 or 3 corresponding + // to 'Site time zone', 'User time zone' and 'Local time zone' it contains + // the name of a custom time zone, so the time zone type must be set to + // integer value 4. + $time_zone_type = ($time_zone === 1 || $time_zone === 2 || $time_zone === 3) ? $time_zone : 4; + $custom_time_zone = ($time_zone_type === 4) ? $time_zone : 'UTC'; + $form['time_zone_type'] = array( + '#type' => 'radios', + '#title' => t('Time zone settings'), + '#description' => t('Local time zone is the time zone on the operating system of the person visiting (regardless of anonymous or authenticated).'), + '#options' => array( + 1 => t('Site time zone'), + 3 => t('Local time zone'), + 4 => t('Custom time zone'), + ), + '#default_value' => $time_zone_type, + ); + // In case of user-configurable timezones show it as an option. + if (variable_get('configurable_timezones', 1) == 1) { + $form['time_zone_type']['#options'][2] = t('User time zone'); + $form['time_zone_type']['#description'] = t('User time zone is the time zone the Drupal user has selected on his or her profile page. Local time zone is the time zone on the operating system of the person visiting (regardless of anonymous or authenticated).'); + // Make the "User time zone" option appear second. + ksort($form['time_zone_type']['#options']); + } + // date_timezone_names() returns an empty first row. + $time_zone_names = date_timezone_names(); + array_shift($time_zone_names); + $form['time_zone_custom'] = array( + '#type' => 'select', + '#options' => $time_zone_names, + '#default_value' => $custom_time_zone, + // Show the select list only if "Custom time zone" is selected. + '#states' => array( + 'visible' => array( + ':input[name="time_zone_type"]' => array('value' => "4"), + ), + ), + ); + + // Date type options. + // Format the current time with each date type for display in the form. If + // the user has changed the time zone since the last page load, + // the formatted time is displayed in the wrong, old time zone. + $date_types = array(); + foreach (system_get_date_types() as $date_type => $info) { + // Each date format type has a corresponding variable. If it is not set, + // get the list of date formats for that type and use the first one. + $date_format = variable_get('date_format_' . $date_type, key(system_get_date_formats($date_type))); + $date_types[$date_type] = $info['title'] . ' (' . date_format_date(date_now(_clock_get_timezone()), 'custom', $date_format) . ')'; + } + $form['date_type'] = array( + '#type' => 'radios', + '#title' => t('Date type'), + '#description' => t('You can configure these date types on the date and time configuration page.', array('@date-and-time-admin' => url('admin/config/regional/date-time'))), + '#weight' => 3, + '#default_value' => variable_get('clock_date_type', 'long'), + '#options' => $date_types, + ); + + // Update options. + $form['update'] = array( + '#type' => 'checkbox', + '#title' => t('Update the clock every second'), + '#description' => t('This only works with JavaScript enabled.'), + '#weight' => 5, + '#default_value' => variable_get('clock_update', '1'), + ); + + return $form; + } +} + +/** + * Implements hook_block_save(). + */ +function clock_block_save($delta = '', $edit = array()) { + if ($delta == 'clock') { + // If the time zone type is 'Custom time zone' store the name of the custom + // time zone in $time_zone. Otherwise, store the value of the time zone + // type. + $time_zone = ($edit['time_zone_type'] == 4) ? $edit['time_zone_custom'] : $edit['time_zone_type']; + variable_set('clock_time_zone', $time_zone); + variable_set('clock_date_type', $edit['date_type']); + variable_set('clock_update', $edit['update']); + return; + } +} + +/** + * Implements hook_block_view(). + */ +function clock_block_view($delta = '') { + if ($delta == 'clock') { + $block = array(); + $block['subject'] = t('Clock'); + $block['content'] = array( + '#theme' => 'clock', + '#time_zone' => _clock_get_timezone(), + '#date_format' => _clock_get_date_format(), + '#update' => variable_get('clock_update', 1), + ); + return $block; + } +} + +/** + * Gets the correct timezone to display. + * + * @return + * The name of the timezone, NULL if the user's time zone is to be used or + * 'Local' if the user's local time is to be used. + */ +function _clock_get_timezone() { + $time_zone = variable_get('clock_time_zone', 2); + switch ($time_zone) { + // Site time zone. + case 1: + $time_zone = variable_get('date_default_timezone', 'UTC'); + break; + // User time zone. + case 2: + $time_zone = NULL; + break; + // Local time zone. + case 3: + $time_zone = 'Local'; + break; + } + // If the time zone type is 'Custom time zone', $time_zone directly contains + // the name of the time zone. + return $time_zone; +} + +/** + * Gets the correct date format. + * + * @return + * The date format of the date type used for the clock. + */ +function _clock_get_date_format() { + $date_type = variable_get('clock_date_type', 'long'); + // Each date format type has a corresponding variable. If it is not set, get + // the list of date formats for that type and use the first one. + $date_format = variable_get('date_format_' . $date_type, key(system_get_date_formats($date_type))); + return $date_format; +} + +/** + * Implements hook_theme. + */ +function clock_theme() { + return array( + 'clock' => array( + 'variables' => array( + 'time_zone' => NULL, + 'date_format' => '', + 'update' => 1, + ), + ), + ); +} + +/* + * Provide a default implementation of theme_clock(). + */ +function theme_clock($variables) { + // Initialize the variables. + $time_zone = $variables['time_zone']; + $date_format = $variables['date_format']; + $update = $variables['update']; + + if ($time_zone == 'Local' || $update == 1) { + + $local = 0; + if ($time_zone == 'Local') { + $local = 1; + // Use the site time zone as a fallback for non-JavaScript users. + $time_zone = variable_get('date_default_timezone', 'UTC'); + } + + drupal_add_js(drupal_get_path('module', 'clock') . '/clock.js'); + + // Pass the needed variables to JavaScript. + // Create a time string, from which JavaScript can create a date. The time + // string contains the month name, which needs to be in English. + $time = date_format_date(date_now($time_zone), 'custom', 'F j, Y H:i:s', 'en'); + // Get the name of the offset, e.g. 'GMT'. + $offset_name = date_format_date(date_now($time_zone), 'custom', 'T'); + // Get the time zone offset in seconds. + $offset_seconds = date_format_date(date_now($time_zone), 'custom', 'Z'); + // Get Daylight Savings Time information. '1' for yes, '0' for no. + $daylight_savings_time = date_format_date(date_now($time_zone), 'custom', 'I'); + drupal_add_js(array( + 'time_zone' => $time_zone, + 'date_format' => $date_format, + 'update' => $update, + 'local' => $local, + 'offset_name' => $offset_name, + 'offset_seconds' => $offset_seconds, + 'daylight_savings_time' => $daylight_savings_time, + ), 'setting'); + + } + + // Create a date object with the correct timezone and format it with the correct date format. + $clock = date_format_date(date_now($time_zone), 'custom', $date_format); + + return '
' . $clock . '
'; +} +