wp/wp-includes/nav-menu.php
changeset 9 177826044cd9
parent 7 cf61fcea0001
child 16 a86126ab1dd4
equal deleted inserted replaced
8:c7c34916027a 9:177826044cd9
    58  *
    58  *
    59  * @param int|string|WP_Term $menu Menu ID, slug, name, or object of menu to check.
    59  * @param int|string|WP_Term $menu Menu ID, slug, name, or object of menu to check.
    60  * @return bool Whether the menu exists.
    60  * @return bool Whether the menu exists.
    61  */
    61  */
    62 function is_nav_menu( $menu ) {
    62 function is_nav_menu( $menu ) {
    63 	if ( ! $menu )
    63 	if ( ! $menu ) {
    64 		return false;
    64 		return false;
       
    65 	}
    65 
    66 
    66 	$menu_obj = wp_get_nav_menu_object( $menu );
    67 	$menu_obj = wp_get_nav_menu_object( $menu );
    67 
    68 
    68 	if (
    69 	if (
    69 		$menu_obj &&
    70 		$menu_obj &&
    70 		! is_wp_error( $menu_obj ) &&
    71 		! is_wp_error( $menu_obj ) &&
    71 		! empty( $menu_obj->taxonomy ) &&
    72 		! empty( $menu_obj->taxonomy ) &&
    72 		'nav_menu' == $menu_obj->taxonomy
    73 		'nav_menu' == $menu_obj->taxonomy
    73 	)
    74 	) {
    74 		return true;
    75 		return true;
       
    76 	}
    75 
    77 
    76 	return false;
    78 	return false;
    77 }
    79 }
    78 
    80 
    79 /**
    81 /**
   103  * @return bool True on success, false on failure.
   105  * @return bool True on success, false on failure.
   104  */
   106  */
   105 function unregister_nav_menu( $location ) {
   107 function unregister_nav_menu( $location ) {
   106 	global $_wp_registered_nav_menus;
   108 	global $_wp_registered_nav_menus;
   107 
   109 
   108 	if ( is_array( $_wp_registered_nav_menus ) && isset( $_wp_registered_nav_menus[$location] ) ) {
   110 	if ( is_array( $_wp_registered_nav_menus ) && isset( $_wp_registered_nav_menus[ $location ] ) ) {
   109 		unset( $_wp_registered_nav_menus[$location] );
   111 		unset( $_wp_registered_nav_menus[ $location ] );
   110 		if ( empty( $_wp_registered_nav_menus ) ) {
   112 		if ( empty( $_wp_registered_nav_menus ) ) {
   111 			_remove_theme_support( 'menus' );
   113 			_remove_theme_support( 'menus' );
   112 		}
   114 		}
   113 		return true;
   115 		return true;
   114 	}
   116 	}
   135  *
   137  *
   136  * @return array Registered navigation menu locations. If none are registered, an empty array.
   138  * @return array Registered navigation menu locations. If none are registered, an empty array.
   137  */
   139  */
   138 function get_registered_nav_menus() {
   140 function get_registered_nav_menus() {
   139 	global $_wp_registered_nav_menus;
   141 	global $_wp_registered_nav_menus;
   140 	if ( isset( $_wp_registered_nav_menus ) )
   142 	if ( isset( $_wp_registered_nav_menus ) ) {
   141 		return $_wp_registered_nav_menus;
   143 		return $_wp_registered_nav_menus;
       
   144 	}
   142 	return array();
   145 	return array();
   143 }
   146 }
   144 
   147 
   145 /**
   148 /**
   146  * Retrieves all registered navigation menu locations and the menus assigned to them.
   149  * Retrieves all registered navigation menu locations and the menus assigned to them.
   167 function has_nav_menu( $location ) {
   170 function has_nav_menu( $location ) {
   168 	$has_nav_menu = false;
   171 	$has_nav_menu = false;
   169 
   172 
   170 	$registered_nav_menus = get_registered_nav_menus();
   173 	$registered_nav_menus = get_registered_nav_menus();
   171 	if ( isset( $registered_nav_menus[ $location ] ) ) {
   174 	if ( isset( $registered_nav_menus[ $location ] ) ) {
   172 		$locations = get_nav_menu_locations();
   175 		$locations    = get_nav_menu_locations();
   173 		$has_nav_menu = ! empty( $locations[ $location ] );
   176 		$has_nav_menu = ! empty( $locations[ $location ] );
   174 	}
   177 	}
   175 
   178 
   176 	/**
   179 	/**
   177 	 * Filters whether a nav menu is assigned to the specified location.
   180 	 * Filters whether a nav menu is assigned to the specified location.
   251  * @param int|string|WP_Term $menu Menu ID, slug, name, or object.
   254  * @param int|string|WP_Term $menu Menu ID, slug, name, or object.
   252  * @return bool|WP_Error True on success, false or WP_Error object on failure.
   255  * @return bool|WP_Error True on success, false or WP_Error object on failure.
   253  */
   256  */
   254 function wp_delete_nav_menu( $menu ) {
   257 function wp_delete_nav_menu( $menu ) {
   255 	$menu = wp_get_nav_menu_object( $menu );
   258 	$menu = wp_get_nav_menu_object( $menu );
   256 	if ( ! $menu )
   259 	if ( ! $menu ) {
   257 		return false;
   260 		return false;
       
   261 	}
   258 
   262 
   259 	$menu_objects = get_objects_in_term( $menu->term_id, 'nav_menu' );
   263 	$menu_objects = get_objects_in_term( $menu->term_id, 'nav_menu' );
   260 	if ( ! empty( $menu_objects ) ) {
   264 	if ( ! empty( $menu_objects ) ) {
   261 		foreach ( $menu_objects as $item ) {
   265 		foreach ( $menu_objects as $item ) {
   262 			wp_delete_post( $item );
   266 			wp_delete_post( $item );
   266 	$result = wp_delete_term( $menu->term_id, 'nav_menu' );
   270 	$result = wp_delete_term( $menu->term_id, 'nav_menu' );
   267 
   271 
   268 	// Remove this menu from any locations.
   272 	// Remove this menu from any locations.
   269 	$locations = get_nav_menu_locations();
   273 	$locations = get_nav_menu_locations();
   270 	foreach ( $locations as $location => $menu_id ) {
   274 	foreach ( $locations as $location => $menu_id ) {
   271 		if ( $menu_id == $menu->term_id )
   275 		if ( $menu_id == $menu->term_id ) {
   272 			$locations[ $location ] = 0;
   276 			$locations[ $location ] = 0;
       
   277 		}
   273 	}
   278 	}
   274 	set_theme_mod( 'nav_menu_locations', $locations );
   279 	set_theme_mod( 'nav_menu_locations', $locations );
   275 
   280 
   276 	if ( $result && !is_wp_error($result) )
   281 	if ( $result && ! is_wp_error( $result ) ) {
   277 
   282 
   278 		/**
   283 		/**
   279 		 * Fires after a navigation menu has been successfully deleted.
   284 		 * Fires after a navigation menu has been successfully deleted.
   280 		 *
   285 		 *
   281 		 * @since 3.0.0
   286 		 * @since 3.0.0
   282 		 *
   287 		 *
   283 		 * @param int $term_id ID of the deleted menu.
   288 		 * @param int $term_id ID of the deleted menu.
   284 		 */
   289 		 */
   285 		do_action( 'wp_delete_nav_menu', $menu->term_id );
   290 		do_action( 'wp_delete_nav_menu', $menu->term_id );
       
   291 	}
   286 
   292 
   287 	return $result;
   293 	return $result;
   288 }
   294 }
   289 
   295 
   290 /**
   296 /**
   303 	$menu_id = (int) $menu_id;
   309 	$menu_id = (int) $menu_id;
   304 
   310 
   305 	$_menu = wp_get_nav_menu_object( $menu_id );
   311 	$_menu = wp_get_nav_menu_object( $menu_id );
   306 
   312 
   307 	$args = array(
   313 	$args = array(
   308 		'description' => ( isset( $menu_data['description'] ) ? $menu_data['description']  : '' ),
   314 		'description' => ( isset( $menu_data['description'] ) ? $menu_data['description'] : '' ),
   309 		'name'        => ( isset( $menu_data['menu-name']   ) ? $menu_data['menu-name']    : '' ),
   315 		'name'        => ( isset( $menu_data['menu-name'] ) ? $menu_data['menu-name'] : '' ),
   310 		'parent'      => ( isset( $menu_data['parent']      ) ? (int) $menu_data['parent'] : 0  ),
   316 		'parent'      => ( isset( $menu_data['parent'] ) ? (int) $menu_data['parent'] : 0 ),
   311 		'slug'        => null,
   317 		'slug'        => null,
   312 	);
   318 	);
   313 
   319 
   314 	// double-check that we're not going to have one menu take the name of another
   320 	// double-check that we're not going to have one menu take the name of another
   315 	$_possible_existing = get_term_by( 'name', $menu_data['menu-name'], 'nav_menu' );
   321 	$_possible_existing = get_term_by( 'name', $menu_data['menu-name'], 'nav_menu' );
   317 		$_possible_existing &&
   323 		$_possible_existing &&
   318 		! is_wp_error( $_possible_existing ) &&
   324 		! is_wp_error( $_possible_existing ) &&
   319 		isset( $_possible_existing->term_id ) &&
   325 		isset( $_possible_existing->term_id ) &&
   320 		$_possible_existing->term_id != $menu_id
   326 		$_possible_existing->term_id != $menu_id
   321 	) {
   327 	) {
   322 		return new WP_Error( 'menu_exists',
   328 		return new WP_Error(
       
   329 			'menu_exists',
   323 			/* translators: %s: menu name */
   330 			/* translators: %s: menu name */
   324 			sprintf( __( 'The menu name %s conflicts with another menu name. Please try another.' ),
   331 			sprintf(
       
   332 				__( 'The menu name %s conflicts with another menu name. Please try another.' ),
   325 				'<strong>' . esc_html( $menu_data['menu-name'] ) . '</strong>'
   333 				'<strong>' . esc_html( $menu_data['menu-name'] ) . '</strong>'
   326 			)
   334 			)
   327 		);
   335 		);
   328 	}
   336 	}
   329 
   337 
   330 	// menu doesn't already exist, so create a new menu
   338 	// menu doesn't already exist, so create a new menu
   331 	if ( ! $_menu || is_wp_error( $_menu ) ) {
   339 	if ( ! $_menu || is_wp_error( $_menu ) ) {
   332 		$menu_exists = get_term_by( 'name', $menu_data['menu-name'], 'nav_menu' );
   340 		$menu_exists = get_term_by( 'name', $menu_data['menu-name'], 'nav_menu' );
   333 
   341 
   334 		if ( $menu_exists ) {
   342 		if ( $menu_exists ) {
   335 			return new WP_Error( 'menu_exists',
   343 			return new WP_Error(
       
   344 				'menu_exists',
   336 				/* translators: %s: menu name */
   345 				/* translators: %s: menu name */
   337 				sprintf( __( 'The menu name %s conflicts with another menu name. Please try another.' ),
   346 				sprintf(
       
   347 					__( 'The menu name %s conflicts with another menu name. Please try another.' ),
   338 					'<strong>' . esc_html( $menu_data['menu-name'] ) . '</strong>'
   348 					'<strong>' . esc_html( $menu_data['menu-name'] ) . '</strong>'
   339 				)
   349 				)
   340 			);
   350 			);
   341 		}
   351 		}
   342 
   352 
   343 		$_menu = wp_insert_term( $menu_data['menu-name'], 'nav_menu', $args );
   353 		$_menu = wp_insert_term( $menu_data['menu-name'], 'nav_menu', $args );
   344 
   354 
   345 		if ( is_wp_error( $_menu ) )
   355 		if ( is_wp_error( $_menu ) ) {
   346 			return $_menu;
   356 			return $_menu;
       
   357 		}
   347 
   358 
   348 		/**
   359 		/**
   349 		 * Fires after a navigation menu is successfully created.
   360 		 * Fires after a navigation menu is successfully created.
   350 		 *
   361 		 *
   351 		 * @since 3.0.0
   362 		 * @since 3.0.0
   356 		do_action( 'wp_create_nav_menu', $_menu['term_id'], $menu_data );
   367 		do_action( 'wp_create_nav_menu', $_menu['term_id'], $menu_data );
   357 
   368 
   358 		return (int) $_menu['term_id'];
   369 		return (int) $_menu['term_id'];
   359 	}
   370 	}
   360 
   371 
   361 	if ( ! $_menu || ! isset( $_menu->term_id ) )
   372 	if ( ! $_menu || ! isset( $_menu->term_id ) ) {
   362 		return 0;
   373 		return 0;
       
   374 	}
   363 
   375 
   364 	$menu_id = (int) $_menu->term_id;
   376 	$menu_id = (int) $_menu->term_id;
   365 
   377 
   366 	$update_response = wp_update_term( $menu_id, 'nav_menu', $args );
   378 	$update_response = wp_update_term( $menu_id, 'nav_menu', $args );
   367 
   379 
   368 	if ( is_wp_error( $update_response ) )
   380 	if ( is_wp_error( $update_response ) ) {
   369 		return $update_response;
   381 		return $update_response;
       
   382 	}
   370 
   383 
   371 	$menu_id = (int) $update_response['term_id'];
   384 	$menu_id = (int) $update_response['term_id'];
   372 
   385 
   373 	/**
   386 	/**
   374 	 * Fires after a navigation menu has been successfully updated.
   387 	 * Fires after a navigation menu has been successfully updated.
   394  * @param int   $menu_item_db_id The ID of the menu item. If "0", creates a new menu item.
   407  * @param int   $menu_item_db_id The ID of the menu item. If "0", creates a new menu item.
   395  * @param array $menu_item_data  The menu item's data.
   408  * @param array $menu_item_data  The menu item's data.
   396  * @return int|WP_Error The menu item's database ID or WP_Error object on failure.
   409  * @return int|WP_Error The menu item's database ID or WP_Error object on failure.
   397  */
   410  */
   398 function wp_update_nav_menu_item( $menu_id = 0, $menu_item_db_id = 0, $menu_item_data = array() ) {
   411 function wp_update_nav_menu_item( $menu_id = 0, $menu_item_db_id = 0, $menu_item_data = array() ) {
   399 	$menu_id = (int) $menu_id;
   412 	$menu_id         = (int) $menu_id;
   400 	$menu_item_db_id = (int) $menu_item_db_id;
   413 	$menu_item_db_id = (int) $menu_item_db_id;
   401 
   414 
   402 	// make sure that we don't convert non-nav_menu_item objects into nav_menu_item objects
   415 	// make sure that we don't convert non-nav_menu_item objects into nav_menu_item objects
   403 	if ( ! empty( $menu_item_db_id ) && ! is_nav_menu_item( $menu_item_db_id ) )
   416 	if ( ! empty( $menu_item_db_id ) && ! is_nav_menu_item( $menu_item_db_id ) ) {
   404 		return new WP_Error( 'update_nav_menu_item_failed', __( 'The given object ID is not that of a menu item.' ) );
   417 		return new WP_Error( 'update_nav_menu_item_failed', __( 'The given object ID is not that of a menu item.' ) );
       
   418 	}
   405 
   419 
   406 	$menu = wp_get_nav_menu_object( $menu_id );
   420 	$menu = wp_get_nav_menu_object( $menu_id );
   407 
   421 
   408 	if ( ! $menu && 0 !== $menu_id ) {
   422 	if ( ! $menu && 0 !== $menu_id ) {
   409 		return new WP_Error( 'invalid_menu_id', __( 'Invalid menu ID.' ) );
   423 		return new WP_Error( 'invalid_menu_id', __( 'Invalid menu ID.' ) );
   412 	if ( is_wp_error( $menu ) ) {
   426 	if ( is_wp_error( $menu ) ) {
   413 		return $menu;
   427 		return $menu;
   414 	}
   428 	}
   415 
   429 
   416 	$defaults = array(
   430 	$defaults = array(
   417 		'menu-item-db-id' => $menu_item_db_id,
   431 		'menu-item-db-id'       => $menu_item_db_id,
   418 		'menu-item-object-id' => 0,
   432 		'menu-item-object-id'   => 0,
   419 		'menu-item-object' => '',
   433 		'menu-item-object'      => '',
   420 		'menu-item-parent-id' => 0,
   434 		'menu-item-parent-id'   => 0,
   421 		'menu-item-position' => 0,
   435 		'menu-item-position'    => 0,
   422 		'menu-item-type' => 'custom',
   436 		'menu-item-type'        => 'custom',
   423 		'menu-item-title' => '',
   437 		'menu-item-title'       => '',
   424 		'menu-item-url' => '',
   438 		'menu-item-url'         => '',
   425 		'menu-item-description' => '',
   439 		'menu-item-description' => '',
   426 		'menu-item-attr-title' => '',
   440 		'menu-item-attr-title'  => '',
   427 		'menu-item-target' => '',
   441 		'menu-item-target'      => '',
   428 		'menu-item-classes' => '',
   442 		'menu-item-classes'     => '',
   429 		'menu-item-xfn' => '',
   443 		'menu-item-xfn'         => '',
   430 		'menu-item-status' => '',
   444 		'menu-item-status'      => '',
   431 	);
   445 	);
   432 
   446 
   433 	$args = wp_parse_args( $menu_item_data, $defaults );
   447 	$args = wp_parse_args( $menu_item_data, $defaults );
   434 
   448 
   435 	if ( 0 == $menu_id ) {
   449 	if ( 0 == $menu_id ) {
   436 		$args['menu-item-position'] = 1;
   450 		$args['menu-item-position'] = 1;
   437 	} elseif ( 0 == (int) $args['menu-item-position'] ) {
   451 	} elseif ( 0 == (int) $args['menu-item-position'] ) {
   438 		$menu_items = 0 == $menu_id ? array() : (array) wp_get_nav_menu_items( $menu_id, array( 'post_status' => 'publish,draft' ) );
   452 		$menu_items                 = 0 == $menu_id ? array() : (array) wp_get_nav_menu_items( $menu_id, array( 'post_status' => 'publish,draft' ) );
   439 		$last_item = array_pop( $menu_items );
   453 		$last_item                  = array_pop( $menu_items );
   440 		$args['menu-item-position'] = ( $last_item && isset( $last_item->menu_order ) ) ? 1 + $last_item->menu_order : count( $menu_items );
   454 		$args['menu-item-position'] = ( $last_item && isset( $last_item->menu_order ) ) ? 1 + $last_item->menu_order : count( $menu_items );
   441 	}
   455 	}
   442 
   456 
   443 	$original_parent = 0 < $menu_item_db_id ? get_post_field( 'post_parent', $menu_item_db_id ) : 0;
   457 	$original_parent = 0 < $menu_item_db_id ? get_post_field( 'post_parent', $menu_item_db_id ) : 0;
   444 
   458 
   445 	if ( 'custom' != $args['menu-item-type'] ) {
   459 	if ( 'custom' === $args['menu-item-type'] ) {
   446 		/* if non-custom menu item, then:
   460 		// If custom menu item, trim the URL.
   447 			* use original object's URL
   461 		$args['menu-item-url'] = trim( $args['menu-item-url'] );
   448 			* blank default title to sync with original object's
   462 	} else {
   449 		*/
   463 		/*
       
   464 		 * If non-custom menu item, then:
       
   465 		 * - use the original object's URL.
       
   466 		 * - blank default title to sync with the original object's title.
       
   467 		 */
   450 
   468 
   451 		$args['menu-item-url'] = '';
   469 		$args['menu-item-url'] = '';
   452 
   470 
   453 		$original_title = '';
   471 		$original_title = '';
   454 		if ( 'taxonomy' == $args['menu-item-type'] ) {
   472 		if ( 'taxonomy' == $args['menu-item-type'] ) {
   455 			$original_parent = get_term_field( 'parent', $args['menu-item-object-id'], $args['menu-item-object'], 'raw' );
   473 			$original_parent = get_term_field( 'parent', $args['menu-item-object-id'], $args['menu-item-object'], 'raw' );
   456 			$original_title = get_term_field( 'name', $args['menu-item-object-id'], $args['menu-item-object'], 'raw' );
   474 			$original_title  = get_term_field( 'name', $args['menu-item-object-id'], $args['menu-item-object'], 'raw' );
   457 		} elseif ( 'post_type' == $args['menu-item-type'] ) {
   475 		} elseif ( 'post_type' == $args['menu-item-type'] ) {
   458 
   476 
   459 			$original_object = get_post( $args['menu-item-object-id'] );
   477 			$original_object = get_post( $args['menu-item-object-id'] );
   460 			$original_parent = (int) $original_object->post_parent;
   478 			$original_parent = (int) $original_object->post_parent;
   461 			$original_title = $original_object->post_title;
   479 			$original_title  = $original_object->post_title;
   462 		} elseif ( 'post_type_archive' == $args['menu-item-type'] ) {
   480 		} elseif ( 'post_type_archive' == $args['menu-item-type'] ) {
   463 			$original_object = get_post_type_object( $args['menu-item-object'] );
   481 			$original_object = get_post_type_object( $args['menu-item-object'] );
   464 			if ( $original_object ) {
   482 			if ( $original_object ) {
   465 				$original_title = $original_object->labels->archives;
   483 				$original_title = $original_object->labels->archives;
   466 			}
   484 			}
   467 		}
   485 		}
   468 
   486 
   469 		if ( $args['menu-item-title'] == $original_title )
   487 		if ( $args['menu-item-title'] == $original_title ) {
   470 			$args['menu-item-title'] = '';
   488 			$args['menu-item-title'] = '';
       
   489 		}
   471 
   490 
   472 		// hack to get wp to create a post object when too many properties are empty
   491 		// hack to get wp to create a post object when too many properties are empty
   473 		if ( '' ==  $args['menu-item-title'] && '' == $args['menu-item-description'] )
   492 		if ( '' == $args['menu-item-title'] && '' == $args['menu-item-description'] ) {
   474 			$args['menu-item-description'] = ' ';
   493 			$args['menu-item-description'] = ' ';
       
   494 		}
   475 	}
   495 	}
   476 
   496 
   477 	// Populate the menu item object
   497 	// Populate the menu item object
   478 	$post = array(
   498 	$post = array(
   479 		'menu_order' => $args['menu-item-position'],
   499 		'menu_order'   => $args['menu-item-position'],
   480 		'ping_status' => 0,
   500 		'ping_status'  => 0,
   481 		'post_content' => $args['menu-item-description'],
   501 		'post_content' => $args['menu-item-description'],
   482 		'post_excerpt' => $args['menu-item-attr-title'],
   502 		'post_excerpt' => $args['menu-item-attr-title'],
   483 		'post_parent' => $original_parent,
   503 		'post_parent'  => $original_parent,
   484 		'post_title' => $args['menu-item-title'],
   504 		'post_title'   => $args['menu-item-title'],
   485 		'post_type' => 'nav_menu_item',
   505 		'post_type'    => 'nav_menu_item',
   486 	);
   506 	);
   487 
   507 
   488 	$update = 0 != $menu_item_db_id;
   508 	$update = 0 != $menu_item_db_id;
   489 
   509 
   490 	// New menu item. Default is draft status
   510 	// New menu item. Default is draft status
   491 	if ( ! $update ) {
   511 	if ( ! $update ) {
   492 		$post['ID'] = 0;
   512 		$post['ID']          = 0;
   493 		$post['post_status'] = 'publish' == $args['menu-item-status'] ? 'publish' : 'draft';
   513 		$post['post_status'] = 'publish' == $args['menu-item-status'] ? 'publish' : 'draft';
   494 		$menu_item_db_id = wp_insert_post( $post );
   514 		$menu_item_db_id     = wp_insert_post( $post );
   495 		if ( ! $menu_item_db_id	|| is_wp_error( $menu_item_db_id ) )
   515 		if ( ! $menu_item_db_id || is_wp_error( $menu_item_db_id ) ) {
   496 			return $menu_item_db_id;
   516 			return $menu_item_db_id;
       
   517 		}
   497 
   518 
   498 		/**
   519 		/**
   499 		 * Fires immediately after a new navigation menu item has been added.
   520 		 * Fires immediately after a new navigation menu item has been added.
   500 		 *
   521 		 *
   501 		 * @since 4.4.0
   522 		 * @since 4.4.0
   509 		do_action( 'wp_add_nav_menu_item', $menu_id, $menu_item_db_id, $args );
   530 		do_action( 'wp_add_nav_menu_item', $menu_id, $menu_item_db_id, $args );
   510 	}
   531 	}
   511 
   532 
   512 	// Associate the menu item with the menu term
   533 	// Associate the menu item with the menu term
   513 	// Only set the menu term if it isn't set to avoid unnecessary wp_get_object_terms()
   534 	// Only set the menu term if it isn't set to avoid unnecessary wp_get_object_terms()
   514 	 if ( $menu_id && ( ! $update || ! is_object_in_term( $menu_item_db_id, 'nav_menu', (int) $menu->term_id ) ) ) {
   535 	if ( $menu_id && ( ! $update || ! is_object_in_term( $menu_item_db_id, 'nav_menu', (int) $menu->term_id ) ) ) {
   515 		wp_set_object_terms( $menu_item_db_id, array( $menu->term_id ), 'nav_menu' );
   536 		wp_set_object_terms( $menu_item_db_id, array( $menu->term_id ), 'nav_menu' );
   516 	}
   537 	}
   517 
   538 
   518 	if ( 'custom' == $args['menu-item-type'] ) {
   539 	if ( 'custom' == $args['menu-item-type'] ) {
   519 		$args['menu-item-object-id'] = $menu_item_db_id;
   540 		$args['menu-item-object-id'] = $menu_item_db_id;
   520 		$args['menu-item-object'] = 'custom';
   541 		$args['menu-item-object']    = 'custom';
   521 	}
   542 	}
   522 
   543 
   523 	$menu_item_db_id = (int) $menu_item_db_id;
   544 	$menu_item_db_id = (int) $menu_item_db_id;
   524 
   545 
   525 	update_post_meta( $menu_item_db_id, '_menu_item_type', sanitize_key($args['menu-item-type']) );
   546 	update_post_meta( $menu_item_db_id, '_menu_item_type', sanitize_key( $args['menu-item-type'] ) );
   526 	update_post_meta( $menu_item_db_id, '_menu_item_menu_item_parent', strval( (int) $args['menu-item-parent-id'] ) );
   547 	update_post_meta( $menu_item_db_id, '_menu_item_menu_item_parent', strval( (int) $args['menu-item-parent-id'] ) );
   527 	update_post_meta( $menu_item_db_id, '_menu_item_object_id', strval( (int) $args['menu-item-object-id'] ) );
   548 	update_post_meta( $menu_item_db_id, '_menu_item_object_id', strval( (int) $args['menu-item-object-id'] ) );
   528 	update_post_meta( $menu_item_db_id, '_menu_item_object', sanitize_key($args['menu-item-object']) );
   549 	update_post_meta( $menu_item_db_id, '_menu_item_object', sanitize_key( $args['menu-item-object'] ) );
   529 	update_post_meta( $menu_item_db_id, '_menu_item_target', sanitize_key($args['menu-item-target']) );
   550 	update_post_meta( $menu_item_db_id, '_menu_item_target', sanitize_key( $args['menu-item-target'] ) );
   530 
   551 
   531 	$args['menu-item-classes'] = array_map( 'sanitize_html_class', explode( ' ', $args['menu-item-classes'] ) );
   552 	$args['menu-item-classes'] = array_map( 'sanitize_html_class', explode( ' ', $args['menu-item-classes'] ) );
   532 	$args['menu-item-xfn'] = implode( ' ', array_map( 'sanitize_html_class', explode( ' ', $args['menu-item-xfn'] ) ) );
   553 	$args['menu-item-xfn']     = implode( ' ', array_map( 'sanitize_html_class', explode( ' ', $args['menu-item-xfn'] ) ) );
   533 	update_post_meta( $menu_item_db_id, '_menu_item_classes', $args['menu-item-classes'] );
   554 	update_post_meta( $menu_item_db_id, '_menu_item_classes', $args['menu-item-classes'] );
   534 	update_post_meta( $menu_item_db_id, '_menu_item_xfn', $args['menu-item-xfn'] );
   555 	update_post_meta( $menu_item_db_id, '_menu_item_xfn', $args['menu-item-xfn'] );
   535 	update_post_meta( $menu_item_db_id, '_menu_item_url', esc_url_raw($args['menu-item-url']) );
   556 	update_post_meta( $menu_item_db_id, '_menu_item_url', esc_url_raw( $args['menu-item-url'] ) );
   536 
   557 
   537 	if ( 0 == $menu_id )
   558 	if ( 0 == $menu_id ) {
   538 		update_post_meta( $menu_item_db_id, '_menu_item_orphaned', (string) time() );
   559 		update_post_meta( $menu_item_db_id, '_menu_item_orphaned', (string) time() );
   539 	elseif ( get_post_meta( $menu_item_db_id, '_menu_item_orphaned' ) )
   560 	} elseif ( get_post_meta( $menu_item_db_id, '_menu_item_orphaned' ) ) {
   540 		delete_post_meta( $menu_item_db_id, '_menu_item_orphaned' );
   561 		delete_post_meta( $menu_item_db_id, '_menu_item_orphaned' );
       
   562 	}
   541 
   563 
   542 	// Update existing menu item. Default is publish status
   564 	// Update existing menu item. Default is publish status
   543 	if ( $update ) {
   565 	if ( $update ) {
   544 		$post['ID'] = $menu_item_db_id;
   566 		$post['ID']          = $menu_item_db_id;
   545 		$post['post_status'] = 'draft' == $args['menu-item-status'] ? 'draft' : 'publish';
   567 		$post['post_status'] = 'draft' == $args['menu-item-status'] ? 'draft' : 'publish';
   546 		wp_update_post( $post );
   568 		wp_update_post( $post );
   547 	}
   569 	}
   548 
   570 
   549 	/**
   571 	/**
   572  * @param array $args Optional. Array of arguments passed on to get_terms().
   594  * @param array $args Optional. Array of arguments passed on to get_terms().
   573  *                    Default empty array.
   595  *                    Default empty array.
   574  * @return array Menu objects.
   596  * @return array Menu objects.
   575  */
   597  */
   576 function wp_get_nav_menus( $args = array() ) {
   598 function wp_get_nav_menus( $args = array() ) {
   577 	$defaults = array( 'hide_empty' => false, 'orderby' => 'name' );
   599 	$defaults = array(
   578 	$args = wp_parse_args( $args, $defaults );
   600 		'hide_empty' => false,
       
   601 		'orderby'    => 'name',
       
   602 	);
       
   603 	$args     = wp_parse_args( $args, $defaults );
   579 
   604 
   580 	/**
   605 	/**
   581 	 * Filters the navigation menu objects being returned.
   606 	 * Filters the navigation menu objects being returned.
   582 	 *
   607 	 *
   583 	 * @since 3.0.0
   608 	 * @since 3.0.0
   585 	 * @see get_terms()
   610 	 * @see get_terms()
   586 	 *
   611 	 *
   587 	 * @param array $menus An array of menu objects.
   612 	 * @param array $menus An array of menu objects.
   588 	 * @param array $args  An array of arguments used to retrieve menu objects.
   613 	 * @param array $args  An array of arguments used to retrieve menu objects.
   589 	 */
   614 	 */
   590 	return apply_filters( 'wp_get_nav_menus', get_terms( 'nav_menu',  $args), $args );
   615 	return apply_filters( 'wp_get_nav_menus', get_terms( 'nav_menu', $args ), $args );
   591 }
   616 }
   592 
   617 
   593 /**
   618 /**
   594  * Return if a menu item is valid.
   619  * Return if a menu item is valid.
   595  *
   620  *
   613  * indirectly affect the ultimate ordering and content of the resulting nav menu
   638  * indirectly affect the ultimate ordering and content of the resulting nav menu
   614  * items that get returned from this function.
   639  * items that get returned from this function.
   615  *
   640  *
   616  * @since 3.0.0
   641  * @since 3.0.0
   617  *
   642  *
   618  * @global string $_menu_item_sort_prop
       
   619  * @staticvar array $fetched
   643  * @staticvar array $fetched
   620  *
   644  *
   621  * @param int|string|WP_Term $menu Menu ID, slug, name, or object.
   645  * @param int|string|WP_Term $menu Menu ID, slug, name, or object.
   622  * @param array              $args {
   646  * @param array              $args {
   623  *     Optional. Arguments to pass to get_posts().
   647  *     Optional. Arguments to pass to get_posts().
   649 	$items = get_objects_in_term( $menu->term_id, 'nav_menu' );
   673 	$items = get_objects_in_term( $menu->term_id, 'nav_menu' );
   650 	if ( is_wp_error( $items ) ) {
   674 	if ( is_wp_error( $items ) ) {
   651 		return false;
   675 		return false;
   652 	}
   676 	}
   653 
   677 
   654 	$defaults = array( 'order' => 'ASC', 'orderby' => 'menu_order', 'post_type' => 'nav_menu_item',
   678 	$defaults        = array(
   655 		'post_status' => 'publish', 'output' => ARRAY_A, 'output_key' => 'menu_order', 'nopaging' => true );
   679 		'order'       => 'ASC',
   656 	$args = wp_parse_args( $args, $defaults );
   680 		'orderby'     => 'menu_order',
       
   681 		'post_type'   => 'nav_menu_item',
       
   682 		'post_status' => 'publish',
       
   683 		'output'      => ARRAY_A,
       
   684 		'output_key'  => 'menu_order',
       
   685 		'nopaging'    => true,
       
   686 	);
       
   687 	$args            = wp_parse_args( $args, $defaults );
   657 	$args['include'] = $items;
   688 	$args['include'] = $items;
   658 
   689 
   659 	if ( ! empty( $items ) ) {
   690 	if ( ! empty( $items ) ) {
   660 		$items = get_posts( $args );
   691 		$items = get_posts( $args );
   661 	} else {
   692 	} else {
   662 		$items = array();
   693 		$items = array();
   663 	}
   694 	}
   664 
   695 
   665 	// Get all posts and terms at once to prime the caches
   696 	// Get all posts and terms at once to prime the caches
   666 	if ( empty( $fetched[ $menu->term_id ] ) && ! wp_using_ext_object_cache() ) {
   697 	if ( empty( $fetched[ $menu->term_id ] ) && ! wp_using_ext_object_cache() ) {
   667 		$fetched[$menu->term_id] = true;
   698 		$fetched[ $menu->term_id ] = true;
   668 		$posts = array();
   699 		$posts                     = array();
   669 		$terms = array();
   700 		$terms                     = array();
   670 		foreach ( $items as $item ) {
   701 		foreach ( $items as $item ) {
   671 			$object_id = get_post_meta( $item->ID, '_menu_item_object_id', true );
   702 			$object_id = get_post_meta( $item->ID, '_menu_item_object_id', true );
   672 			$object    = get_post_meta( $item->ID, '_menu_item_object',    true );
   703 			$object    = get_post_meta( $item->ID, '_menu_item_object', true );
   673 			$type      = get_post_meta( $item->ID, '_menu_item_type',      true );
   704 			$type      = get_post_meta( $item->ID, '_menu_item_type', true );
   674 
   705 
   675 			if ( 'post_type' == $type )
   706 			if ( 'post_type' == $type ) {
   676 				$posts[$object][] = $object_id;
   707 				$posts[ $object ][] = $object_id;
   677 			elseif ( 'taxonomy' == $type)
   708 			} elseif ( 'taxonomy' == $type ) {
   678 				$terms[$object][] = $object_id;
   709 				$terms[ $object ][] = $object_id;
       
   710 			}
   679 		}
   711 		}
   680 
   712 
   681 		if ( ! empty( $posts ) ) {
   713 		if ( ! empty( $posts ) ) {
   682 			foreach ( array_keys($posts) as $post_type ) {
   714 			foreach ( array_keys( $posts ) as $post_type ) {
   683 				get_posts( array('post__in' => $posts[$post_type], 'post_type' => $post_type, 'nopaging' => true, 'update_post_term_cache' => false) );
   715 				get_posts(
       
   716 					array(
       
   717 						'post__in'               => $posts[ $post_type ],
       
   718 						'post_type'              => $post_type,
       
   719 						'nopaging'               => true,
       
   720 						'update_post_term_cache' => false,
       
   721 					)
       
   722 				);
   684 			}
   723 			}
   685 		}
   724 		}
   686 		unset($posts);
   725 		unset( $posts );
   687 
   726 
   688 		if ( ! empty( $terms ) ) {
   727 		if ( ! empty( $terms ) ) {
   689 			foreach ( array_keys($terms) as $taxonomy ) {
   728 			foreach ( array_keys( $terms ) as $taxonomy ) {
   690 				get_terms( $taxonomy, array(
   729 				get_terms(
   691 					'include' => $terms[ $taxonomy ],
   730 					$taxonomy,
   692 					'hierarchical' => false,
   731 					array(
   693 				) );
   732 						'include'      => $terms[ $taxonomy ],
       
   733 						'hierarchical' => false,
       
   734 					)
       
   735 				);
   694 			}
   736 			}
   695 		}
   737 		}
   696 		unset($terms);
   738 		unset( $terms );
   697 	}
   739 	}
   698 
   740 
   699 	$items = array_map( 'wp_setup_nav_menu_item', $items );
   741 	$items = array_map( 'wp_setup_nav_menu_item', $items );
   700 
   742 
   701 	if ( ! is_admin() ) { // Remove invalid items only in front end
   743 	if ( ! is_admin() ) { // Remove invalid items only in front end
   702 		$items = array_filter( $items, '_is_valid_nav_menu_item' );
   744 		$items = array_filter( $items, '_is_valid_nav_menu_item' );
   703 	}
   745 	}
   704 
   746 
   705 	if ( ARRAY_A == $args['output'] ) {
   747 	if ( ARRAY_A == $args['output'] ) {
   706 		$items = wp_list_sort( $items, array(
   748 		$items = wp_list_sort(
   707 			$args['output_key'] => 'ASC',
   749 			$items,
   708 		) );
   750 			array(
   709 		$i = 1;
   751 				$args['output_key'] => 'ASC',
       
   752 			)
       
   753 		);
       
   754 		$i     = 1;
   710 		foreach ( $items as $k => $item ) {
   755 		foreach ( $items as $k => $item ) {
   711 			$items[$k]->{$args['output_key']} = $i++;
   756 			$items[ $k ]->{$args['output_key']} = $i++;
   712 		}
   757 		}
   713 	}
   758 	}
   714 
   759 
   715 	/**
   760 	/**
   716 	 * Filters the navigation menu items being returned.
   761 	 * Filters the navigation menu items being returned.
   752  * @return object $menu_item The menu item with standard menu item properties.
   797  * @return object $menu_item The menu item with standard menu item properties.
   753  */
   798  */
   754 function wp_setup_nav_menu_item( $menu_item ) {
   799 function wp_setup_nav_menu_item( $menu_item ) {
   755 	if ( isset( $menu_item->post_type ) ) {
   800 	if ( isset( $menu_item->post_type ) ) {
   756 		if ( 'nav_menu_item' == $menu_item->post_type ) {
   801 		if ( 'nav_menu_item' == $menu_item->post_type ) {
   757 			$menu_item->db_id = (int) $menu_item->ID;
   802 			$menu_item->db_id            = (int) $menu_item->ID;
   758 			$menu_item->menu_item_parent = ! isset( $menu_item->menu_item_parent ) ? get_post_meta( $menu_item->ID, '_menu_item_menu_item_parent', true ) : $menu_item->menu_item_parent;
   803 			$menu_item->menu_item_parent = ! isset( $menu_item->menu_item_parent ) ? get_post_meta( $menu_item->ID, '_menu_item_menu_item_parent', true ) : $menu_item->menu_item_parent;
   759 			$menu_item->object_id = ! isset( $menu_item->object_id ) ? get_post_meta( $menu_item->ID, '_menu_item_object_id', true ) : $menu_item->object_id;
   804 			$menu_item->object_id        = ! isset( $menu_item->object_id ) ? get_post_meta( $menu_item->ID, '_menu_item_object_id', true ) : $menu_item->object_id;
   760 			$menu_item->object = ! isset( $menu_item->object ) ? get_post_meta( $menu_item->ID, '_menu_item_object', true ) : $menu_item->object;
   805 			$menu_item->object           = ! isset( $menu_item->object ) ? get_post_meta( $menu_item->ID, '_menu_item_object', true ) : $menu_item->object;
   761 			$menu_item->type = ! isset( $menu_item->type ) ? get_post_meta( $menu_item->ID, '_menu_item_type', true ) : $menu_item->type;
   806 			$menu_item->type             = ! isset( $menu_item->type ) ? get_post_meta( $menu_item->ID, '_menu_item_type', true ) : $menu_item->type;
   762 
   807 
   763 			if ( 'post_type' == $menu_item->type ) {
   808 			if ( 'post_type' == $menu_item->type ) {
   764 				$object = get_post_type_object( $menu_item->object );
   809 				$object = get_post_type_object( $menu_item->object );
   765 				if ( $object ) {
   810 				if ( $object ) {
   766 					$menu_item->type_label = $object->labels->singular_name;
   811 					$menu_item->type_label = $object->labels->singular_name;
   767 				} else {
   812 				} else {
   768 					$menu_item->type_label = $menu_item->object;
   813 					$menu_item->type_label = $menu_item->object;
   769 					$menu_item->_invalid = true;
   814 					$menu_item->_invalid   = true;
   770 				}
   815 				}
   771 
   816 
   772 				if ( 'trash' === get_post_status( $menu_item->object_id ) ) {
   817 				if ( 'trash' === get_post_status( $menu_item->object_id ) ) {
   773 					$menu_item->_invalid = true;
   818 					$menu_item->_invalid = true;
   774 				}
   819 				}
   785 				}
   830 				}
   786 
   831 
   787 				$menu_item->title = '' == $menu_item->post_title ? $original_title : $menu_item->post_title;
   832 				$menu_item->title = '' == $menu_item->post_title ? $original_title : $menu_item->post_title;
   788 
   833 
   789 			} elseif ( 'post_type_archive' == $menu_item->type ) {
   834 			} elseif ( 'post_type_archive' == $menu_item->type ) {
   790 				$object =  get_post_type_object( $menu_item->object );
   835 				$object = get_post_type_object( $menu_item->object );
   791 				if ( $object ) {
   836 				if ( $object ) {
   792 					$menu_item->title = '' == $menu_item->post_title ? $object->labels->archives : $menu_item->post_title;
   837 					$menu_item->title      = '' == $menu_item->post_title ? $object->labels->archives : $menu_item->post_title;
   793 					$post_type_description = $object->description;
   838 					$post_type_description = $object->description;
   794 				} else {
   839 				} else {
   795 					$menu_item->_invalid = true;
   840 					$menu_item->_invalid   = true;
   796 					$post_type_description = '';
   841 					$post_type_description = '';
   797 				}
   842 				}
   798 
   843 
   799 				$menu_item->type_label = __( 'Post Type Archive' );
   844 				$menu_item->type_label = __( 'Post Type Archive' );
   800 				$post_content = wp_trim_words( $menu_item->post_content, 200 );
   845 				$post_content          = wp_trim_words( $menu_item->post_content, 200 );
   801 				$post_type_description = '' == $post_content ? $post_type_description : $post_content;
   846 				$post_type_description = '' == $post_content ? $post_type_description : $post_content;
   802 				$menu_item->url = get_post_type_archive_link( $menu_item->object );
   847 				$menu_item->url        = get_post_type_archive_link( $menu_item->object );
   803 			} elseif ( 'taxonomy' == $menu_item->type ) {
   848 			} elseif ( 'taxonomy' == $menu_item->type ) {
   804 				$object = get_taxonomy( $menu_item->object );
   849 				$object = get_taxonomy( $menu_item->object );
   805 				if ( $object ) {
   850 				if ( $object ) {
   806 					$menu_item->type_label = $object->labels->singular_name;
   851 					$menu_item->type_label = $object->labels->singular_name;
   807 				} else {
   852 				} else {
   808 					$menu_item->type_label = $menu_item->object;
   853 					$menu_item->type_label = $menu_item->object;
   809 					$menu_item->_invalid = true;
   854 					$menu_item->_invalid   = true;
   810 				}
   855 				}
   811 
   856 
   812 				$term_url = get_term_link( (int) $menu_item->object_id, $menu_item->object );
   857 				$term_url       = get_term_link( (int) $menu_item->object_id, $menu_item->object );
   813 				$menu_item->url = !is_wp_error( $term_url ) ? $term_url : '';
   858 				$menu_item->url = ! is_wp_error( $term_url ) ? $term_url : '';
   814 
   859 
   815 				$original_title = get_term_field( 'name', $menu_item->object_id, $menu_item->object, 'raw' );
   860 				$original_title = get_term_field( 'name', $menu_item->object_id, $menu_item->object, 'raw' );
   816 				if ( is_wp_error( $original_title ) )
   861 				if ( is_wp_error( $original_title ) ) {
   817 					$original_title = false;
   862 					$original_title = false;
       
   863 				}
   818 				$menu_item->title = '' == $menu_item->post_title ? $original_title : $menu_item->post_title;
   864 				$menu_item->title = '' == $menu_item->post_title ? $original_title : $menu_item->post_title;
   819 
   865 
   820 			} else {
   866 			} else {
   821 				$menu_item->type_label = __('Custom Link');
   867 				$menu_item->type_label = __( 'Custom Link' );
   822 				$menu_item->title = $menu_item->post_title;
   868 				$menu_item->title      = $menu_item->post_title;
   823 				$menu_item->url = ! isset( $menu_item->url ) ? get_post_meta( $menu_item->ID, '_menu_item_url', true ) : $menu_item->url;
   869 				$menu_item->url        = ! isset( $menu_item->url ) ? get_post_meta( $menu_item->ID, '_menu_item_url', true ) : $menu_item->url;
   824 			}
   870 			}
   825 
   871 
   826 			$menu_item->target = ! isset( $menu_item->target ) ? get_post_meta( $menu_item->ID, '_menu_item_target', true ) : $menu_item->target;
   872 			$menu_item->target = ! isset( $menu_item->target ) ? get_post_meta( $menu_item->ID, '_menu_item_target', true ) : $menu_item->target;
   827 
   873 
   828 			/**
   874 			/**
   844 				 */
   890 				 */
   845 				$menu_item->description = apply_filters( 'nav_menu_description', wp_trim_words( $menu_item->post_content, 200 ) );
   891 				$menu_item->description = apply_filters( 'nav_menu_description', wp_trim_words( $menu_item->post_content, 200 ) );
   846 			}
   892 			}
   847 
   893 
   848 			$menu_item->classes = ! isset( $menu_item->classes ) ? (array) get_post_meta( $menu_item->ID, '_menu_item_classes', true ) : $menu_item->classes;
   894 			$menu_item->classes = ! isset( $menu_item->classes ) ? (array) get_post_meta( $menu_item->ID, '_menu_item_classes', true ) : $menu_item->classes;
   849 			$menu_item->xfn = ! isset( $menu_item->xfn ) ? get_post_meta( $menu_item->ID, '_menu_item_xfn', true ) : $menu_item->xfn;
   895 			$menu_item->xfn     = ! isset( $menu_item->xfn ) ? get_post_meta( $menu_item->ID, '_menu_item_xfn', true ) : $menu_item->xfn;
   850 		} else {
   896 		} else {
   851 			$menu_item->db_id = 0;
   897 			$menu_item->db_id            = 0;
   852 			$menu_item->menu_item_parent = 0;
   898 			$menu_item->menu_item_parent = 0;
   853 			$menu_item->object_id = (int) $menu_item->ID;
   899 			$menu_item->object_id        = (int) $menu_item->ID;
   854 			$menu_item->type = 'post_type';
   900 			$menu_item->type             = 'post_type';
   855 
   901 
   856 			$object = get_post_type_object( $menu_item->post_type );
   902 			$object                = get_post_type_object( $menu_item->post_type );
   857 			$menu_item->object = $object->name;
   903 			$menu_item->object     = $object->name;
   858 			$menu_item->type_label = $object->labels->singular_name;
   904 			$menu_item->type_label = $object->labels->singular_name;
   859 
   905 
   860 			if ( '' === $menu_item->post_title ) {
   906 			if ( '' === $menu_item->post_title ) {
   861 				/* translators: %d: ID of a post */
   907 				/* translators: %d: ID of a post */
   862 				$menu_item->post_title = sprintf( __( '#%d (no title)' ), $menu_item->ID );
   908 				$menu_item->post_title = sprintf( __( '#%d (no title)' ), $menu_item->ID );
   863 			}
   909 			}
   864 
   910 
   865 			$menu_item->title = $menu_item->post_title;
   911 			$menu_item->title  = $menu_item->post_title;
   866 			$menu_item->url = get_permalink( $menu_item->ID );
   912 			$menu_item->url    = get_permalink( $menu_item->ID );
   867 			$menu_item->target = '';
   913 			$menu_item->target = '';
   868 
   914 
   869 			/** This filter is documented in wp-includes/nav-menu.php */
   915 			/** This filter is documented in wp-includes/nav-menu.php */
   870 			$menu_item->attr_title = apply_filters( 'nav_menu_attr_title', '' );
   916 			$menu_item->attr_title = apply_filters( 'nav_menu_attr_title', '' );
   871 
   917 
   872 			/** This filter is documented in wp-includes/nav-menu.php */
   918 			/** This filter is documented in wp-includes/nav-menu.php */
   873 			$menu_item->description = apply_filters( 'nav_menu_description', '' );
   919 			$menu_item->description = apply_filters( 'nav_menu_description', '' );
   874 			$menu_item->classes = array();
   920 			$menu_item->classes     = array();
   875 			$menu_item->xfn = '';
   921 			$menu_item->xfn         = '';
   876 		}
   922 		}
   877 	} elseif ( isset( $menu_item->taxonomy ) ) {
   923 	} elseif ( isset( $menu_item->taxonomy ) ) {
   878 		$menu_item->ID = $menu_item->term_id;
   924 		$menu_item->ID               = $menu_item->term_id;
   879 		$menu_item->db_id = 0;
   925 		$menu_item->db_id            = 0;
   880 		$menu_item->menu_item_parent = 0;
   926 		$menu_item->menu_item_parent = 0;
   881 		$menu_item->object_id = (int) $menu_item->term_id;
   927 		$menu_item->object_id        = (int) $menu_item->term_id;
   882 		$menu_item->post_parent = (int) $menu_item->parent;
   928 		$menu_item->post_parent      = (int) $menu_item->parent;
   883 		$menu_item->type = 'taxonomy';
   929 		$menu_item->type             = 'taxonomy';
   884 
   930 
   885 		$object = get_taxonomy( $menu_item->taxonomy );
   931 		$object                = get_taxonomy( $menu_item->taxonomy );
   886 		$menu_item->object = $object->name;
   932 		$menu_item->object     = $object->name;
   887 		$menu_item->type_label = $object->labels->singular_name;
   933 		$menu_item->type_label = $object->labels->singular_name;
   888 
   934 
   889 		$menu_item->title = $menu_item->name;
   935 		$menu_item->title       = $menu_item->name;
   890 		$menu_item->url = get_term_link( $menu_item, $menu_item->taxonomy );
   936 		$menu_item->url         = get_term_link( $menu_item, $menu_item->taxonomy );
   891 		$menu_item->target = '';
   937 		$menu_item->target      = '';
   892 		$menu_item->attr_title = '';
   938 		$menu_item->attr_title  = '';
   893 		$menu_item->description = get_term_field( 'description', $menu_item->term_id, $menu_item->taxonomy );
   939 		$menu_item->description = get_term_field( 'description', $menu_item->term_id, $menu_item->taxonomy );
   894 		$menu_item->classes = array();
   940 		$menu_item->classes     = array();
   895 		$menu_item->xfn = '';
   941 		$menu_item->xfn         = '';
   896 
   942 
   897 	}
   943 	}
   898 
   944 
   899 	/**
   945 	/**
   900 	 * Filters a navigation menu item object.
   946 	 * Filters a navigation menu item object.
   915  * @param string $object_type The type of object, such as "taxonomy" or "post_type."
   961  * @param string $object_type The type of object, such as "taxonomy" or "post_type."
   916  * @param string $taxonomy    If $object_type is "taxonomy", $taxonomy is the name of the tax that $object_id belongs to
   962  * @param string $taxonomy    If $object_type is "taxonomy", $taxonomy is the name of the tax that $object_id belongs to
   917  * @return array The array of menu item IDs; empty array if none;
   963  * @return array The array of menu item IDs; empty array if none;
   918  */
   964  */
   919 function wp_get_associated_nav_menu_items( $object_id = 0, $object_type = 'post_type', $taxonomy = '' ) {
   965 function wp_get_associated_nav_menu_items( $object_id = 0, $object_type = 'post_type', $taxonomy = '' ) {
   920 	$object_id = (int) $object_id;
   966 	$object_id     = (int) $object_id;
   921 	$menu_item_ids = array();
   967 	$menu_item_ids = array();
   922 
   968 
   923 	$query = new WP_Query;
   969 	$query      = new WP_Query;
   924 	$menu_items = $query->query(
   970 	$menu_items = $query->query(
   925 		array(
   971 		array(
   926 			'meta_key' => '_menu_item_object_id',
   972 			'meta_key'       => '_menu_item_object_id',
   927 			'meta_value' => $object_id,
   973 			'meta_value'     => $object_id,
   928 			'post_status' => 'any',
   974 			'post_status'    => 'any',
   929 			'post_type' => 'nav_menu_item',
   975 			'post_type'      => 'nav_menu_item',
   930 			'posts_per_page' => -1,
   976 			'posts_per_page' => -1,
   931 		)
   977 		)
   932 	);
   978 	);
   933 	foreach ( (array) $menu_items as $menu_item ) {
   979 	foreach ( (array) $menu_items as $menu_item ) {
   934 		if ( isset( $menu_item->ID ) && is_nav_menu_item( $menu_item->ID ) ) {
   980 		if ( isset( $menu_item->ID ) && is_nav_menu_item( $menu_item->ID ) ) {
   956  *
  1002  *
   957  * @since 3.0.0
  1003  * @since 3.0.0
   958  * @access private
  1004  * @access private
   959  *
  1005  *
   960  * @param int $object_id The ID of the original object being trashed.
  1006  * @param int $object_id The ID of the original object being trashed.
   961  *
       
   962  */
  1007  */
   963 function _wp_delete_post_menu_item( $object_id = 0 ) {
  1008 function _wp_delete_post_menu_item( $object_id = 0 ) {
   964 	$object_id = (int) $object_id;
  1009 	$object_id = (int) $object_id;
   965 
  1010 
   966 	$menu_item_ids = wp_get_associated_nav_menu_items( $object_id, 'post_type' );
  1011 	$menu_item_ids = wp_get_associated_nav_menu_items( $object_id, 'post_type' );
   999  * @param string $new_status The new status of the post object.
  1044  * @param string $new_status The new status of the post object.
  1000  * @param string $old_status The old status of the post object.
  1045  * @param string $old_status The old status of the post object.
  1001  * @param object $post       The post object being transitioned from one status to another.
  1046  * @param object $post       The post object being transitioned from one status to another.
  1002  */
  1047  */
  1003 function _wp_auto_add_pages_to_menu( $new_status, $old_status, $post ) {
  1048 function _wp_auto_add_pages_to_menu( $new_status, $old_status, $post ) {
  1004 	if ( 'publish' != $new_status || 'publish' == $old_status || 'page' != $post->post_type )
  1049 	if ( 'publish' != $new_status || 'publish' == $old_status || 'page' != $post->post_type ) {
  1005 		return;
  1050 		return;
  1006 	if ( ! empty( $post->post_parent ) )
  1051 	}
       
  1052 	if ( ! empty( $post->post_parent ) ) {
  1007 		return;
  1053 		return;
       
  1054 	}
  1008 	$auto_add = get_option( 'nav_menu_options' );
  1055 	$auto_add = get_option( 'nav_menu_options' );
  1009 	if ( empty( $auto_add ) || ! is_array( $auto_add ) || ! isset( $auto_add['auto_add'] ) )
  1056 	if ( empty( $auto_add ) || ! is_array( $auto_add ) || ! isset( $auto_add['auto_add'] ) ) {
  1010 		return;
  1057 		return;
       
  1058 	}
  1011 	$auto_add = $auto_add['auto_add'];
  1059 	$auto_add = $auto_add['auto_add'];
  1012 	if ( empty( $auto_add ) || ! is_array( $auto_add ) )
  1060 	if ( empty( $auto_add ) || ! is_array( $auto_add ) ) {
  1013 		return;
  1061 		return;
       
  1062 	}
  1014 
  1063 
  1015 	$args = array(
  1064 	$args = array(
  1016 		'menu-item-object-id' => $post->ID,
  1065 		'menu-item-object-id' => $post->ID,
  1017 		'menu-item-object' => $post->post_type,
  1066 		'menu-item-object'    => $post->post_type,
  1018 		'menu-item-type' => 'post_type',
  1067 		'menu-item-type'      => 'post_type',
  1019 		'menu-item-status' => 'publish',
  1068 		'menu-item-status'    => 'publish',
  1020 	);
  1069 	);
  1021 
  1070 
  1022 	foreach ( $auto_add as $menu_id ) {
  1071 	foreach ( $auto_add as $menu_id ) {
  1023 		$items = wp_get_nav_menu_items( $menu_id, array( 'post_status' => 'publish,draft' ) );
  1072 		$items = wp_get_nav_menu_items( $menu_id, array( 'post_status' => 'publish,draft' ) );
  1024 		if ( ! is_array( $items ) )
  1073 		if ( ! is_array( $items ) ) {
  1025 			continue;
  1074 			continue;
       
  1075 		}
  1026 		foreach ( $items as $item ) {
  1076 		foreach ( $items as $item ) {
  1027 			if ( $post->ID == $item->object_id )
  1077 			if ( $post->ID == $item->object_id ) {
  1028 				continue 2;
  1078 				continue 2;
       
  1079 			}
  1029 		}
  1080 		}
  1030 		wp_update_nav_menu_item( $menu_id, 0, $args );
  1081 		wp_update_nav_menu_item( $menu_id, 0, $args );
  1031 	}
  1082 	}
  1032 }
  1083 }
  1033 
  1084 
  1137 
  1188 
  1138 			// ...and any of the new menu locations...
  1189 			// ...and any of the new menu locations...
  1139 			foreach ( $registered_nav_menus as $new_location => $name ) {
  1190 			foreach ( $registered_nav_menus as $new_location => $name ) {
  1140 
  1191 
  1141 				// ...actually match!
  1192 				// ...actually match!
  1142 				if ( false === stripos( $new_location, $slug ) && false === stripos( $slug, $new_location ) ) {
  1193 				if ( is_string( $new_location ) && false === stripos( $new_location, $slug ) && false === stripos( $slug, $new_location ) ) {
       
  1194 					continue;
       
  1195 				} elseif ( is_numeric( $new_location ) && $new_location !== $slug ) {
  1143 					continue;
  1196 					continue;
  1144 				}
  1197 				}
  1145 
  1198 
  1146 				// Then see if any of the old locations...
  1199 				// Then see if any of the old locations...
  1147 				foreach ( $old_nav_menu_locations as $location => $menu_id ) {
  1200 				foreach ( $old_nav_menu_locations as $location => $menu_id ) {
  1148 
  1201 
  1149 					// ...and any slug in the same group...
  1202 					// ...and any slug in the same group...
  1150 					foreach ( $slug_group as $slug ) {
  1203 					foreach ( $slug_group as $slug ) {
  1151 
  1204 
  1152 						// ... have a match as well.
  1205 						// ... have a match as well.
  1153 						if ( false === stripos( $location, $slug ) && false === stripos( $slug, $location ) ) {
  1206 						if ( is_string( $location ) && false === stripos( $location, $slug ) && false === stripos( $slug, $location ) ) {
       
  1207 							continue;
       
  1208 						} elseif ( is_numeric( $location ) && $location !== $slug ) {
  1154 							continue;
  1209 							continue;
  1155 						}
  1210 						}
  1156 
  1211 
  1157 						// Make sure this location wasn't mapped and removed previously.
  1212 						// Make sure this location wasn't mapped and removed previously.
  1158 						if ( ! empty( $old_nav_menu_locations[ $location ] ) ) {
  1213 						if ( ! empty( $old_nav_menu_locations[ $location ] ) ) {