Make WordPress Core

Opened 7 weeks ago

Last modified 4 weeks ago

#63483 new enhancement

Compatibility float and whitelist timezone string

Reported by: autotutorial's profile autotutorial Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version:
Component: Options, Meta APIs Keywords:
Focuses: php-compatibility Cc:

Description

This is a follow-up to #58814.
This is an "enhancement" of existing code. Compatibility for versions before php 8.
Float point numbers add_filter( 'pre_option_gmt_offset','wp_timezone_override_offset' ); from get_option( 'gmt_offset' );
https://wiki.php.net/rfc/locale_independent_float_to_string
As of PHP 8.0.0, the decimal point character is always a period ("."). Prior to PHP 8.0.0, the decimal point character is defined in the script's locale (category LC_NUMERIC).
Example get_option( 'gmt_offset' ):

<?php

setlocale( LC_ALL, 'de_DE');
$numeric = 5.5;
var_dump( $numeric ); // Before PHP 8 is 5,5
?>

Before PHP 8 x UTC timezone is valid x timezone.
Only set if whitelisted and resets $_POST variables instead of saving to the already existing timezone database (redundant code).
https://bugs.php.net/bug.php?id=78139&edit=1

<?php
        unset( $_POST['gmt_offset'] );
                // Map UTC+- timezones to gmt_offsets and set timezone_string to empty.
        if ( isset( $_POST['timezone_string'] ) ) {
                        $first = 'UTC';
                        $two = 'UTC+';
                        $offset_range = array(
                            '',
                                $first . '-12',
                                $first . '-11.5',
                                $first . '-11',
                                $first . '-10.5',
                                $first . '-10',
                                $first . '-9.5',
                                $first . '-9',
                                $first . '-8.5',
                                $first . '-8',
                                $first . '-7.5',
                                $first . '-7',
                                $first . '-6.5',
                                $first . '-6',
                                $first . '-5.5',
                                $first . '-5',
                                $first . '-4.5',
                                $first . '-4',
                                $first . '-3.5',
                                $first . '-3',
                                $first . '-2.5',
                                $first . '-2',
                                $first . '-1.5',
                                $first . '-1',
                                $first . '-0.5',
                                $two . '0',
                                $two . '0.5',
                                $two . '1',
                                $two . '1.5',
                                $two . '2',
                                $two . '2.5',
                                $two . '3',
                                $two . '3.5',
                                $two . '4',
                                $two . '4.5',
                                $two . '5',
                                $two . '5.5',
                                $two . '5.75',
                                $two . '6',
                                $two . '6.5',
                                $two . '7',
                                $two . '7.5',
                                $two . '8',
                                $two . '8.5',
                                $two . '8.75',
                                $two . '9',
                                $two . '9.5',
                                $two . '10',
                                $two . '10.5',
                                $two . '11',
                                $two . '11.5',
                                $two . '12',
                                $two . '12.75',
                                $two . '13',
                                $two . '13.75',
                                $two . '14',
                );

            $key_valid = array_search( $_POST['timezone_string'], $offset_range );
            if ( $key_valid ) {
                $_POST['gmt_offset'] = strtr( $offset_range[$key_valid], array( 'UTC+' => '', 'UTC' => '' ) );
                $_POST['timezone_string'] = '';
            } else {
                $tz_identifiers = timezone_identifiers_list( DateTimeZone::ALL_WITH_BC );
                $key_valid = array_search( $_POST['timezone_string'], $tz_identifiers );
                if( is_int( $key_valid ) ) {
                    $_POST['timezone_string'] = $tz_identifiers[$key_valid];
                } else {
                    unset( $_POST['timezone_string'] );

                    add_settings_error(
                                        'general',
                                        'settings_updated',
                                        __( 'The timezone you have entered is not valid. Please select a valid timezone.' ),
                                        'error'
                                );
                }
            }
            unset( $offset_range, $tz_identifiers );
        }
?>

Good job

Change History (1)

#1 @autotutorial
5 weeks ago

  • Focuses php-compatibility added
  • Severity changed from trivial to normal

Hi everyone, please set $_POSTtimezone string? as required. In my pseudo php code, if $_POSTtimezone_string? is absent or invalid, set the error and then recover by setting $_POSTtimezone_string? and $_POSTgmt_offset? from the respective functions get_option('timezone_string') for the timezone ID and get_option('gmt_offset') for the manual offset.

In the option.php file $value is null if it doesn't exist, I don't think you want to set timezone_string and gmt_offset to anything other than explicit choice.

<?php
        $offset_range = array(
                '',
                 '-12',
                 '-11.5',
                 '-11',
                 '-10.5',
                 '-10',
                 '-9.5',
                 '-9',
                 '-8.5',
                 '-8',
                 '-7.5',
                 '-7',
                 '-6.5',
                 '-6',
                 '-5.5',
                 '-5',
                 '-4.5',
                 '-4',
                 '-3.5',
                 '-3',
                 '-2.5',
                 '-2',
                 '-1.5',
                 '-1',
                 '-0.5',
                 '0',
                 '0.5',
                 '1',
                 '1.5',
                 '2',
                 '2.5',
                 '3',
                 '3.5',
                 '4',
                 '4.5',
                 '5',
                 '5.5',
                 '5.75',
                 '6',
                 '6.5',
                 '7',
                 '7.5',
                 '8',
                 '8.5',
                 '8.75',
                 '9',
                 '9.5',
                 '10',
                 '10.5',
                 '11',
                 '11.5',
                 '12',
                 '12.75',
                 '13',
                 '13.75',
                 '14',
        );
        if ( empty( $_POST['timezone_string'] ) || ! is_string($_POST['timezone_string']) ) {
                $_POST['timezone_string'] = '';
        }

        $copy = $_POST['timezone_string'];
        $_POST['timezone_string'] = '';
        $key_valid1 = (int) array_search( strtr( $copy, array( 'UTC+' => '', 'UTC-' => '-' ) ), $offset_range );
        $key_valid2 = 'UTC+' === $copy || $copy !== strtr( 'UTC+' . $offset_range[$key_valid1], array( '+-' => '-' ) );
        if ( $key_valid2 ) {
                $tz_identifiers = timezone_identifiers_list( DateTimeZone::ALL_WITH_BC );
                $key_valid2 = array_search( $copy, $tz_identifiers );
                if ( false === $key_valid2 ) {
                        //Reset to the current value
                        $key_valid2 = array_search( get_option('timezone_string' ), $tz_identifiers );
                        add_settings_error(
                        'general',
                        'settings_updated',
                        __( 'The timezone you have entered is not valid. Please select a valid timezone.' ),
                        'error'
                        );
                }

                if ( is_int( $key_valid2 ) ) {
                        $_POST['timezone_string'] = $tz_identifiers[$key_valid2];
                } else {
                        $copy = get_option( 'gmt_offset' );
                        $key_valid1 = (int) is_numeric( $copy );
                        $copy = strtr( '' . $key_valid1, array( '1' => strtr( '' . (float) $copy, array( ',' => '.' ) ), '0' => '' ) );
                        $key_valid1 = (int) array_search( $copy, $offset_range );
                }
        }
        $_POST['gmt_offset'] = $offset_range[$key_valid1];
        unset( $offset_range, $tz_identifiers );
?>

Thank for reading.
The gmt_offset when it comes to sanitize_option use preg_replace if instead of null you can edit and remove is_numeric added for php 8 compatibility.

Last edited 4 weeks ago by autotutorial (previous) (diff)
Note: See TracTickets for help on using tickets.