diff --git a/src/wp-admin/js/nav-menu.js b/src/wp-admin/js/nav-menu.js index 264dc574fc..abff8f937f 100644 --- a/src/wp-admin/js/nav-menu.js +++ b/src/wp-admin/js/nav-menu.js @@ -43,6 +43,7 @@ var wpNavMenu; this.attachQuickSearchListeners(); this.attachThemeLocationsListeners(); + this.attachMenuSaveSubmitListeners(); this.attachTabsPanelListeners(); @@ -834,6 +835,30 @@ var wpNavMenu; }); }, + attachMenuSaveSubmitListeners : function() { + /* + * When a navigation menu is saved, store a JSON representation of all form data + * in a single input to avoid PHP `max_input_vars` limitations. See #14134. + */ + $('#update-nav-menu').submit(function() { + var navMenuData = {}; + $('#update-nav-menu input').each(function(index, element) { + var name = $(element).attr('name'); + var regex = /(.*)(?:\[(\d+)\])/; + if ( regex.test( name ) ) { + var matches = regex.exec(name); + if ( ! navMenuData[matches[1]] ) { + navMenuData[matches[1]] = []; + } + navMenuData[matches[1]][matches[2]] = $(element).val(); + } else { + navMenuData[name] = $(element).val(); + } + }); + $('[name="nav-menu-data"]').val( JSON.stringify( navMenuData ) ); + }); + }, + attachThemeLocationsListeners : function() { var loc = $('#nav-menu-theme-locations'), params = {}; params.action = 'menu-locations-save'; diff --git a/src/wp-admin/nav-menus.php b/src/wp-admin/nav-menus.php index 8f17e03031..deac6d2ca4 100644 --- a/src/wp-admin/nav-menus.php +++ b/src/wp-admin/nav-menus.php @@ -49,6 +49,19 @@ $num_locations = count( array_keys( $locations ) ); // Allowed actions: add, update, delete $action = isset( $_REQUEST['action'] ) ? $_REQUEST['action'] : 'edit'; +/* + * 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_var => $post_data ) { + $_POST[$post_var] = $post_data; + } + } +} + switch ( $action ) { case 'add-menu-item': check_admin_referer( 'add-menu_item', 'menu-settings-column-nonce' ); @@ -731,6 +744,7 @@ require_once( ABSPATH . 'wp-admin/admin-header.php' );