WordPress.org

Make WordPress Core

Ticket #36590: 36590.diff

File 36590.diff, 5.1 KB (added by ericlewis, 5 years ago)
  • src/wp-admin/includes/nav-menu.php

    diff --git a/src/wp-admin/includes/nav-menu.php b/src/wp-admin/includes/nav-menu.php
    index 18dcc97..951c03c 100644
    a b function wp_nav_menu_update_menu_items ( $nav_menu_selected_id, $nav_menu_select 
    10571057
    10581058        return $messages;
    10591059}
     1060
     1061/**
     1062 * If a JSON blob of navigation menu data is in POST data, expand it and inject
     1063 * it into `$_POST` to avoid PHP `max_input_vars` limitations. See #14134.
     1064 *
     1065 * @since 4.5.1
     1066 */
     1067function wp_expand_nav_menu_post_data() {
     1068        if ( ! isset( $_POST['nav-menu-data'] ) ) {
     1069                return;
     1070        }
     1071        $data = json_decode( stripslashes( $_POST['nav-menu-data'] ) );
     1072        if ( ! is_null( $data ) && $data ) {
     1073                foreach ( $data as $post_input_data ) {
     1074                        // For input names that are arrays (e.g. `menu-item-db-id[3][4][5]`), derive the array path keys via regex.
     1075                        if ( preg_match( '#([^\[]*)\[(.+)\]#', $post_input_data->name, $matches ) ) {
     1076                                $array_bits = explode( '][', $matches[2] );
     1077                                $_new_data = array();
     1078                                for ( $i = count($array_bits) - 1; $i >= 0; $i -- ) {
     1079                                        if ( $i == count($array_bits) - 1 ) {
     1080                                                $_new_data[ $array_bits[$i] ] = wp_slash( $post_input_data->value );
     1081                                        } else {
     1082                                                $_i = array();
     1083                                                $_i[ $array_bits[$i] ] = $_new_data;
     1084                                                $_new_data = $_i;
     1085                                        }
     1086                                }
     1087                                $new_data = array();
     1088                                $new_data[$matches[1]] = $_new_data;
     1089                                $_POST = array_merge_recursive( $_POST, $new_data );
     1090                        } else {
     1091                                $_POST[ $post_input_data->name ] = wp_slash( $post_input_data->value );
     1092                        }
     1093                }
     1094        }
     1095}
  • src/wp-admin/nav-menus.php

    diff --git a/src/wp-admin/nav-menus.php b/src/wp-admin/nav-menus.php
    index 7099e49..a037659 100644
    a b $action = isset( $_REQUEST['action'] ) ? $_REQUEST['action'] : 'edit'; 
    5353 * If a JSON blob of navigation menu data is found, expand it and inject it
    5454 * into `$_POST` to avoid PHP `max_input_vars` limitations. See #14134.
    5555 */
    56 if ( isset( $_POST['nav-menu-data'] ) ) {
    57         $data = json_decode( stripslashes( $_POST['nav-menu-data'] ) );
    58         if ( ! is_null( $data ) && $data ) {
    59                 foreach ( $data as $post_input_data ) {
    60                         // For input names that are arrays (e.g. `menu-item-db-id[3][4][5]`), derive the array path keys via regex.
    61                         if ( preg_match( '#([^\[]*)\[(.+)\]#', $post_input_data->name, $matches ) ) {
    62                                 $array_bits = explode( '][', $matches[2] );
    63                                 $_new_data = array();
    64                                 for ( $i = count($array_bits) - 1; $i >= 0; $i -- ) {
    65                                         if ( $i == count($array_bits) - 1 ) {
    66                                                 $_new_data[ $array_bits[$i] ] = wp_slash( $post_input_data->value );
    67                                         } else {
    68                                                 $_i = array();
    69                                                 $_i[ $array_bits[$i] ] = $_new_data;
    70                                                 $_new_data = $_i;
    71                                         }
    72                                 }
    73                                 $new_data = array();
    74                                 $new_data[$matches[1]] = $_new_data;
    75                                 $_POST = array_merge_recursive( $_POST, $new_data );
    76                         } else {
    77                                 $_POST[ $post_input_data->name ] = wp_slash( $post_input_data->value );
    78                         }
    79                 }
    80         }
    81 }
     56wp_expand_nav_menu_post_data();
     57
    8258switch ( $action ) {
    8359        case 'add-menu-item':
    8460                check_admin_referer( 'add-menu_item', 'menu-settings-column-nonce' );
  • new file tests/phpunit/tests/menu/wpExpandNavMenuPostData.php

    diff --git a/tests/phpunit/tests/menu/wpExpandNavMenuPostData.php b/tests/phpunit/tests/menu/wpExpandNavMenuPostData.php
    new file mode 100644
    index 0000000..9db1858
    - +  
     1<?php
     2
     3/**
     4 * @group menu
     5 */
     6class Tests_Menu_WpExpandNavMenuPostData extends WP_UnitTestCase {
     7
     8        public function test_multidimensional_nested_array_should_expand() {
     9                include_once( ABSPATH . 'wp-admin/includes/nav-menu.php' );
     10                if ( empty( $_POST ) ) {
     11                        $_POST = array();
     12                }
     13                $data = array();
     14                $data[0] = new StdClass;
     15                $data[0]->name = "would[1][do][the][trick]";
     16                $data[0]->value = "yes";
     17                $_POST['nav-menu-data'] = addslashes( json_encode( $data ) );
     18                wp_expand_nav_menu_post_data();
     19                $expected = array(
     20                        'nav-menu-data' => $_POST['nav-menu-data'],
     21                        'would' => array(
     22                                1 => array(
     23                                        'do' => array(
     24                                                'the' => array(
     25                                                        'trick' => 'yes'
     26                                                )
     27                                        )
     28                                )
     29                        )
     30                );
     31                $this->assertEquals( $expected, $_POST );
     32        }
     33
     34        public function test_multidimensional_nested_array_should_expand_and_merge() {
     35                include_once( ABSPATH . 'wp-admin/includes/nav-menu.php' );
     36                if ( empty( $_POST ) ) {
     37                        $_POST = array();
     38                }
     39                $data = array();
     40                $data[0] = new StdClass;
     41                $data[0]->name = "would[1][do][the][trick]";
     42                $data[0]->value = "yes";
     43                $data[1] = new StdClass;
     44                $data[1]->name = "would[2][do][the][trick]";
     45                $data[1]->value = "yes";
     46                $data[2] = new StdClass;
     47                $data[2]->name = "would[2][do][the][job]";
     48                $data[2]->value = "yes";
     49                $_POST['nav-menu-data'] = addslashes( json_encode( $data ) );
     50                wp_expand_nav_menu_post_data();
     51                $expected = array(
     52                        'nav-menu-data' => $_POST['nav-menu-data'],
     53                        'would' => array(
     54                                1 => array(
     55                                        'do' => array(
     56                                                'the' => array(
     57                                                        'trick' => 'yes'
     58                                                )
     59                                        )
     60                                ),
     61                                2 => array(
     62                                        'do' => array(
     63                                                'the' => array(
     64                                                        'trick' => 'yes',
     65                                                        'job' => 'yes'
     66                                                )
     67                                        )
     68                                )
     69                        )
     70                );
     71                $this->assertEquals( $expected, $_POST );
     72        }
     73
     74}