wp/wp-includes/nav-menu.php
changeset 16 a86126ab1dd4
parent 9 177826044cd9
child 18 be944660c56a
equal deleted inserted replaced
15:3d4e9c994f10 16:a86126ab1dd4
    68 
    68 
    69 	if (
    69 	if (
    70 		$menu_obj &&
    70 		$menu_obj &&
    71 		! is_wp_error( $menu_obj ) &&
    71 		! is_wp_error( $menu_obj ) &&
    72 		! empty( $menu_obj->taxonomy ) &&
    72 		! empty( $menu_obj->taxonomy ) &&
    73 		'nav_menu' == $menu_obj->taxonomy
    73 		'nav_menu' === $menu_obj->taxonomy
    74 	) {
    74 	) {
    75 		return true;
    75 		return true;
    76 	}
    76 	}
    77 
    77 
    78 	return false;
    78 	return false;
    90 function register_nav_menus( $locations = array() ) {
    90 function register_nav_menus( $locations = array() ) {
    91 	global $_wp_registered_nav_menus;
    91 	global $_wp_registered_nav_menus;
    92 
    92 
    93 	add_theme_support( 'menus' );
    93 	add_theme_support( 'menus' );
    94 
    94 
       
    95 	foreach ( $locations as $key => $value ) {
       
    96 		if ( is_int( $key ) ) {
       
    97 			_doing_it_wrong( __FUNCTION__, __( 'Nav menu locations must be strings.' ), '5.3.0' );
       
    98 			break;
       
    99 		}
       
   100 	}
       
   101 
    95 	$_wp_registered_nav_menus = array_merge( (array) $_wp_registered_nav_menus, $locations );
   102 	$_wp_registered_nav_menus = array_merge( (array) $_wp_registered_nav_menus, $locations );
    96 }
   103 }
    97 
   104 
    98 /**
   105 /**
    99  * Unregisters a navigation menu location for a theme.
   106  * Unregisters a navigation menu location for a theme.
   100  *
   107  *
   101  * @since 3.1.0
   108  * @since 3.1.0
       
   109  *
   102  * @global array $_wp_registered_nav_menus
   110  * @global array $_wp_registered_nav_menus
   103  *
   111  *
   104  * @param string $location The menu location identifier.
   112  * @param string $location The menu location identifier.
   105  * @return bool True on success, false on failure.
   113  * @return bool True on success, false on failure.
   106  */
   114  */
   226  *
   234  *
   227  * @param int $menu_item_id The ID of the potential nav menu item.
   235  * @param int $menu_item_id The ID of the potential nav menu item.
   228  * @return bool Whether the given ID is that of a nav menu item.
   236  * @return bool Whether the given ID is that of a nav menu item.
   229  */
   237  */
   230 function is_nav_menu_item( $menu_item_id = 0 ) {
   238 function is_nav_menu_item( $menu_item_id = 0 ) {
   231 	return ( ! is_wp_error( $menu_item_id ) && ( 'nav_menu_item' == get_post_type( $menu_item_id ) ) );
   239 	return ( ! is_wp_error( $menu_item_id ) && ( 'nav_menu_item' === get_post_type( $menu_item_id ) ) );
   232 }
   240 }
   233 
   241 
   234 /**
   242 /**
   235  * Creates a navigation menu.
   243  * Creates a navigation menu.
   236  *
   244  *
   315 		'name'        => ( isset( $menu_data['menu-name'] ) ? $menu_data['menu-name'] : '' ),
   323 		'name'        => ( isset( $menu_data['menu-name'] ) ? $menu_data['menu-name'] : '' ),
   316 		'parent'      => ( isset( $menu_data['parent'] ) ? (int) $menu_data['parent'] : 0 ),
   324 		'parent'      => ( isset( $menu_data['parent'] ) ? (int) $menu_data['parent'] : 0 ),
   317 		'slug'        => null,
   325 		'slug'        => null,
   318 	);
   326 	);
   319 
   327 
   320 	// double-check that we're not going to have one menu take the name of another
   328 	// Double-check that we're not going to have one menu take the name of another.
   321 	$_possible_existing = get_term_by( 'name', $menu_data['menu-name'], 'nav_menu' );
   329 	$_possible_existing = get_term_by( 'name', $menu_data['menu-name'], 'nav_menu' );
   322 	if (
   330 	if (
   323 		$_possible_existing &&
   331 		$_possible_existing &&
   324 		! is_wp_error( $_possible_existing ) &&
   332 		! is_wp_error( $_possible_existing ) &&
   325 		isset( $_possible_existing->term_id ) &&
   333 		isset( $_possible_existing->term_id ) &&
   326 		$_possible_existing->term_id != $menu_id
   334 		$_possible_existing->term_id != $menu_id
   327 	) {
   335 	) {
   328 		return new WP_Error(
   336 		return new WP_Error(
   329 			'menu_exists',
   337 			'menu_exists',
   330 			/* translators: %s: menu name */
       
   331 			sprintf(
   338 			sprintf(
       
   339 				/* translators: %s: Menu name. */
   332 				__( 'The menu name %s conflicts with another menu name. Please try another.' ),
   340 				__( 'The menu name %s conflicts with another menu name. Please try another.' ),
   333 				'<strong>' . esc_html( $menu_data['menu-name'] ) . '</strong>'
   341 				'<strong>' . esc_html( $menu_data['menu-name'] ) . '</strong>'
   334 			)
   342 			)
   335 		);
   343 		);
   336 	}
   344 	}
   337 
   345 
   338 	// menu doesn't already exist, so create a new menu
   346 	// Menu doesn't already exist, so create a new menu.
   339 	if ( ! $_menu || is_wp_error( $_menu ) ) {
   347 	if ( ! $_menu || is_wp_error( $_menu ) ) {
   340 		$menu_exists = get_term_by( 'name', $menu_data['menu-name'], 'nav_menu' );
   348 		$menu_exists = get_term_by( 'name', $menu_data['menu-name'], 'nav_menu' );
   341 
   349 
   342 		if ( $menu_exists ) {
   350 		if ( $menu_exists ) {
   343 			return new WP_Error(
   351 			return new WP_Error(
   344 				'menu_exists',
   352 				'menu_exists',
   345 				/* translators: %s: menu name */
       
   346 				sprintf(
   353 				sprintf(
       
   354 					/* translators: %s: Menu name. */
   347 					__( 'The menu name %s conflicts with another menu name. Please try another.' ),
   355 					__( 'The menu name %s conflicts with another menu name. Please try another.' ),
   348 					'<strong>' . esc_html( $menu_data['menu-name'] ) . '</strong>'
   356 					'<strong>' . esc_html( $menu_data['menu-name'] ) . '</strong>'
   349 				)
   357 				)
   350 			);
   358 			);
   351 		}
   359 		}
   410  */
   418  */
   411 function wp_update_nav_menu_item( $menu_id = 0, $menu_item_db_id = 0, $menu_item_data = array() ) {
   419 function wp_update_nav_menu_item( $menu_id = 0, $menu_item_db_id = 0, $menu_item_data = array() ) {
   412 	$menu_id         = (int) $menu_id;
   420 	$menu_id         = (int) $menu_id;
   413 	$menu_item_db_id = (int) $menu_item_db_id;
   421 	$menu_item_db_id = (int) $menu_item_db_id;
   414 
   422 
   415 	// make sure that we don't convert non-nav_menu_item objects into nav_menu_item objects
   423 	// Make sure that we don't convert non-nav_menu_item objects into nav_menu_item objects.
   416 	if ( ! empty( $menu_item_db_id ) && ! is_nav_menu_item( $menu_item_db_id ) ) {
   424 	if ( ! empty( $menu_item_db_id ) && ! is_nav_menu_item( $menu_item_db_id ) ) {
   417 		return new WP_Error( 'update_nav_menu_item_failed', __( 'The given object ID is not that of a menu item.' ) );
   425 		return new WP_Error( 'update_nav_menu_item_failed', __( 'The given object ID is not that of a menu item.' ) );
   418 	}
   426 	}
   419 
   427 
   420 	$menu = wp_get_nav_menu_object( $menu_id );
   428 	$menu = wp_get_nav_menu_object( $menu_id );
   467 		 */
   475 		 */
   468 
   476 
   469 		$args['menu-item-url'] = '';
   477 		$args['menu-item-url'] = '';
   470 
   478 
   471 		$original_title = '';
   479 		$original_title = '';
   472 		if ( 'taxonomy' == $args['menu-item-type'] ) {
   480 		if ( 'taxonomy' === $args['menu-item-type'] ) {
   473 			$original_parent = get_term_field( 'parent', $args['menu-item-object-id'], $args['menu-item-object'], 'raw' );
   481 			$original_parent = get_term_field( 'parent', $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' );
   482 			$original_title  = get_term_field( 'name', $args['menu-item-object-id'], $args['menu-item-object'], 'raw' );
   475 		} elseif ( 'post_type' == $args['menu-item-type'] ) {
   483 		} elseif ( 'post_type' === $args['menu-item-type'] ) {
   476 
   484 
   477 			$original_object = get_post( $args['menu-item-object-id'] );
   485 			$original_object = get_post( $args['menu-item-object-id'] );
   478 			$original_parent = (int) $original_object->post_parent;
   486 			$original_parent = (int) $original_object->post_parent;
   479 			$original_title  = $original_object->post_title;
   487 			$original_title  = $original_object->post_title;
   480 		} elseif ( 'post_type_archive' == $args['menu-item-type'] ) {
   488 		} elseif ( 'post_type_archive' === $args['menu-item-type'] ) {
   481 			$original_object = get_post_type_object( $args['menu-item-object'] );
   489 			$original_object = get_post_type_object( $args['menu-item-object'] );
   482 			if ( $original_object ) {
   490 			if ( $original_object ) {
   483 				$original_title = $original_object->labels->archives;
   491 				$original_title = $original_object->labels->archives;
   484 			}
   492 			}
   485 		}
   493 		}
   486 
   494 
   487 		if ( $args['menu-item-title'] == $original_title ) {
   495 		if ( wp_unslash( $args['menu-item-title'] ) === wp_specialchars_decode( $original_title ) ) {
   488 			$args['menu-item-title'] = '';
   496 			$args['menu-item-title'] = '';
   489 		}
   497 		}
   490 
   498 
   491 		// hack to get wp to create a post object when too many properties are empty
   499 		// Hack to get wp to create a post object when too many properties are empty.
   492 		if ( '' == $args['menu-item-title'] && '' == $args['menu-item-description'] ) {
   500 		if ( '' === $args['menu-item-title'] && '' === $args['menu-item-description'] ) {
   493 			$args['menu-item-description'] = ' ';
   501 			$args['menu-item-description'] = ' ';
   494 		}
   502 		}
   495 	}
   503 	}
   496 
   504 
   497 	// Populate the menu item object
   505 	// Populate the menu item object.
   498 	$post = array(
   506 	$post = array(
   499 		'menu_order'   => $args['menu-item-position'],
   507 		'menu_order'   => $args['menu-item-position'],
   500 		'ping_status'  => 0,
   508 		'ping_status'  => 0,
   501 		'post_content' => $args['menu-item-description'],
   509 		'post_content' => $args['menu-item-description'],
   502 		'post_excerpt' => $args['menu-item-attr-title'],
   510 		'post_excerpt' => $args['menu-item-attr-title'],
   505 		'post_type'    => 'nav_menu_item',
   513 		'post_type'    => 'nav_menu_item',
   506 	);
   514 	);
   507 
   515 
   508 	$update = 0 != $menu_item_db_id;
   516 	$update = 0 != $menu_item_db_id;
   509 
   517 
   510 	// New menu item. Default is draft status
   518 	// New menu item. Default is draft status.
   511 	if ( ! $update ) {
   519 	if ( ! $update ) {
   512 		$post['ID']          = 0;
   520 		$post['ID']          = 0;
   513 		$post['post_status'] = 'publish' == $args['menu-item-status'] ? 'publish' : 'draft';
   521 		$post['post_status'] = 'publish' === $args['menu-item-status'] ? 'publish' : 'draft';
   514 		$menu_item_db_id     = wp_insert_post( $post );
   522 		$menu_item_db_id     = wp_insert_post( $post );
   515 		if ( ! $menu_item_db_id || is_wp_error( $menu_item_db_id ) ) {
   523 		if ( ! $menu_item_db_id || is_wp_error( $menu_item_db_id ) ) {
   516 			return $menu_item_db_id;
   524 			return $menu_item_db_id;
   517 		}
   525 		}
   518 
   526 
   528 		 * @param array $args            An array of arguments used to update/add the menu item.
   536 		 * @param array $args            An array of arguments used to update/add the menu item.
   529 		 */
   537 		 */
   530 		do_action( 'wp_add_nav_menu_item', $menu_id, $menu_item_db_id, $args );
   538 		do_action( 'wp_add_nav_menu_item', $menu_id, $menu_item_db_id, $args );
   531 	}
   539 	}
   532 
   540 
   533 	// Associate the menu item with the menu term
   541 	// Associate the menu item with the menu term.
   534 	// Only set the menu term if it isn't set to avoid unnecessary wp_get_object_terms()
   542 	// Only set the menu term if it isn't set to avoid unnecessary wp_get_object_terms().
   535 	if ( $menu_id && ( ! $update || ! is_object_in_term( $menu_item_db_id, 'nav_menu', (int) $menu->term_id ) ) ) {
   543 	if ( $menu_id && ( ! $update || ! is_object_in_term( $menu_item_db_id, 'nav_menu', (int) $menu->term_id ) ) ) {
   536 		wp_set_object_terms( $menu_item_db_id, array( $menu->term_id ), 'nav_menu' );
   544 		wp_set_object_terms( $menu_item_db_id, array( $menu->term_id ), 'nav_menu' );
   537 	}
   545 	}
   538 
   546 
   539 	if ( 'custom' == $args['menu-item-type'] ) {
   547 	if ( 'custom' === $args['menu-item-type'] ) {
   540 		$args['menu-item-object-id'] = $menu_item_db_id;
   548 		$args['menu-item-object-id'] = $menu_item_db_id;
   541 		$args['menu-item-object']    = 'custom';
   549 		$args['menu-item-object']    = 'custom';
   542 	}
   550 	}
   543 
   551 
   544 	$menu_item_db_id = (int) $menu_item_db_id;
   552 	$menu_item_db_id = (int) $menu_item_db_id;
   559 		update_post_meta( $menu_item_db_id, '_menu_item_orphaned', (string) time() );
   567 		update_post_meta( $menu_item_db_id, '_menu_item_orphaned', (string) time() );
   560 	} elseif ( get_post_meta( $menu_item_db_id, '_menu_item_orphaned' ) ) {
   568 	} elseif ( get_post_meta( $menu_item_db_id, '_menu_item_orphaned' ) ) {
   561 		delete_post_meta( $menu_item_db_id, '_menu_item_orphaned' );
   569 		delete_post_meta( $menu_item_db_id, '_menu_item_orphaned' );
   562 	}
   570 	}
   563 
   571 
   564 	// Update existing menu item. Default is publish status
   572 	// Update existing menu item. Default is publish status.
   565 	if ( $update ) {
   573 	if ( $update ) {
   566 		$post['ID']          = $menu_item_db_id;
   574 		$post['ID']          = $menu_item_db_id;
   567 		$post['post_status'] = 'draft' == $args['menu-item-status'] ? 'draft' : 'publish';
   575 		$post['post_status'] = ( 'draft' === $args['menu-item-status'] ) ? 'draft' : 'publish';
   568 		wp_update_post( $post );
   576 		wp_update_post( $post );
   569 	}
   577 	}
   570 
   578 
   571 	/**
   579 	/**
   572 	 * Fires after a navigation menu item has been updated.
   580 	 * Fires after a navigation menu item has been updated.
   591  * @since 4.1.0 Default value of the 'orderby' argument was changed from 'none'
   599  * @since 4.1.0 Default value of the 'orderby' argument was changed from 'none'
   592  *              to 'name'.
   600  *              to 'name'.
   593  *
   601  *
   594  * @param array $args Optional. Array of arguments passed on to get_terms().
   602  * @param array $args Optional. Array of arguments passed on to get_terms().
   595  *                    Default empty array.
   603  *                    Default empty array.
   596  * @return array Menu objects.
   604  * @return WP_Term[] An array of menu objects.
   597  */
   605  */
   598 function wp_get_nav_menus( $args = array() ) {
   606 function wp_get_nav_menus( $args = array() ) {
   599 	$defaults = array(
   607 	$defaults = array(
       
   608 		'taxonomy'   => 'nav_menu',
   600 		'hide_empty' => false,
   609 		'hide_empty' => false,
   601 		'orderby'    => 'name',
   610 		'orderby'    => 'name',
   602 	);
   611 	);
   603 	$args     = wp_parse_args( $args, $defaults );
   612 	$args     = wp_parse_args( $args, $defaults );
   604 
   613 
   607 	 *
   616 	 *
   608 	 * @since 3.0.0
   617 	 * @since 3.0.0
   609 	 *
   618 	 *
   610 	 * @see get_terms()
   619 	 * @see get_terms()
   611 	 *
   620 	 *
   612 	 * @param array $menus An array of menu objects.
   621 	 * @param WP_Term[] $menus An array of menu objects.
   613 	 * @param array $args  An array of arguments used to retrieve menu objects.
   622 	 * @param array     $args  An array of arguments used to retrieve menu objects.
   614 	 */
   623 	 */
   615 	return apply_filters( 'wp_get_nav_menus', get_terms( 'nav_menu', $args ), $args );
   624 	return apply_filters( 'wp_get_nav_menus', get_terms( $args ), $args );
   616 }
   625 }
   617 
   626 
   618 /**
   627 /**
   619  * Return if a menu item is valid.
   628  * Return if a menu item is valid.
   620  *
   629  *
   637  * specifically for retrieving nav_menu_item posts from get_posts() and may only
   646  * specifically for retrieving nav_menu_item posts from get_posts() and may only
   638  * indirectly affect the ultimate ordering and content of the resulting nav menu
   647  * indirectly affect the ultimate ordering and content of the resulting nav menu
   639  * items that get returned from this function.
   648  * items that get returned from this function.
   640  *
   649  *
   641  * @since 3.0.0
   650  * @since 3.0.0
   642  *
       
   643  * @staticvar array $fetched
       
   644  *
   651  *
   645  * @param int|string|WP_Term $menu Menu ID, slug, name, or object.
   652  * @param int|string|WP_Term $menu Menu ID, slug, name, or object.
   646  * @param array              $args {
   653  * @param array              $args {
   647  *     Optional. Arguments to pass to get_posts().
   654  *     Optional. Arguments to pass to get_posts().
   648  *
   655  *
   657  *     @type string $output_key  Key to use for ordering the actual menu items that get returned. Note that
   664  *     @type string $output_key  Key to use for ordering the actual menu items that get returned. Note that
   658  *                               that is not a get_posts() argument and will only affect output of menu items
   665  *                               that is not a get_posts() argument and will only affect output of menu items
   659  *                               processed in this function. Default 'menu_order'.
   666  *                               processed in this function. Default 'menu_order'.
   660  *     @type bool   $nopaging    Whether to retrieve all menu items (true) or paginate (false). Default true.
   667  *     @type bool   $nopaging    Whether to retrieve all menu items (true) or paginate (false). Default true.
   661  * }
   668  * }
   662  * @return false|array $items Array of menu items, otherwise false.
   669  * @return array|false Array of menu items, otherwise false.
   663  */
   670  */
   664 function wp_get_nav_menu_items( $menu, $args = array() ) {
   671 function wp_get_nav_menu_items( $menu, $args = array() ) {
   665 	$menu = wp_get_nav_menu_object( $menu );
   672 	$menu = wp_get_nav_menu_object( $menu );
   666 
   673 
   667 	if ( ! $menu ) {
   674 	if ( ! $menu ) {
   691 		$items = get_posts( $args );
   698 		$items = get_posts( $args );
   692 	} else {
   699 	} else {
   693 		$items = array();
   700 		$items = array();
   694 	}
   701 	}
   695 
   702 
   696 	// Get all posts and terms at once to prime the caches
   703 	// Get all posts and terms at once to prime the caches.
   697 	if ( empty( $fetched[ $menu->term_id ] ) && ! wp_using_ext_object_cache() ) {
   704 	if ( empty( $fetched[ $menu->term_id ] ) && ! wp_using_ext_object_cache() ) {
   698 		$fetched[ $menu->term_id ] = true;
   705 		$fetched[ $menu->term_id ] = true;
   699 		$posts                     = array();
   706 		$posts                     = array();
   700 		$terms                     = array();
   707 		$terms                     = array();
   701 		foreach ( $items as $item ) {
   708 		foreach ( $items as $item ) {
   702 			$object_id = get_post_meta( $item->ID, '_menu_item_object_id', true );
   709 			$object_id = get_post_meta( $item->ID, '_menu_item_object_id', true );
   703 			$object    = get_post_meta( $item->ID, '_menu_item_object', true );
   710 			$object    = get_post_meta( $item->ID, '_menu_item_object', true );
   704 			$type      = get_post_meta( $item->ID, '_menu_item_type', true );
   711 			$type      = get_post_meta( $item->ID, '_menu_item_type', true );
   705 
   712 
   706 			if ( 'post_type' == $type ) {
   713 			if ( 'post_type' === $type ) {
   707 				$posts[ $object ][] = $object_id;
   714 				$posts[ $object ][] = $object_id;
   708 			} elseif ( 'taxonomy' == $type ) {
   715 			} elseif ( 'taxonomy' === $type ) {
   709 				$terms[ $object ][] = $object_id;
   716 				$terms[ $object ][] = $object_id;
   710 			}
   717 			}
   711 		}
   718 		}
   712 
   719 
   713 		if ( ! empty( $posts ) ) {
   720 		if ( ! empty( $posts ) ) {
   725 		unset( $posts );
   732 		unset( $posts );
   726 
   733 
   727 		if ( ! empty( $terms ) ) {
   734 		if ( ! empty( $terms ) ) {
   728 			foreach ( array_keys( $terms ) as $taxonomy ) {
   735 			foreach ( array_keys( $terms ) as $taxonomy ) {
   729 				get_terms(
   736 				get_terms(
   730 					$taxonomy,
       
   731 					array(
   737 					array(
       
   738 						'taxonomy'     => $taxonomy,
   732 						'include'      => $terms[ $taxonomy ],
   739 						'include'      => $terms[ $taxonomy ],
   733 						'hierarchical' => false,
   740 						'hierarchical' => false,
   734 					)
   741 					)
   735 				);
   742 				);
   736 			}
   743 			}
   738 		unset( $terms );
   745 		unset( $terms );
   739 	}
   746 	}
   740 
   747 
   741 	$items = array_map( 'wp_setup_nav_menu_item', $items );
   748 	$items = array_map( 'wp_setup_nav_menu_item', $items );
   742 
   749 
   743 	if ( ! is_admin() ) { // Remove invalid items only in front end
   750 	if ( ! is_admin() ) { // Remove invalid items only on front end.
   744 		$items = array_filter( $items, '_is_valid_nav_menu_item' );
   751 		$items = array_filter( $items, '_is_valid_nav_menu_item' );
   745 	}
   752 	}
   746 
   753 
   747 	if ( ARRAY_A == $args['output'] ) {
   754 	if ( ARRAY_A == $args['output'] ) {
   748 		$items = wp_list_sort(
   755 		$items = wp_list_sort(
   777  * - attr_title:       The title attribute of the link element for this menu item.
   784  * - attr_title:       The title attribute of the link element for this menu item.
   778  * - classes:          The array of class attribute values for the link element of this menu item.
   785  * - classes:          The array of class attribute values for the link element of this menu item.
   779  * - db_id:            The DB ID of this item as a nav_menu_item object, if it exists (0 if it doesn't exist).
   786  * - db_id:            The DB ID of this item as a nav_menu_item object, if it exists (0 if it doesn't exist).
   780  * - description:      The description of this menu item.
   787  * - description:      The description of this menu item.
   781  * - menu_item_parent: The DB ID of the nav_menu_item that is this item's menu parent, if any. 0 otherwise.
   788  * - menu_item_parent: The DB ID of the nav_menu_item that is this item's menu parent, if any. 0 otherwise.
   782  * - object:           The type of object originally represented, such as "category," "post", or "attachment."
   789  * - object:           The type of object originally represented, such as 'category', 'post', or 'attachment'.
   783  * - object_id:        The DB ID of the original object this menu item represents, e.g. ID for posts and term_id for categories.
   790  * - object_id:        The DB ID of the original object this menu item represents, e.g. ID for posts and term_id for categories.
   784  * - post_parent:      The DB ID of the original object's parent object, if any (0 otherwise).
   791  * - post_parent:      The DB ID of the original object's parent object, if any (0 otherwise).
   785  * - post_title:       A "no title" label if menu item represents a post that lacks a title.
   792  * - post_title:       A "no title" label if menu item represents a post that lacks a title.
   786  * - target:           The target attribute of the link element for this menu item.
   793  * - target:           The target attribute of the link element for this menu item.
   787  * - title:            The title of this menu item.
   794  * - title:            The title of this menu item.
   788  * - type:             The family of objects originally represented, such as "post_type" or "taxonomy."
   795  * - type:             The family of objects originally represented, such as 'post_type' or 'taxonomy'.
   789  * - type_label:       The singular label used to describe this type of menu item.
   796  * - type_label:       The singular label used to describe this type of menu item.
   790  * - url:              The URL to which this menu item points.
   797  * - url:              The URL to which this menu item points.
   791  * - xfn:              The XFN relationship expressed in the link of this menu item.
   798  * - xfn:              The XFN relationship expressed in the link of this menu item.
   792  * - _invalid:         Whether the menu item represents an object that no longer exists.
   799  * - _invalid:         Whether the menu item represents an object that no longer exists.
   793  *
   800  *
   794  * @since 3.0.0
   801  * @since 3.0.0
   795  *
   802  *
   796  * @param object $menu_item The menu item to modify.
   803  * @param object $menu_item The menu item to modify.
   797  * @return object $menu_item The menu item with standard menu item properties.
   804  * @return object The menu item with standard menu item properties.
   798  */
   805  */
   799 function wp_setup_nav_menu_item( $menu_item ) {
   806 function wp_setup_nav_menu_item( $menu_item ) {
   800 	if ( isset( $menu_item->post_type ) ) {
   807 	if ( isset( $menu_item->post_type ) ) {
   801 		if ( 'nav_menu_item' == $menu_item->post_type ) {
   808 		if ( 'nav_menu_item' === $menu_item->post_type ) {
   802 			$menu_item->db_id            = (int) $menu_item->ID;
   809 			$menu_item->db_id            = (int) $menu_item->ID;
   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;
   810 			$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;
   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;
   811 			$menu_item->object_id        = ! isset( $menu_item->object_id ) ? get_post_meta( $menu_item->ID, '_menu_item_object_id', true ) : $menu_item->object_id;
   805 			$menu_item->object           = ! isset( $menu_item->object ) ? get_post_meta( $menu_item->ID, '_menu_item_object', true ) : $menu_item->object;
   812 			$menu_item->object           = ! isset( $menu_item->object ) ? get_post_meta( $menu_item->ID, '_menu_item_object', true ) : $menu_item->object;
   806 			$menu_item->type             = ! isset( $menu_item->type ) ? get_post_meta( $menu_item->ID, '_menu_item_type', true ) : $menu_item->type;
   813 			$menu_item->type             = ! isset( $menu_item->type ) ? get_post_meta( $menu_item->ID, '_menu_item_type', true ) : $menu_item->type;
   807 
   814 
   808 			if ( 'post_type' == $menu_item->type ) {
   815 			if ( 'post_type' === $menu_item->type ) {
   809 				$object = get_post_type_object( $menu_item->object );
   816 				$object = get_post_type_object( $menu_item->object );
   810 				if ( $object ) {
   817 				if ( $object ) {
   811 					$menu_item->type_label = $object->labels->singular_name;
   818 					$menu_item->type_label = $object->labels->singular_name;
       
   819 					// Denote post states for special pages (only in the admin).
       
   820 					if ( function_exists( 'get_post_states' ) ) {
       
   821 						$menu_post   = get_post( $menu_item->object_id );
       
   822 						$post_states = get_post_states( $menu_post );
       
   823 						if ( $post_states ) {
       
   824 							$menu_item->type_label = wp_strip_all_tags( implode( ', ', $post_states ) );
       
   825 						}
       
   826 					}
   812 				} else {
   827 				} else {
   813 					$menu_item->type_label = $menu_item->object;
   828 					$menu_item->type_label = $menu_item->object;
   814 					$menu_item->_invalid   = true;
   829 					$menu_item->_invalid   = true;
   815 				}
   830 				}
   816 
   831 
   817 				if ( 'trash' === get_post_status( $menu_item->object_id ) ) {
   832 				if ( 'trash' === get_post_status( $menu_item->object_id ) ) {
   818 					$menu_item->_invalid = true;
   833 					$menu_item->_invalid = true;
   819 				}
   834 				}
   820 
   835 
   821 				$menu_item->url = get_permalink( $menu_item->object_id );
       
   822 
       
   823 				$original_object = get_post( $menu_item->object_id );
   836 				$original_object = get_post( $menu_item->object_id );
   824 				/** This filter is documented in wp-includes/post-template.php */
   837 
   825 				$original_title = apply_filters( 'the_title', $original_object->post_title, $original_object->ID );
   838 				if ( $original_object ) {
       
   839 					$menu_item->url = get_permalink( $original_object->ID );
       
   840 					/** This filter is documented in wp-includes/post-template.php */
       
   841 					$original_title = apply_filters( 'the_title', $original_object->post_title, $original_object->ID );
       
   842 				} else {
       
   843 					$menu_item->url      = '';
       
   844 					$original_title      = '';
       
   845 					$menu_item->_invalid = true;
       
   846 				}
   826 
   847 
   827 				if ( '' === $original_title ) {
   848 				if ( '' === $original_title ) {
   828 					/* translators: %d: ID of a post */
   849 					/* translators: %d: ID of a post. */
   829 					$original_title = sprintf( __( '#%d (no title)' ), $original_object->ID );
   850 					$original_title = sprintf( __( '#%d (no title)' ), $menu_item->object_id );
   830 				}
   851 				}
   831 
   852 
   832 				$menu_item->title = '' == $menu_item->post_title ? $original_title : $menu_item->post_title;
   853 				$menu_item->title = ( '' === $menu_item->post_title ) ? $original_title : $menu_item->post_title;
   833 
   854 
   834 			} elseif ( 'post_type_archive' == $menu_item->type ) {
   855 			} elseif ( 'post_type_archive' === $menu_item->type ) {
   835 				$object = get_post_type_object( $menu_item->object );
   856 				$object = get_post_type_object( $menu_item->object );
   836 				if ( $object ) {
   857 				if ( $object ) {
   837 					$menu_item->title      = '' == $menu_item->post_title ? $object->labels->archives : $menu_item->post_title;
   858 					$menu_item->title      = ( '' === $menu_item->post_title ) ? $object->labels->archives : $menu_item->post_title;
   838 					$post_type_description = $object->description;
   859 					$post_type_description = $object->description;
   839 				} else {
   860 				} else {
       
   861 					$post_type_description = '';
   840 					$menu_item->_invalid   = true;
   862 					$menu_item->_invalid   = true;
   841 					$post_type_description = '';
       
   842 				}
   863 				}
   843 
   864 
   844 				$menu_item->type_label = __( 'Post Type Archive' );
   865 				$menu_item->type_label = __( 'Post Type Archive' );
   845 				$post_content          = wp_trim_words( $menu_item->post_content, 200 );
   866 				$post_content          = wp_trim_words( $menu_item->post_content, 200 );
   846 				$post_type_description = '' == $post_content ? $post_type_description : $post_content;
   867 				$post_type_description = ( '' === $post_content ) ? $post_type_description : $post_content;
   847 				$menu_item->url        = get_post_type_archive_link( $menu_item->object );
   868 				$menu_item->url        = get_post_type_archive_link( $menu_item->object );
   848 			} elseif ( 'taxonomy' == $menu_item->type ) {
   869 
       
   870 			} elseif ( 'taxonomy' === $menu_item->type ) {
   849 				$object = get_taxonomy( $menu_item->object );
   871 				$object = get_taxonomy( $menu_item->object );
   850 				if ( $object ) {
   872 				if ( $object ) {
   851 					$menu_item->type_label = $object->labels->singular_name;
   873 					$menu_item->type_label = $object->labels->singular_name;
   852 				} else {
   874 				} else {
   853 					$menu_item->type_label = $menu_item->object;
   875 					$menu_item->type_label = $menu_item->object;
   854 					$menu_item->_invalid   = true;
   876 					$menu_item->_invalid   = true;
   855 				}
   877 				}
   856 
   878 
   857 				$term_url       = get_term_link( (int) $menu_item->object_id, $menu_item->object );
   879 				$original_object = get_term( (int) $menu_item->object_id, $menu_item->object );
   858 				$menu_item->url = ! is_wp_error( $term_url ) ? $term_url : '';
   880 
   859 
   881 				if ( $original_object && ! is_wp_error( $original_object ) ) {
   860 				$original_title = get_term_field( 'name', $menu_item->object_id, $menu_item->object, 'raw' );
   882 					$menu_item->url = get_term_link( (int) $menu_item->object_id, $menu_item->object );
   861 				if ( is_wp_error( $original_title ) ) {
   883 					$original_title = $original_object->name;
   862 					$original_title = false;
   884 				} else {
       
   885 					$menu_item->url      = '';
       
   886 					$original_title      = '';
       
   887 					$menu_item->_invalid = true;
   863 				}
   888 				}
   864 				$menu_item->title = '' == $menu_item->post_title ? $original_title : $menu_item->post_title;
   889 
       
   890 				if ( '' === $original_title ) {
       
   891 					/* translators: %d: ID of a term. */
       
   892 					$original_title = sprintf( __( '#%d (no title)' ), $menu_item->object_id );
       
   893 				}
       
   894 
       
   895 				$menu_item->title = ( '' === $menu_item->post_title ) ? $original_title : $menu_item->post_title;
   865 
   896 
   866 			} else {
   897 			} else {
   867 				$menu_item->type_label = __( 'Custom Link' );
   898 				$menu_item->type_label = __( 'Custom Link' );
   868 				$menu_item->title      = $menu_item->post_title;
   899 				$menu_item->title      = $menu_item->post_title;
   869 				$menu_item->url        = ! isset( $menu_item->url ) ? get_post_meta( $menu_item->ID, '_menu_item_url', true ) : $menu_item->url;
   900 				$menu_item->url        = ! isset( $menu_item->url ) ? get_post_meta( $menu_item->ID, '_menu_item_url', true ) : $menu_item->url;
   902 			$object                = get_post_type_object( $menu_item->post_type );
   933 			$object                = get_post_type_object( $menu_item->post_type );
   903 			$menu_item->object     = $object->name;
   934 			$menu_item->object     = $object->name;
   904 			$menu_item->type_label = $object->labels->singular_name;
   935 			$menu_item->type_label = $object->labels->singular_name;
   905 
   936 
   906 			if ( '' === $menu_item->post_title ) {
   937 			if ( '' === $menu_item->post_title ) {
   907 				/* translators: %d: ID of a post */
   938 				/* translators: %d: ID of a post. */
   908 				$menu_item->post_title = sprintf( __( '#%d (no title)' ), $menu_item->ID );
   939 				$menu_item->post_title = sprintf( __( '#%d (no title)' ), $menu_item->ID );
   909 			}
   940 			}
   910 
   941 
   911 			$menu_item->title  = $menu_item->post_title;
   942 			$menu_item->title  = $menu_item->post_title;
   912 			$menu_item->url    = get_permalink( $menu_item->ID );
   943 			$menu_item->url    = get_permalink( $menu_item->ID );
   956  * Get the menu items associated with a particular object.
   987  * Get the menu items associated with a particular object.
   957  *
   988  *
   958  * @since 3.0.0
   989  * @since 3.0.0
   959  *
   990  *
   960  * @param int    $object_id   The ID of the original object.
   991  * @param int    $object_id   The ID of the original object.
   961  * @param string $object_type The type of object, such as "taxonomy" or "post_type."
   992  * @param string $object_type The type of object, such as 'taxonomy' or 'post_type'.
   962  * @param string $taxonomy    If $object_type is "taxonomy", $taxonomy is the name of the tax that $object_id belongs to
   993  * @param string $taxonomy    If $object_type is 'taxonomy', $taxonomy is the name of the tax
   963  * @return array The array of menu item IDs; empty array if none;
   994  *                            that $object_id belongs to.
       
   995  * @return int[] The array of menu item IDs; empty array if none;
   964  */
   996  */
   965 function wp_get_associated_nav_menu_items( $object_id = 0, $object_type = 'post_type', $taxonomy = '' ) {
   997 function wp_get_associated_nav_menu_items( $object_id = 0, $object_type = 'post_type', $taxonomy = '' ) {
   966 	$object_id     = (int) $object_id;
   998 	$object_id     = (int) $object_id;
   967 	$menu_item_ids = array();
   999 	$menu_item_ids = array();
   968 
  1000 
   978 	);
  1010 	);
   979 	foreach ( (array) $menu_items as $menu_item ) {
  1011 	foreach ( (array) $menu_items as $menu_item ) {
   980 		if ( isset( $menu_item->ID ) && is_nav_menu_item( $menu_item->ID ) ) {
  1012 		if ( isset( $menu_item->ID ) && is_nav_menu_item( $menu_item->ID ) ) {
   981 			$menu_item_type = get_post_meta( $menu_item->ID, '_menu_item_type', true );
  1013 			$menu_item_type = get_post_meta( $menu_item->ID, '_menu_item_type', true );
   982 			if (
  1014 			if (
   983 				'post_type' == $object_type &&
  1015 				'post_type' === $object_type &&
   984 				'post_type' == $menu_item_type
  1016 				'post_type' === $menu_item_type
   985 			) {
  1017 			) {
   986 				$menu_item_ids[] = (int) $menu_item->ID;
  1018 				$menu_item_ids[] = (int) $menu_item->ID;
   987 			} elseif (
  1019 			} elseif (
   988 				'taxonomy' == $object_type &&
  1020 				'taxonomy' === $object_type &&
   989 				'taxonomy' == $menu_item_type &&
  1021 				'taxonomy' === $menu_item_type &&
   990 				get_post_meta( $menu_item->ID, '_menu_item_object', true ) == $taxonomy
  1022 				get_post_meta( $menu_item->ID, '_menu_item_object', true ) == $taxonomy
   991 			) {
  1023 			) {
   992 				$menu_item_ids[] = (int) $menu_item->ID;
  1024 				$menu_item_ids[] = (int) $menu_item->ID;
   993 			}
  1025 			}
   994 		}
  1026 		}
  1039  * Automatically add newly published page objects to menus with that as an option.
  1071  * Automatically add newly published page objects to menus with that as an option.
  1040  *
  1072  *
  1041  * @since 3.0.0
  1073  * @since 3.0.0
  1042  * @access private
  1074  * @access private
  1043  *
  1075  *
  1044  * @param string $new_status The new status of the post object.
  1076  * @param string  $new_status The new status of the post object.
  1045  * @param string $old_status The old status of the post object.
  1077  * @param string  $old_status The old status of the post object.
  1046  * @param object $post       The post object being transitioned from one status to another.
  1078  * @param WP_Post $post       The post object being transitioned from one status to another.
  1047  */
  1079  */
  1048 function _wp_auto_add_pages_to_menu( $new_status, $old_status, $post ) {
  1080 function _wp_auto_add_pages_to_menu( $new_status, $old_status, $post ) {
  1049 	if ( 'publish' != $new_status || 'publish' == $old_status || 'page' != $post->post_type ) {
  1081 	if ( 'publish' !== $new_status || 'publish' === $old_status || 'page' !== $post->post_type ) {
  1050 		return;
  1082 		return;
  1051 	}
  1083 	}
  1052 	if ( ! empty( $post->post_parent ) ) {
  1084 	if ( ! empty( $post->post_parent ) ) {
  1053 		return;
  1085 		return;
  1054 	}
  1086 	}
  1219 							unset( $old_nav_menu_locations[ $location ] );
  1251 							unset( $old_nav_menu_locations[ $location ] );
  1220 
  1252 
  1221 							// Go back and check the next new menu location.
  1253 							// Go back and check the next new menu location.
  1222 							continue 3;
  1254 							continue 3;
  1223 						}
  1255 						}
  1224 					} // endforeach ( $slug_group as $slug )
  1256 					} // End foreach ( $slug_group as $slug ).
  1225 				} // endforeach ( $old_nav_menu_locations as $location => $menu_id )
  1257 				} // End foreach ( $old_nav_menu_locations as $location => $menu_id ).
  1226 			} // endforeach foreach ( $registered_nav_menus as $new_location => $name )
  1258 			} // End foreach foreach ( $registered_nav_menus as $new_location => $name ).
  1227 		} // endforeach ( $slug_group as $slug )
  1259 		} // End foreach ( $slug_group as $slug ).
  1228 	} // endforeach ( $common_slug_groups as $slug_group )
  1260 	} // End foreach ( $common_slug_groups as $slug_group ).
  1229 
  1261 
  1230 	return $new_nav_menu_locations;
  1262 	return $new_nav_menu_locations;
  1231 }
  1263 }