[wp-trac] [WordPress Trac] #36590: POST['nav-menu-data'] breaks other POST values

WordPress Trac noreply at wordpress.org
Wed Apr 20 08:28:52 UTC 2016


#36590: POST['nav-menu-data'] breaks other POST values
-------------------------------------+-------------------------------------
 Reporter:  Unyson                   |       Owner:
     Type:  defect (bug)             |      Status:  new
 Priority:  normal                   |   Milestone:  4.5.1
Component:  Menus                    |     Version:  4.5
 Severity:  normal                   |  Resolution:
 Keywords:  needs-patch needs-       |     Focuses:  javascript,
  testing                            |  administration
-------------------------------------+-------------------------------------
Changes (by keraweb):

 * keywords:  needs-patch => needs-patch needs-testing


Comment:

 Okay, Did some testing with various plugins and this looks promising.
 Perhaps someone could make the code more "neat".

 This is a complete redo of the current function that handles the {{{$_POST
 ['nav-menu-data']}}} data.

 Instead of a preg_match i've used explode to separate all the array keys
 (removing the "]" afterwards).
 I loop through all the depth levels to create a temporary array that has
 the correct depth and keys.
 When this is complete I merge this with the {{{$_POST}}} values (replacing
 if needed).

 If anyone can help me test this for different plugins and settings that
 would be great.

 @Unyson can you check if the problem is fixed for your plugin? I somehow
 can't get the plugin to work properly in the dev release of WP.

 {{{#!php
 <?php
 /*
  * If a JSON blob of navigation menu data is found, expand it and inject
 it
  * into `$_POST` to avoid PHP `max_input_vars` limitations. See #14134.
  */
 if ( isset( $_POST['nav-menu-data'] ) ) {
         $data = json_decode( stripslashes( $_POST['nav-menu-data'] ) );
         if ( ! is_null( $data ) && $data ) {
                 foreach ( $data as $post_input_data ) {
                         // For input names that are arrays (e.g. `menu-
 item-db-id[3]`), derive the array path keys via explode.
                         $levels = explode('[', $post_input_data->name );
                         if ( count( $levels ) > 1 ) {
                                 if ( empty( $_POST[ $levels[0] ] ) ) {
                                         $_POST[ $levels[0] ] = array();
                                 }
                                 foreach ( $levels as $level_key =>
 $array_key ) {
                                         if ( $level_key == 0 ) {
                                                 continue;
                                         }
                                         // Remove the trailing "]"
                                         $levels[ $level_key ] = substr(
 $array_key, 0, -1 );
                                         // Cast keys with a numeric array
 index to integers.
                                         if ( is_numeric( $array_key ) ) {
                                                 $levels[ $level_key ] =
 (int) $array_key;
                                         }
                                 }

                                 $temp_array = array(); // Temp array to
 create the correct depth with the level keys
                                 $start = 1; // 1 because the level 0
 allready exists in $_POST
                                 $depth = count( $levels ) - 1; // minus 1
 because counting arrays doesn't match their key indexes

                                 // Add the actual value to the last found
 level
                                 $temp_array[ $levels[ $depth ] ] =
 wp_slash( $post_input_data->value );
                                 // Create the correct depth if needed
                                 if ( $depth > $start ) {
                                         for ( $i = ( $depth - 1 ), $min =
 $start; $i >= $min; $i-- ) {
                                                 // Create the new array
 depth
                                                 $temp_array[ $levels[ $i ]
 ] = $temp_array;
                                         }
                                 }
                                 // Add (or replace if it exists) the value
 to the $_POST object at the correct depth
                                 $_POST[ $levels[0] ] =
 array_replace_recursive( $_POST[ $levels[0] ], $temp_array );
                         } else {
                                 $_POST[ $post_input_data->name ] =
 wp_slash( $post_input_data->value );
                         }
                 }
         }
 }
 }}}

--
Ticket URL: <https://core.trac.wordpress.org/ticket/36590#comment:6>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list