Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use local timezone when formatting Time fields #2107

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 45 additions & 52 deletions includes/class-gravityview-merge-tags.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,15 +95,10 @@ public static function process_modifiers( $value, $merge_tag, $modifier, $field,

// matching regex => the value is the method to call to replace the value.
$gv_modifiers = array(
'maxwords:(\d+)' => 'modifier_maxwords',
/** @see modifier_maxwords */
'timestamp' => 'modifier_timestamp',
/** @see modifier_timestamp */
'explode' => 'modifier_explode',
/** @see modifier_explode */

/** @see modifier_strings */
'urlencode' => 'modifier_strings',
'maxwords:(\d+)' => 'modifier_maxwords', /** @see modifier_maxwords */
'timestamp' => 'modifier_timestamp', /** @see modifier_timestamp */
'explode' => 'modifier_explode', /** @see modifier_explode */
'urlencode' => 'modifier_strings', /** @see modifier_strings */
'wpautop' => 'modifier_strings',
'esc_html' => 'modifier_strings',
'sanitize_html_class' => 'modifier_strings',
Expand All @@ -113,7 +108,7 @@ public static function process_modifiers( $value, $merge_tag, $modifier, $field,
'ucfirst' => 'modifier_strings',
'ucwords' => 'modifier_strings',
'wptexturize' => 'modifier_strings',
'format' => 'modifier_format',
'format' => 'modifier_format', /** @see modifier_format */
);

$modifiers = explode( ',', $modifier );
Expand Down Expand Up @@ -181,7 +176,17 @@ public static function process_modifiers( $value, $merge_tag, $modifier, $field,
* @return string
*/
private static function modifier_format( $raw_value, $matches, $value, $field, $modifier ) {
if ( ( $field instanceof GF_Field_Date || $field instanceof GF_Field_Time ) && $modifier ) {
$format = self::get_format_merge_tag_modifier_value( $modifier );

if ( ! $format ) {
return $raw_value;
}

if ( $field instanceof GF_Field_Time ) {
return ( new DateTime( $raw_value ) )->format( $format ); // GF's Time field always uses local time.
}

if ( $field instanceof GF_Field_Date ) {
return self::format_date( $raw_value, $modifier );
}

Expand Down Expand Up @@ -578,63 +583,51 @@ public static function replace_entry_link( $original_text, $form = array(), $ent
}

/**
* Format Merge Tags using GVCommon::format_date()
* Formats merge tag value using Merge Tags using GVCommon::format_date()
*
* @todo This is no longer needed since Gravity Forms 2.5 as it supports modifiers, but should be reviewed before removal.
*
* @uses GVCommon::format_date()
* @since 1.16
*
* @see https://docs.gravitykit.com/article/331-date-created-merge-tag for documentation
* @todo Once Gravity Forms 2.5 becomes the minimum requirement, this is no longer needed.
* @see https://docs.gravitykit.com/article/331-date-created-merge-tag for documentation
* @uses GVCommon::format_date()
*
* @param string $date_created The Gravity Forms date created format
* @param string $property Any modifiers for the merge tag (`human`, `format:m/d/Y`)
* @param string $date_or_time_string The Gravity Forms date or time string.
* @param string $modifier Merge tag modifier (`human`, `format:m/d/Y`)
*
* @return int|string If timestamp requested, timestamp int. Otherwise, string output.
*/
public static function format_date( $date_created = '', $property = '' ) {

// Expand all modifiers, skipping escaped colons. str_replace worked better than preg_split( "/(?<!\\):/" )
$exploded = explode( ':', str_replace( '\:', '|COLON|', $property ) );

$atts = array(
'format' => self::get_format_from_modifiers( $exploded, false ),
'human' => in_array( 'human', $exploded ), // {date_created:human}
'diff' => in_array( 'diff', $exploded ), // {date_created:diff}
'raw' => in_array( 'raw', $exploded ), // {date_created:raw}
'timestamp' => in_array( 'timestamp', $exploded ), // {date_created:timestamp}
'time' => in_array( 'time', $exploded ), // {date_created:time}
);

$formatted_date = GVCommon::format_date( $date_created, $atts );

return $formatted_date;
public static function format_date( $date_or_time_string = '', $modifier = '' ) {
$parsed_modifier = explode( ':', $modifier );

$atts = [
'format' => self::get_format_merge_tag_modifier_value( $modifier, false ),
'human' => in_array( 'human', $parsed_modifier ), // {date_created:human}
'diff' => in_array( 'diff', $parsed_modifier ), // {date_created:diff}
'raw' => in_array( 'raw', $parsed_modifier ), // {date_created:raw}
'timestamp' => in_array( 'timestamp', $parsed_modifier ), // {date_created:timestamp}
'time' => in_array( 'time', $parsed_modifier ), // {date_created:time}
];

return GVCommon::format_date( $date_or_time_string, $atts );
}

/**
* If there is a `:format` modifier in a merge tag, grab the formatting
*
* The `:format` modifier should always have the format follow it; it's the next item in the array
* In `foo:format:bar`, "bar" will be the returned format
* Returns the `format:` merge tag modifier value.
* This handles cases such as "foo:format:m/d/Y", "format:m/d/Y", "format:m/d/Y\ \a\t\ H\:i\:s".
*
* @since 1.16
* @since TODO Renamed and refactored to use regex and instead of working with an array.
*
* @param array $exploded Array of modifiers with a possible `format` value
* @param string $backup The backup value to use, if not found
* @param string $modifier Merge tag modifier.
* @param mixed $backup The backup value to use, if format not found.
*
* @return string If format is found, the passed format. Otherwise, the backup.
*/
private static function get_format_from_modifiers( $exploded, $backup = '' ) {

$return = $backup;
private static function get_format_merge_tag_modifier_value( $modifier, $backup = '' ) {
preg_match( '/(?:^|:)format:(.*)/', $modifier, $match );

$format_key_index = array_search( 'format', $exploded );

// If there's a "format:[php date format string]" date format, grab it
if ( false !== $format_key_index && isset( $exploded[ $format_key_index + 1 ] ) ) {
// Return escaped colons placeholder
$return = str_replace( '|COLON|', ':', implode( ':', array_slice( $exploded, $format_key_index + 1 ) ) );
}

return $return;
return isset( $match[1] ) ? str_replace( '\:', ':', $match[1] ) : $backup;
}

/**
Expand Down
1 change: 1 addition & 0 deletions readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Beautifully display your Gravity Forms entries. Learn more on [gravitykit.com](h
* Fixed: When searching a View, the searched time zone would not appear as selected in the Search Bar.
* Fixed: Fields added to the View could not be configured and would disappear after saving the View when Multiple Forms was enabled.
* Fixed: Fatal error on the Edit Entry screen when Multiple Forms is enabled.
* Fixed: The ``:format` merge tag modifier on the Time field returned a UTC-adjusted time value.

= 2.26 on August 8, 2024 =

Expand Down