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

WordPress Trac noreply at wordpress.org
Tue May 3 09:58:26 UTC 2016


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

Comment (by Ryan Stutzman):

 Hi keraweb, I can verify this fixes it.

 Replying to [comment:6 keraweb]:
 > 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:33>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list