WordPress.org

Make WordPress Core

Ticket #25280: 25280.4.diff

File 25280.4.diff, 6.5 KB (added by adamsilverstein, 15 months ago)
  • src/wp-includes/class.wp-scripts.php

    diff --git src/wp-includes/class.wp-scripts.php src/wp-includes/class.wp-scripts.php
    index cfb72280fd..da59fea584 100644
    class WP_Scripts extends WP_Dependencies { 
    450450                return $this->add_data( $handle, 'data', $script );
    451451        }
    452452
     453        /**
     454         * Pass data to a script if the script has already been added.
     455         *
     456         * @since 5.0.0
     457         * @access public
     458         *
     459         * @param string $handle
     460         * @param string $object_name
     461         * @param array  $data
     462         * @return bool
     463         */
     464        public function pass_data( $handle, $object_name, $data ) {
     465
     466                // Pass scalar values untouched; pass strings through html_entity_decode.
     467                if ( is_scalar( $data ) ) {
     468
     469                        // Pass strings through html_entity_decode, pass other scalar untouched.
     470                        if ( is_string( $data ) ) {
     471                                $data = html_entity_decode( $data, ENT_QUOTES, 'UTF-8');
     472                        }
     473                } else {
     474                        // Recurse over passed arrays. Cast objects to arrays.
     475                        foreach ( (array) $data as $key => $value ) {
     476
     477                                // Pass scalar values untouched; pass strings through html_entity_decode.
     478                                if ( is_scalar( $value ) ) {
     479
     480                                        // Pass strings through html_entity_decode, pass other scalar values untouched.
     481                                        if ( is_string( $value ) ) {
     482                                                $data[ $key ] = html_entity_decode( $value, ENT_QUOTES, 'UTF-8');
     483                                        } else {
     484                                                $data[$key] = $value;
     485                                        }
     486                                } else {
     487
     488                                        $data = $this->entity_decode_array_values( $data );
     489                                }
     490                        }
     491                }
     492
     493                $script = "var $object_name = " . wp_json_encode( $data ) . ';';
     494                $data = $this->get_data( $handle, 'data' );
     495
     496                if ( ! empty( $data ) ) {
     497                        $script = "$data\n$script";
     498                }
     499
     500                return $this->add_data( $handle, 'data', $script );
     501        }
     502
     503        /**
     504        * Handles recursively HTML entity decoding multi-dimensional array values.
     505        *
     506        * @since 5.0.0
     507        *
     508        * @param  array $data_array Array of data which should be decoded.
     509        *
     510        * @return array Array with decoded values.
     511        */
     512        public function entity_decode_array_values( $data_array ) {
     513
     514                // Begin a new array so that non-decoded values do not get added.
     515                $data = array();
     516
     517                foreach ( (array) $data_array as $key => $value ) {
     518                        if ( is_array( $value ) ) {
     519                                $data[ $key ] = $this->entity_decode_array_values( $value );
     520                        }
     521
     522                        // Non-array, non-scalar values should not be added.
     523                        if ( ! is_scalar( $value ) ) {
     524                                continue;
     525                        }
     526
     527                        // Pass strings through html_entity_decode, pass other scalars untouched.
     528                        if ( is_string( $value ) ) {
     529                                $data[ $key ] = html_entity_decode( $value, ENT_QUOTES, 'UTF-8');
     530                        } else {
     531                                $data[ $key ] = $value;
     532                        }
     533                }
     534
     535                return $data;
     536        }
     537
    453538        /**
    454539         * Sets handle group.
    455540         *
  • src/wp-includes/functions.wp-scripts.php

    diff --git src/wp-includes/functions.wp-scripts.php src/wp-includes/functions.wp-scripts.php
    index 765fe92ad4..5b248763ba 100644
    function wp_localize_script( $handle, $object_name, $l10n ) { 
    195195        return $wp_scripts->localize( $handle, $object_name, $l10n );
    196196}
    197197
     198/**
     199 * Pass data from PHP to a registered JavaScript file.
     200 *
     201 * Accepts a scalar value or an associative array and creates a JavaScript object. Passes strings through html_entity_decode.
     202 *
     203 * @since 5.0.0
     204 *
     205 * @param string $handle      Script handle the data will be attached to.
     206 * @param string $object_name Name for the JavaScript object. Passed directly, so it should be qualified JS variable.
     207 * @param array  $data        The data itself. The data can be either a scalar value, or a single or multi-dimensional array.
     208 *
     209 * @return bool True if the script was successfully localized, false otherwise.
     210 */
     211function wp_pass_data_to_script( $handle, $object_name, $data ) {
     212        global $wp_scripts;
     213        if ( ! ( $wp_scripts instanceof WP_Scripts ) ) {
     214                _wp_scripts_maybe_doing_it_wrong( __FUNCTION__ );
     215                return false;
     216        }
     217
     218        return $wp_scripts->pass_data( $handle, $object_name, $data );
     219}
     220
    198221/**
    199222 * Remove a registered script.
    200223 *
  • tests/phpunit/tests/dependencies/scripts.php

    diff --git tests/phpunit/tests/dependencies/scripts.php tests/phpunit/tests/dependencies/scripts.php
    index 20ade29c0e..72a9fd49a6 100644
    class Tests_Dependencies_Scripts extends WP_UnitTestCase { 
    10901090                        array_keys( $wp_enqueue_code_editor['htmlhint'] )
    10911091                );
    10921092        }
     1093
     1094        /**
     1095         * Testing `wp_pass_data_to_script` with scalar and array values.
     1096         * @ticket 25280
     1097         */
     1098        function test_wp_pass_data_to_script_with_scalar_and_multidimensional_arrays() {
     1099                // Enqueue & localize variables
     1100                wp_enqueue_script( 'test-l10n-data', 'example.com', array(), null );
     1101                wp_pass_data_to_script( 'test-l10n-data', 'data', true );
     1102
     1103                $test_array = array( 'var' => 'string' );
     1104                wp_pass_data_to_script( 'test-l10n-data', 'dataArray', $test_array );
     1105
     1106                $test_multidimensional = array(
     1107                        'first-level' => array(
     1108                                'second-level' => array(
     1109                                        'index' => "I'll \"walk\" the <b>dog</b> now",
     1110                                ),
     1111                        ),
     1112                );
     1113                wp_pass_data_to_script( 'test-l10n-data', 'dataMultiDimensionalArray', $test_multidimensional );
     1114
     1115
     1116                // Boolean output.
     1117                $expected = "var data = true;\n";
     1118                // One-dimensional array output.
     1119                $expected .= "var dataArray = {\"var\":\"string\"};\n";
     1120                // Multi-dimensional array output with odd characters.
     1121                $string = '\"walk\"';
     1122                $expected .= "var dataMultiDimensionalArray = {\"first-level\":{\"second-level\":{\"index\":\"I'll " .
     1123                        $string . " the <b>dog<\/b> now\"}}};\n";
     1124                // var script wrapper output
     1125                $expected = "<script type='text/javascript'>\n/* <![CDATA[ */\n$expected/* ]]> */\n</script>\n";
     1126                // script link output
     1127                $expected .= "<script type='text/javascript' src='http://example.com'></script>\n";
     1128                $this->assertEquals( $expected, get_echo( 'wp_print_scripts' ) );
     1129                // No scripts left to print
     1130                $this->assertEquals( '', get_echo( 'wp_print_scripts' ) );
     1131        }
     1132
     1133        /**
     1134         * Test passing data to scripts via `wp_pass_data_to_script`.
     1135         *
     1136         * @ticket 25280
     1137         */
     1138        function test_wp_pass_data_to_script_doesnt_convert_types_unexpectedly() {
     1139                global $wp_scripts;
     1140                $array_to_pass = array(
     1141                        'a_string'  => __( 'Some String' ),
     1142                        'a_number'  => 10,
     1143                        'a_boolean' => true,
     1144                );
     1145                wp_enqueue_script( 'localize_test','localize_script.js', array(), '1.0.0', true );
     1146                wp_pass_data_to_script( 'localize_test', 'localized_variable', $array_to_pass );
     1147                $this->assertEquals(
     1148                        'var localized_variable = {"a_string":"Some String","a_number":10,"a_boolean":true};',
     1149                        $wp_scripts->print_extra_script( 'localize_test', false )
     1150                );
     1151        }
    10931152}