Ticket #36590: 36590-trunk.3.diff
File 36590-trunk.3.diff, 7.5 KB (added by , 9 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..33bc73a 100644
a b function wp_nav_menu_update_menu_items ( $nav_menu_selected_id, $nav_menu_select 1057 1057 1058 1058 return $messages; 1059 1059 } 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 * @ignore 1066 * @since 4.5.3 1067 * @access private 1068 */ 1069 function _wp_expand_nav_menu_post_data() { 1070 if ( ! isset( $_POST['nav-menu-data'] ) ) { 1071 return; 1072 } 1073 1074 $data = json_decode( stripslashes( $_POST['nav-menu-data'] ) ); 1075 1076 if ( ! is_null( $data ) && $data ) { 1077 foreach ( $data as $post_input_data ) { 1078 // For input names that are arrays (e.g. `menu-item-db-id[3][4][5]`), 1079 // derive the array path keys via regex and set the value in $_POST. 1080 preg_match( '#([^\[]*)(\[(.+)\])?#', $post_input_data->name, $matches ); 1081 1082 $array_bits = array( $matches[1] ); 1083 1084 if ( isset( $matches[3] ) ) { 1085 $array_bits = array_merge( $array_bits, explode( '][', $matches[3] ) ); 1086 } 1087 1088 $new_post_data = array(); 1089 1090 // Build the new array value from leaf to trunk. 1091 for ( $i = count( $array_bits ) - 1; $i >= 0; $i -- ) { 1092 if ( $i == count( $array_bits ) - 1 ) { 1093 $new_post_data[ $array_bits[ $i ] ] = wp_slash( $post_input_data->value ); 1094 } else { 1095 $new_post_data = array( $array_bits[ $i ] => $new_post_data ); 1096 } 1097 } 1098 1099 $_POST = array_replace_recursive( $_POST, $new_post_data ); 1100 } 1101 } 1102 } -
src/wp-admin/nav-menus.php
diff --git a/src/wp-admin/nav-menus.php b/src/wp-admin/nav-menus.php index ab15bed..1b5e09b 100644
a b $action = isset( $_REQUEST['action'] ) ? $_REQUEST['action'] : 'edit'; 53 53 * If a JSON blob of navigation menu data is found, expand it and inject it 54 54 * into `$_POST` to avoid PHP `max_input_vars` limitations. See #14134. 55 55 */ 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]`), 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]; 68 } 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 ); 72 } 73 } 74 } 75 } 56 _wp_expand_nav_menu_post_data(); 57 76 58 switch ( $action ) { 77 59 case 'add-menu-item': 78 60 check_admin_referer( 'add-menu_item', 'menu-settings-column-nonce' ); -
src/wp-includes/compat.php
diff --git a/src/wp-includes/compat.php b/src/wp-includes/compat.php index cfb0f70..e6b699e 100644
a b if ( ! interface_exists( 'JsonSerializable' ) ) { 434 434 if ( ! function_exists( 'random_int' ) ) { 435 435 require ABSPATH . WPINC . '/random_compat/random.php'; 436 436 } 437 438 if ( ! function_exists( 'array_replace_recursive' ) ) : 439 /** 440 * PHP-agnostic version of {@link array_replace_recursive()}. 441 * 442 * The array_replace_recursive() function is a PHP 5.3 function. WordPress 443 * currently supports down to PHP 5.2, so this method is a workaround 444 * for PHP 5.2. 445 * 446 * Note: array_replace_recursive() supports infinite arguments, but for our use- 447 * case, we only need to support two arguments. 448 * 449 * Subject to removal once WordPress makes PHP 5.3.0 the minimum requirement. 450 * 451 * @since 4.5.3 452 * 453 * @see http://php.net/manual/en/function.array-replace-recursive.php#109390 454 * 455 * @param array $base Array with keys needing to be replaced. 456 * @param array $replacements Array with the replaced keys. 457 * 458 * @return array 459 */ 460 function array_replace_recursive( $base = array(), $replacements = array() ) { 461 // PHP 5.2-compatible version 462 // http://php.net/manual/en/function.array-replace-recursive.php#109390. 463 foreach ( array_slice( func_get_args(), 1 ) as $replacements ) { 464 $bref_stack = array( &$base ); 465 $head_stack = array( $replacements ); 466 467 do { 468 end( $bref_stack ); 469 470 $bref = &$bref_stack[ key( $bref_stack ) ]; 471 $head = array_pop( $head_stack ); 472 473 unset( $bref_stack[ key( $bref_stack ) ] ); 474 475 foreach ( array_keys( $head ) as $key ) { 476 if ( isset( $key, $bref ) && is_array( $bref[ $key ] ) && is_array( $head[ $key ] ) ) { 477 $bref_stack[] = &$bref[ $key ]; 478 $head_stack[] = $head[ $key ]; 479 } else { 480 $bref[ $key ] = $head[ $key ]; 481 } 482 } 483 } while ( count( $head_stack ) ); 484 } 485 486 return $base; 487 } 488 endif; -
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..361c4f9
- + 1 <?php 2 3 /** 4 * @group menu 5 * @ticket 36590 6 */ 7 class Tests_Menu_WpExpandNavMenuPostData extends WP_UnitTestCase { 8 public function test_unnested_data_should_expand() { 9 include_once( ABSPATH . 'wp-admin/includes/nav-menu.php' ); 10 11 if ( empty( $_POST ) ) { 12 $_POST = array(); 13 } 14 15 $data = array(); 16 $data[0] = new StdClass; 17 $data[0]->name = 'yesorno'; 18 $data[0]->value = 'yes'; 19 $_POST['nav-menu-data'] = addslashes( json_encode( $data ) ); 20 21 _wp_expand_nav_menu_post_data(); 22 23 $expected = array( 24 'nav-menu-data' => $_POST['nav-menu-data'], 25 'yesorno' => 'yes' 26 ); 27 28 $this->assertEquals( $expected, $_POST ); 29 } 30 31 public function test_multidimensional_nested_array_should_expand() { 32 include_once( ABSPATH . 'wp-admin/includes/nav-menu.php' ); 33 34 if ( empty( $_POST ) ) { 35 $_POST = array(); 36 } 37 38 $data = array(); 39 $data[0] = new StdClass; 40 $data[0]->name = 'would[1][do][the][trick]'; 41 $data[0]->value = 'yes'; 42 $_POST['nav-menu-data'] = addslashes( json_encode( $data ) ); 43 44 _wp_expand_nav_menu_post_data(); 45 46 $expected = array( 47 'nav-menu-data' => $_POST['nav-menu-data'], 48 'would' => array( 49 1 => array( 50 'do' => array( 51 'the' => array( 52 'trick' => 'yes', 53 ), 54 ), 55 ), 56 ), 57 ); 58 $this->assertEquals( $expected, $_POST ); 59 } 60 61 public function test_multidimensional_nested_array_should_expand_and_merge() { 62 include_once( ABSPATH . 'wp-admin/includes/nav-menu.php' ); 63 64 if ( empty( $_POST ) ) { 65 $_POST = array(); 66 } 67 68 $data = array(); 69 $data[0] = new StdClass; 70 $data[0]->name = 'would[1][do][the][trick]'; 71 $data[0]->value = 'yes'; 72 $data[1] = new StdClass; 73 $data[1]->name = 'would[2][do][the][trick]'; 74 $data[1]->value = 'yes'; 75 $data[2] = new StdClass; 76 $data[2]->name = 'would[2][do][the][job]'; 77 $data[2]->value = 'yes'; 78 $_POST['nav-menu-data'] = addslashes( json_encode( $data ) ); 79 80 _wp_expand_nav_menu_post_data(); 81 82 $expected = array( 83 'nav-menu-data' => $_POST['nav-menu-data'], 84 'would' => array( 85 1 => array( 86 'do' => array( 87 'the' => array( 88 'trick' => 'yes', 89 ), 90 ), 91 ), 92 2 => array( 93 'do' => array( 94 'the' => array( 95 'trick' => 'yes', 96 'job' => 'yes', 97 ), 98 ), 99 ), 100 ), 101 ); 102 103 $this->assertEquals( $expected, $_POST ); 104 } 105 }