WP_Customize_Nav_Menu_Setting::update( array|false $value )

Create/update the nav_menu term for this setting.

Description

Any created menus will have their assigned term IDs exported to the client via the ‘customize_save_response’ filter. Likewise, any errors will be exported to the client via the customize_save_response() filter.

To delete a menu, the client can send false as the value.

See also

Parameters

$value

(array|false) (Required) The value to update. Note that slug cannot be updated via wp_update_nav_menu_object(). If false, then the menu will be deleted entirely.

  • 'name'
    (string) The name of the menu to save.
  • 'description'
    (string) The term description. Default empty string.
  • 'parent'
    (int) The id of the parent term. Default 0.
  • 'auto_add'
    (bool) Whether pages will auto_add to this menu. Default false.

Return

(null|void)

Source

File: wp-includes/customize/class-wp-customize-nav-menu-setting.php

protected function update( $value ) {
		if ( $this->is_updated ) {
			return;
		}

		$this->is_updated = true;
		$is_placeholder   = ( $this->term_id < 0 );
		$is_delete        = ( false === $value );

		add_filter( 'customize_save_response', array( $this, 'amend_customize_save_response' ) );

		$auto_add = null;
		if ( $is_delete ) {
			// If the current setting term is a placeholder, a delete request is a no-op.
			if ( $is_placeholder ) {
				$this->update_status = 'deleted';
			} else {
				$r = wp_delete_nav_menu( $this->term_id );

				if ( is_wp_error( $r ) ) {
					$this->update_status = 'error';
					$this->update_error  = $r;
				} else {
					$this->update_status = 'deleted';
					$auto_add            = false;
				}
			}
		} else {
			// Insert or update menu.
			$menu_data              = wp_array_slice_assoc( $value, array( 'description', 'parent' ) );
			$menu_data['menu-name'] = $value['name'];

			$menu_id              = $is_placeholder ? 0 : $this->term_id;
			$r                    = wp_update_nav_menu_object( $menu_id, wp_slash( $menu_data ) );
			$original_name        = $menu_data['menu-name'];
			$name_conflict_suffix = 1;
			while ( is_wp_error( $r ) && 'menu_exists' === $r->get_error_code() ) {
				$name_conflict_suffix += 1;
				/* translators: 1: Original menu name, 2: Duplicate count. */
				$menu_data['menu-name'] = sprintf( __( '%1$s (%2$d)' ), $original_name, $name_conflict_suffix );
				$r                      = wp_update_nav_menu_object( $menu_id, wp_slash( $menu_data ) );
			}

			if ( is_wp_error( $r ) ) {
				$this->update_status = 'error';
				$this->update_error  = $r;
			} else {
				if ( $is_placeholder ) {
					$this->previous_term_id = $this->term_id;
					$this->term_id          = $r;
					$this->update_status    = 'inserted';
				} else {
					$this->update_status = 'updated';
				}

				$auto_add = $value['auto_add'];
			}
		}

		if ( null !== $auto_add ) {
			$nav_menu_options = $this->filter_nav_menu_options_value(
				(array) get_option( 'nav_menu_options', array() ),
				$this->term_id,
				$auto_add
			);
			update_option( 'nav_menu_options', $nav_menu_options );
		}

		if ( 'inserted' === $this->update_status ) {
			// Make sure that new menus assigned to nav menu locations use their new IDs.
			foreach ( $this->manager->settings() as $setting ) {
				if ( ! preg_match( '/^nav_menu_locations\[/', $setting->id ) ) {
					continue;
				}

				$post_value = $setting->post_value( null );
				if ( ! is_null( $post_value ) && (int) $post_value === $this->previous_term_id ) {
					$this->manager->set_post_value( $setting->id, $this->term_id );
					$setting->save();
				}
			}

			// Make sure that any nav_menu widgets referencing the placeholder nav menu get updated and sent back to client.
			foreach ( array_keys( $this->manager->unsanitized_post_values() ) as $setting_id ) {
				$nav_menu_widget_setting = $this->manager->get_setting( $setting_id );
				if ( ! $nav_menu_widget_setting || ! preg_match( '/^widget_nav_menu\[/', $nav_menu_widget_setting->id ) ) {
					continue;
				}

				$widget_instance = $nav_menu_widget_setting->post_value(); // Note that this calls WP_Customize_Widgets::sanitize_widget_instance().
				if ( empty( $widget_instance['nav_menu'] ) || (int) $widget_instance['nav_menu'] !== $this->previous_term_id ) {
					continue;
				}

				$widget_instance['nav_menu'] = $this->term_id;
				$updated_widget_instance     = $this->manager->widgets->sanitize_widget_js_instance( $widget_instance );
				$this->manager->set_post_value( $nav_menu_widget_setting->id, $updated_widget_instance );
				$nav_menu_widget_setting->save();

				$this->_widget_nav_menu_updates[ $nav_menu_widget_setting->id ] = $updated_widget_instance;
			}
		}
	}

Changelog

Version Description
4.3.0 Introduced.

© 2003–2021 WordPress Foundation
Licensed under the GNU GPLv2+ License.
https://developer.wordpress.org/reference/classes/wp_customize_nav_menu_setting/update