Make WordPress Core


Ignore:
Timestamp:
06/19/2016 12:24:23 PM (9 years ago)
Author:
swissspidy
Message:

Menus: Support nested array variables in POST data when saving menus.

[36510] allowed larger menus to be created in the Edit Menu screen by JSON-encoding the entire form into a single input field. However, it did not correctly handle nested arrays.

This introduces a new _wp_expand_nav_menu_post_data() helper function to handle this POST data which uses array_replace_recursive() internally. Since the latter is only available on PHP 5.3+, we add a compatibility function to ensure PHP 5.2 support.

Props ericlewis, neverything, swissspidy.
Fixes #36590 for trunk. See #14134.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/includes/nav-menu.php

    r37529 r37748  
    10601060    return $messages;
    10611061}
     1062
     1063/**
     1064 * If a JSON blob of navigation menu data is in POST data, expand it and inject
     1065 * it into `$_POST` to avoid PHP `max_input_vars` limitations. See #14134.
     1066 *
     1067 * @ignore
     1068 * @since 4.5.3
     1069 * @access private
     1070 */
     1071function _wp_expand_nav_menu_post_data() {
     1072    if ( ! isset( $_POST['nav-menu-data'] ) ) {
     1073        return;
     1074    }
     1075
     1076    $data = json_decode( stripslashes( $_POST['nav-menu-data'] ) );
     1077
     1078    if ( ! is_null( $data ) && $data ) {
     1079        foreach ( $data as $post_input_data ) {
     1080            // For input names that are arrays (e.g. `menu-item-db-id[3][4][5]`),
     1081            // derive the array path keys via regex and set the value in $_POST.
     1082            preg_match( '#([^\[]*)(\[(.+)\])?#', $post_input_data->name, $matches );
     1083
     1084            $array_bits = array( $matches[1] );
     1085
     1086            if ( isset( $matches[3] ) ) {
     1087                $array_bits = array_merge( $array_bits, explode( '][', $matches[3] ) );
     1088            }
     1089
     1090            $new_post_data = array();
     1091
     1092            // Build the new array value from leaf to trunk.
     1093            for ( $i = count( $array_bits ) - 1; $i >= 0; $i -- ) {
     1094                if ( $i == count( $array_bits ) - 1 ) {
     1095                    $new_post_data[ $array_bits[ $i ] ] = wp_slash( $post_input_data->value );
     1096                } else {
     1097                    $new_post_data = array( $array_bits[ $i ] => $new_post_data );
     1098                }
     1099            }
     1100
     1101            $_POST = array_replace_recursive( $_POST, $new_post_data );
     1102        }
     1103    }
     1104}
Note: See TracChangeset for help on using the changeset viewer.