WordPress.org

Make WordPress Core

Ticket #36590: 36590-4.5.3.diff

File 36590-4.5.3.diff, 4.3 KB (added by neverything, 4 years ago)
  • src/wp-admin/nav-menus.php

    diff --git a/src/wp-admin/nav-menus.php b/src/wp-admin/nav-menus.php
    index ab15bed..daa767d 100644
    a b $num_locations = count( array_keys( $locations ) ); 
    4949// Allowed actions: add, update, delete
    5050$action = isset( $_REQUEST['action'] ) ? $_REQUEST['action'] : 'edit';
    5151
    52 /*
    53  * If a JSON blob of navigation menu data is found, expand it and inject it
    54  * into `$_POST` to avoid PHP `max_input_vars` limitations. See #14134.
     52/**
     53 * If a JSON blob of navigation menu data is in POST data, expand it and inject
     54 * it into `$_POST` to avoid PHP `max_input_vars` limitations. See #14134.
     55 *
     56 * @ignore
     57 * @since 4.5.3
     58 * @access private
    5559 */
    56 if ( isset( $_POST['nav-menu-data'] ) ) {
     60function _wp_expand_nav_menu_post_data() {
     61        if ( ! isset( $_POST['nav-menu-data'] ) ) {
     62                return;
     63        }
     64
    5765        $data = json_decode( stripslashes( $_POST['nav-menu-data'] ) );
     66
    5867        if ( ! is_null( $data ) && $data ) {
    5968                foreach ( $data as $post_input_data ) {
    60                         // For input names that are arrays (e.g. `menu-item-db-id[3]`), derive the array path keys via regex.
    61                         if ( preg_match( '#(.*)\[(\w+)\]#', $post_input_data->name, $matches ) ) {
    62                                 if ( empty( $_POST[ $matches[1] ] ) ) {
    63                                         $_POST[ $matches[1] ] = array();
    64                                 }
    65                                 // Cast input elements with a numeric array index to integers.
    66                                 if ( is_numeric( $matches[2] ) ) {
    67                                         $matches[2] = (int) $matches[2];
     69                        // For input names that are arrays (e.g. `menu-item-db-id[3][4][5]`),
     70                        // derive the array path keys via regex and set the value in $_POST.
     71                        preg_match( '#([^\[]*)(\[(.+)\])?#', $post_input_data->name, $matches );
     72
     73                        $array_bits = array( $matches[1] );
     74
     75                        if ( isset( $matches[3] ) ) {
     76                                $array_bits = array_merge( $array_bits, explode( '][', $matches[3] ) );
     77                        }
     78
     79                        $new_post_data = array();
     80
     81                        // Build the new array value from leaf to trunk.
     82                        for ( $i = count( $array_bits ) - 1; $i >= 0; $i -- ) {
     83                                if ( $i == count( $array_bits ) - 1 ) {
     84                                        $new_post_data[ $array_bits[ $i ] ] = wp_slash( $post_input_data->value );
     85                                } else {
     86                                        $new_post_data = array( $array_bits[ $i ] => $new_post_data );
    6887                                }
    69                                 $_POST[ $matches[1] ][ $matches[2] ] = wp_slash( $post_input_data->value );
    70                         } else {
    71                                 $_POST[ $post_input_data->name ] = wp_slash( $post_input_data->value );
    7288                        }
     89
     90                        $_POST = array_replace_recursive( $_POST, $new_post_data );
    7391                }
    7492        }
    7593}
     94
     95if ( ! function_exists( 'array_replace_recursive' ) ) :
     96        /**
     97         * PHP-agnostic version of {@link array_replace_recursive()}.
     98         *
     99         * The array_replace_recursive() function is a PHP 5.3 function. WordPress
     100         * currently supports down to PHP 5.2, so this method is a workaround
     101         * for PHP 5.2.
     102         *
     103         * Note: array_replace_recursive() supports infinite arguments, but for our use-
     104         * case, we only need to support two arguments.
     105         *
     106         * Subject to removal once WordPress makes PHP 5.3.0 the minimum requirement.
     107         *
     108         * @since 4.5.3
     109         *
     110         * @see http://php.net/manual/en/function.array-replace-recursive.php#109390
     111         *
     112         * @param  array $base         Array with keys needing to be replaced.
     113         * @param  array $replacements Array with the replaced keys.
     114         *
     115         * @return array
     116         */
     117        function array_replace_recursive( $base = array(), $replacements = array() ) {
     118                // PHP 5.2-compatible version
     119                // http://php.net/manual/en/function.array-replace-recursive.php#109390.
     120                foreach ( array_slice( func_get_args(), 1 ) as $replacements ) {
     121                        $bref_stack = array( &$base );
     122                        $head_stack = array( $replacements );
     123
     124                        do {
     125                                end( $bref_stack );
     126
     127                                $bref = &$bref_stack[ key( $bref_stack ) ];
     128                                $head = array_pop( $head_stack );
     129
     130                                unset( $bref_stack[ key( $bref_stack ) ] );
     131
     132                                foreach ( array_keys( $head ) as $key ) {
     133                                        if ( isset( $key, $bref ) && is_array( $bref[ $key ] ) && is_array( $head[ $key ] ) ) {
     134                                                $bref_stack[] = &$bref[ $key ];
     135                                                $head_stack[] = $head[ $key ];
     136                                        } else {
     137                                                $bref[ $key ] = $head[ $key ];
     138                                        }
     139                                }
     140                        } while ( count( $head_stack ) );
     141                }
     142
     143                return $base;
     144        }
     145endif;
     146
     147/*
     148 * If a JSON blob of navigation menu data is found, expand it and inject it
     149 * into `$_POST` to avoid PHP `max_input_vars` limitations. See #14134.
     150 */
     151_wp_expand_nav_menu_post_data();
     152
    76153switch ( $action ) {
    77154        case 'add-menu-item':
    78155                check_admin_referer( 'add-menu_item', 'menu-settings-column-nonce' );