Gravity Wiz // Gravity Forms User Timezone Converter
<?php
/**
* Gravity Forms User Timezone Converter
*
* Converts the date-based values/labels of a any choice-based field (i.e. selects, radios) to the user's timezone.
* The value/label of the field must be parseable by PHPs strtotime function.
*
* A thank you to Stack Overflow for this article:
* http://stackoverflow.com/questions/4186868/convert-timestamp-to-timezones
*
* @author David Smith <david@gravitywiz.com>
* @license GPL-2.0+
* @link http://gravitywiz.com/...
* @copyright 2013 Gravity Wiz
*/
class GWUserTimezoneConverter {
var $use_user_timezone = false;
var $field_timestamps = array();
function __construct( $args ) {
$this->_args = wp_parse_args( $args, array(
'form_id' => false,
'field_id' => false,
'format' => 'm/d/y',
'notifications' => array()
) );
extract( $this->_args ); // gives us $form_id, $field_id, and $format
if( ! $form_id || ! $field_id )
return;
add_filter( 'wp', array( $this, 'set_user_timezone' ) );
add_filter( 'gform_pre_render_' . $form_id, array( $this, 'pre_render' ) );
add_filter( 'gform_get_input_value', array( $this, 'format_timestamp' ), 10, 3 );
// set/reset flag to determine when to use user timezone
add_filter( 'gform_notification_' . $form_id, array( $this, 'maybe_set_use_user_timezone_flag' ) );
add_action( 'gform_after_email', array( $this, 'reset_use_user_timezone_flag' ) );
add_filter( 'gform_merge_tag_filter', array( $this, 'maybe_reformat_timestamp' ), 10, 4 );
}
function pre_render( $form ) {
$user_timezone = $this->get_user_timezone();
if( ! $user_timezone )
return $form;
foreach( $form['fields'] as &$field ) {
if( $field['id'] != $this->_args['field_id'] )
continue;
foreach( $field['choices'] as &$choice ) {
$date = $choice['value'];
if( ! $date )
continue;
$server_timezone = get_option( 'timezone_string' );
if( ! $server_timezone )
$server_timezone = 'UTC';
$utc_timestamp = strtotime( $date );
$server_datetime = new DateTime( date( 'Y-m-d H:i:s', $utc_timestamp ), new DateTimeZone( $server_timezone ) );
// be aware $server_datetime is still modified by any manipulation down to $user_datetime
$user_datetime = $server_datetime;
$user_datetime->setTimezone( new DateTimeZone( $user_timezone ) );
$choice['text'] = $user_datetime->format( $this->_args['format'] );
$choice['value'] = $utc_timestamp;
}
}
return $form;
}
function set_user_timezone() {
if( $this->get_user_timezone() )
return;
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_timezone_script' ) );
add_action( 'wp_footer', array( $this, 'init_timezone_script' ) );
}
function enqueue_timezone_script() {
wp_enqueue_script( 'jstz', '//cdnjs.cloudflare.com/ajax/libs/jstimezonedetect/1.0.4/jstz.min.js', array(), '1.0.4', false );
}
function init_timezone_script() {
?>
<script type="text/javascript">
var tz = jstz.determine(),
exDate = new Date(),
exDays = 60,
value = null;
exDate.setDate( exDate.getDate() + exDays );
value = escape( tz.name() ) + '; expires=' + exDate.toUTCString();
document.cookie = 'gwutc_user_timezone=' + value + '; path=/';
</script>
<?php
}
function get_user_timezone() {
return rgar( $_COOKIE, 'gwutc_user_timezone' );
}
function format_timestamp( $value, $lead, $field ) {
if( ! $this->is_applicable_field( $field ) || ! $this->is_timestamp( $value ) )
return $value;
$utc_timestamp = $value;
$this->field_timestamps[$field['id']] = $utc_timestamp;
$server_datetime = new DateTime( date( 'Y-m-d H:i:s', $utc_timestamp ), new DateTimeZone( get_option( 'timezone_string' ) ) );
if( $this->use_user_timezone ) {
$user_timedate = $server_datetime;
$user_timedate->setTimezone( new DateTimeZone( $this->get_user_timezone() ) );
$value = $user_timedate->format( $this->_args['format'] );
} else {
$value = $server_datetime->format( $this->_args['format'] );
}
return $value;
}
function maybe_reformat_timestamp( $value, $lead, $options, $field ) {
if( $this->is_applicable_field( $field ) && $this->use_user_timezone ) {
$value = $this->format_timestamp( $this->field_timestamps[$field['id']], $lead, $field );
}
return $value;
}
function is_applicable_field( $field ) {
if( $field['formId'] != $this->_args['form_id'] )
return false;
if( $field['id'] != $this->_args['field_id'] )
return false;
return true;
}
function maybe_set_use_user_timezone_flag( $notification ) {
if( ! in_array( $notification['name'], $this->_args['notifications'] ) )
return $notification;
$this->use_user_timezone = true;
return $notification;
}
function reset_use_user_timezone_flag() {
$this->user_user_timezone = false;
}
function is_timestamp( $timestamp ) {
return ( (string) (int) $timestamp === $timestamp )
&& ( $timestamp <= PHP_INT_MAX )
&& ( $timestamp >= ~PHP_INT_MAX );
}
}