changeset 19 | 3d72ae0968f4 |
parent 18 | be944660c56a |
child 21 | 48c4eec2b7e6 |
18:be944660c56a | 19:3d72ae0968f4 |
---|---|
48 */ |
48 */ |
49 return apply_filters( 'wp_get_nav_menu_object', $menu_obj, $menu ); |
49 return apply_filters( 'wp_get_nav_menu_object', $menu_obj, $menu ); |
50 } |
50 } |
51 |
51 |
52 /** |
52 /** |
53 * Check if the given ID is a navigation menu. |
53 * Determines whether the given ID is a navigation menu. |
54 * |
54 * |
55 * Returns true if it is; false otherwise. |
55 * Returns true if it is; false otherwise. |
56 * |
56 * |
57 * @since 3.0.0 |
57 * @since 3.0.0 |
58 * |
58 * |
157 /** |
157 /** |
158 * Retrieves all registered navigation menu locations and the menus assigned to them. |
158 * Retrieves all registered navigation menu locations and the menus assigned to them. |
159 * |
159 * |
160 * @since 3.0.0 |
160 * @since 3.0.0 |
161 * |
161 * |
162 * @return int[] Associative array of egistered navigation menu IDs keyed by their |
162 * @return int[] Associative array of registered navigation menu IDs keyed by their |
163 * location name. If none are registered, an empty array. |
163 * location name. If none are registered, an empty array. |
164 */ |
164 */ |
165 function get_nav_menu_locations() { |
165 function get_nav_menu_locations() { |
166 $locations = get_theme_mod( 'nav_menu_locations' ); |
166 $locations = get_theme_mod( 'nav_menu_locations' ); |
167 return ( is_array( $locations ) ) ? $locations : array(); |
167 return ( is_array( $locations ) ) ? $locations : array(); |
253 // expected_slashed ($menu_name) |
253 // expected_slashed ($menu_name) |
254 return wp_update_nav_menu_object( 0, array( 'menu-name' => $menu_name ) ); |
254 return wp_update_nav_menu_object( 0, array( 'menu-name' => $menu_name ) ); |
255 } |
255 } |
256 |
256 |
257 /** |
257 /** |
258 * Delete a Navigation Menu. |
258 * Deletes a navigation menu. |
259 * |
259 * |
260 * @since 3.0.0 |
260 * @since 3.0.0 |
261 * |
261 * |
262 * @param int|string|WP_Term $menu Menu ID, slug, name, or object. |
262 * @param int|string|WP_Term $menu Menu ID, slug, name, or object. |
263 * @return bool|WP_Error True on success, false or WP_Error object on failure. |
263 * @return bool|WP_Error True on success, false or WP_Error object on failure. |
300 |
300 |
301 return $result; |
301 return $result; |
302 } |
302 } |
303 |
303 |
304 /** |
304 /** |
305 * Save the properties of a menu or create a new menu with those properties. |
305 * Saves the properties of a menu or create a new menu with those properties. |
306 * |
306 * |
307 * Note that `$menu_data` is expected to be pre-slashed. |
307 * Note that `$menu_data` is expected to be pre-slashed. |
308 * |
308 * |
309 * @since 3.0.0 |
309 * @since 3.0.0 |
310 * |
310 * |
402 do_action( 'wp_update_nav_menu', $menu_id, $menu_data ); |
402 do_action( 'wp_update_nav_menu', $menu_id, $menu_data ); |
403 return $menu_id; |
403 return $menu_id; |
404 } |
404 } |
405 |
405 |
406 /** |
406 /** |
407 * Save the properties of a menu item or create a new one. |
407 * Saves the properties of a menu item or create a new one. |
408 * |
408 * |
409 * The menu-item-title, menu-item-description, and menu-item-attr-title are expected |
409 * The menu-item-title, menu-item-description and menu-item-attr-title are expected |
410 * to be pre-slashed since they are passed directly into `wp_insert_post()`. |
410 * to be pre-slashed since they are passed directly to APIs that expect slashed data. |
411 * |
411 * |
412 * @since 3.0.0 |
412 * @since 3.0.0 |
413 * |
413 * @since 5.9.0 Added the `$fire_after_hooks` parameter. |
414 * @param int $menu_id The ID of the menu. Required. If "0", makes the menu item a draft orphan. |
414 * |
415 * @param int $menu_item_db_id The ID of the menu item. If "0", creates a new menu item. |
415 * @param int $menu_id The ID of the menu. If 0, makes the menu item a draft orphan. |
416 * @param array $menu_item_data The menu item's data. |
416 * @param int $menu_item_db_id The ID of the menu item. If 0, creates a new menu item. |
417 * @param array $menu_item_data The menu item's data. |
|
418 * @param bool $fire_after_hooks Whether to fire the after insert hooks. Default true. |
|
417 * @return int|WP_Error The menu item's database ID or WP_Error object on failure. |
419 * @return int|WP_Error The menu item's database ID or WP_Error object on failure. |
418 */ |
420 */ |
419 function wp_update_nav_menu_item( $menu_id = 0, $menu_item_db_id = 0, $menu_item_data = array() ) { |
421 function wp_update_nav_menu_item( $menu_id = 0, $menu_item_db_id = 0, $menu_item_data = array(), $fire_after_hooks = true ) { |
420 $menu_id = (int) $menu_id; |
422 $menu_id = (int) $menu_id; |
421 $menu_item_db_id = (int) $menu_item_db_id; |
423 $menu_item_db_id = (int) $menu_item_db_id; |
422 |
424 |
423 // Make sure that we don't convert non-nav_menu_item objects into nav_menu_item objects. |
425 // Make sure that we don't convert non-nav_menu_item objects into nav_menu_item objects. |
424 if ( ! empty( $menu_item_db_id ) && ! is_nav_menu_item( $menu_item_db_id ) ) { |
426 if ( ! empty( $menu_item_db_id ) && ! is_nav_menu_item( $menu_item_db_id ) ) { |
524 |
526 |
525 // New menu item. Default is draft status. |
527 // New menu item. Default is draft status. |
526 if ( ! $update ) { |
528 if ( ! $update ) { |
527 $post['ID'] = 0; |
529 $post['ID'] = 0; |
528 $post['post_status'] = 'publish' === $args['menu-item-status'] ? 'publish' : 'draft'; |
530 $post['post_status'] = 'publish' === $args['menu-item-status'] ? 'publish' : 'draft'; |
529 $menu_item_db_id = wp_insert_post( $post ); |
531 $menu_item_db_id = wp_insert_post( $post, true, $fire_after_hooks ); |
530 if ( ! $menu_item_db_id || is_wp_error( $menu_item_db_id ) ) { |
532 if ( ! $menu_item_db_id || is_wp_error( $menu_item_db_id ) ) { |
531 return $menu_item_db_id; |
533 return $menu_item_db_id; |
532 } |
534 } |
533 |
535 |
534 /** |
536 /** |
546 } |
548 } |
547 |
549 |
548 // Associate the menu item with the menu term. |
550 // Associate the menu item with the menu term. |
549 // Only set the menu term if it isn't set to avoid unnecessary wp_get_object_terms(). |
551 // Only set the menu term if it isn't set to avoid unnecessary wp_get_object_terms(). |
550 if ( $menu_id && ( ! $update || ! is_object_in_term( $menu_item_db_id, 'nav_menu', (int) $menu->term_id ) ) ) { |
552 if ( $menu_id && ( ! $update || ! is_object_in_term( $menu_item_db_id, 'nav_menu', (int) $menu->term_id ) ) ) { |
551 wp_set_object_terms( $menu_item_db_id, array( $menu->term_id ), 'nav_menu' ); |
553 $update_terms = wp_set_object_terms( $menu_item_db_id, array( $menu->term_id ), 'nav_menu' ); |
554 if ( is_wp_error( $update_terms ) ) { |
|
555 return $update_terms; |
|
556 } |
|
552 } |
557 } |
553 |
558 |
554 if ( 'custom' === $args['menu-item-type'] ) { |
559 if ( 'custom' === $args['menu-item-type'] ) { |
555 $args['menu-item-object-id'] = $menu_item_db_id; |
560 $args['menu-item-object-id'] = $menu_item_db_id; |
556 $args['menu-item-object'] = 'custom'; |
561 $args['menu-item-object'] = 'custom'; |
578 |
583 |
579 // Update existing menu item. Default is publish status. |
584 // Update existing menu item. Default is publish status. |
580 if ( $update ) { |
585 if ( $update ) { |
581 $post['ID'] = $menu_item_db_id; |
586 $post['ID'] = $menu_item_db_id; |
582 $post['post_status'] = ( 'draft' === $args['menu-item-status'] ) ? 'draft' : 'publish'; |
587 $post['post_status'] = ( 'draft' === $args['menu-item-status'] ) ? 'draft' : 'publish'; |
583 wp_update_post( $post ); |
588 |
589 $update_post = wp_update_post( $post, true ); |
|
590 if ( is_wp_error( $update_post ) ) { |
|
591 return $update_post; |
|
592 } |
|
584 } |
593 } |
585 |
594 |
586 /** |
595 /** |
587 * Fires after a navigation menu item has been updated. |
596 * Fires after a navigation menu item has been updated. |
588 * |
597 * |
630 */ |
639 */ |
631 return apply_filters( 'wp_get_nav_menus', get_terms( $args ), $args ); |
640 return apply_filters( 'wp_get_nav_menus', get_terms( $args ), $args ); |
632 } |
641 } |
633 |
642 |
634 /** |
643 /** |
635 * Return if a menu item is valid. |
644 * Determines whether a menu item is valid. |
636 * |
645 * |
637 * @link https://core.trac.wordpress.org/ticket/13958 |
646 * @link https://core.trac.wordpress.org/ticket/13958 |
638 * |
647 * |
639 * @since 3.2.0 |
648 * @since 3.2.0 |
640 * @access private |
649 * @access private |
682 return false; |
691 return false; |
683 } |
692 } |
684 |
693 |
685 static $fetched = array(); |
694 static $fetched = array(); |
686 |
695 |
687 $items = get_objects_in_term( $menu->term_id, 'nav_menu' ); |
696 if ( ! taxonomy_exists( 'nav_menu' ) ) { |
688 if ( is_wp_error( $items ) ) { |
|
689 return false; |
697 return false; |
690 } |
698 } |
691 |
699 |
692 $defaults = array( |
700 $defaults = array( |
693 'order' => 'ASC', |
701 'order' => 'ASC', |
694 'orderby' => 'menu_order', |
702 'orderby' => 'menu_order', |
695 'post_type' => 'nav_menu_item', |
703 'post_type' => 'nav_menu_item', |
696 'post_status' => 'publish', |
704 'post_status' => 'publish', |
697 'output' => ARRAY_A, |
705 'output' => ARRAY_A, |
698 'output_key' => 'menu_order', |
706 'output_key' => 'menu_order', |
699 'nopaging' => true, |
707 'nopaging' => true, |
708 'tax_query' => array( |
|
709 array( |
|
710 'taxonomy' => 'nav_menu', |
|
711 'field' => 'term_taxonomy_id', |
|
712 'terms' => $menu->term_taxonomy_id, |
|
713 ), |
|
714 ), |
|
700 ); |
715 ); |
701 $args = wp_parse_args( $args, $defaults ); |
716 $args = wp_parse_args( $args, $defaults ); |
702 $args['include'] = $items; |
717 if ( $menu->count > 0 ) { |
703 |
|
704 if ( ! empty( $items ) ) { |
|
705 $items = get_posts( $args ); |
718 $items = get_posts( $args ); |
706 } else { |
719 } else { |
707 $items = array(); |
720 $items = array(); |
708 } |
721 } |
709 |
722 |
710 // Get all posts and terms at once to prime the caches. |
723 // Prime posts and terms caches. |
711 if ( empty( $fetched[ $menu->term_id ] ) && ! wp_using_ext_object_cache() ) { |
724 if ( empty( $fetched[ $menu->term_id ] ) ) { |
712 $fetched[ $menu->term_id ] = true; |
725 $fetched[ $menu->term_id ] = true; |
713 $posts = array(); |
726 $post_ids = array(); |
714 $terms = array(); |
727 $term_ids = array(); |
715 foreach ( $items as $item ) { |
728 foreach ( $items as $item ) { |
716 $object_id = get_post_meta( $item->ID, '_menu_item_object_id', true ); |
729 $object_id = get_post_meta( $item->ID, '_menu_item_object_id', true ); |
717 $object = get_post_meta( $item->ID, '_menu_item_object', true ); |
|
718 $type = get_post_meta( $item->ID, '_menu_item_type', true ); |
730 $type = get_post_meta( $item->ID, '_menu_item_type', true ); |
719 |
731 |
720 if ( 'post_type' === $type ) { |
732 if ( 'post_type' === $type ) { |
721 $posts[ $object ][] = $object_id; |
733 $post_ids[] = (int) $object_id; |
722 } elseif ( 'taxonomy' === $type ) { |
734 } elseif ( 'taxonomy' === $type ) { |
723 $terms[ $object ][] = $object_id; |
735 $term_ids[] = (int) $object_id; |
724 } |
736 } |
725 } |
737 } |
726 |
738 |
727 if ( ! empty( $posts ) ) { |
739 if ( ! empty( $post_ids ) ) { |
728 foreach ( array_keys( $posts ) as $post_type ) { |
740 _prime_post_caches( $post_ids, false ); |
729 get_posts( |
741 } |
730 array( |
742 unset( $post_ids ); |
731 'post__in' => $posts[ $post_type ], |
743 |
732 'post_type' => $post_type, |
744 if ( ! empty( $term_ids ) ) { |
733 'nopaging' => true, |
745 _prime_term_caches( $term_ids ); |
734 'update_post_term_cache' => false, |
746 } |
735 ) |
747 unset( $term_ids ); |
736 ); |
|
737 } |
|
738 } |
|
739 unset( $posts ); |
|
740 |
|
741 if ( ! empty( $terms ) ) { |
|
742 foreach ( array_keys( $terms ) as $taxonomy ) { |
|
743 get_terms( |
|
744 array( |
|
745 'taxonomy' => $taxonomy, |
|
746 'include' => $terms[ $taxonomy ], |
|
747 'hierarchical' => false, |
|
748 ) |
|
749 ); |
|
750 } |
|
751 } |
|
752 unset( $terms ); |
|
753 } |
748 } |
754 |
749 |
755 $items = array_map( 'wp_setup_nav_menu_item', $items ); |
750 $items = array_map( 'wp_setup_nav_menu_item', $items ); |
756 |
751 |
757 if ( ! is_admin() ) { // Remove invalid items only on front end. |
752 if ( ! is_admin() ) { // Remove invalid items only on front end. |
991 */ |
986 */ |
992 return apply_filters( 'wp_setup_nav_menu_item', $menu_item ); |
987 return apply_filters( 'wp_setup_nav_menu_item', $menu_item ); |
993 } |
988 } |
994 |
989 |
995 /** |
990 /** |
996 * Get the menu items associated with a particular object. |
991 * Returns the menu items associated with a particular object. |
997 * |
992 * |
998 * @since 3.0.0 |
993 * @since 3.0.0 |
999 * |
994 * |
1000 * @param int $object_id Optional. The ID of the original object. Default 0. |
995 * @param int $object_id Optional. The ID of the original object. Default 0. |
1001 * @param string $object_type Optional. The type of object, such as 'post_type' or 'taxonomy'. |
996 * @param string $object_type Optional. The type of object, such as 'post_type' or 'taxonomy'. |
1123 wp_update_nav_menu_item( $menu_id, 0, $args ); |
1118 wp_update_nav_menu_item( $menu_id, 0, $args ); |
1124 } |
1119 } |
1125 } |
1120 } |
1126 |
1121 |
1127 /** |
1122 /** |
1128 * Delete auto-draft posts associated with the supplied changeset. |
1123 * Deletes auto-draft posts associated with the supplied changeset. |
1129 * |
1124 * |
1130 * @since 4.8.0 |
1125 * @since 4.8.0 |
1131 * @access private |
1126 * @access private |
1132 * |
1127 * |
1133 * @param int $post_id Post ID for the customize_changeset. |
1128 * @param int $post_id Post ID for the customize_changeset. |
1157 } |
1152 } |
1158 add_action( 'delete_post', '_wp_delete_customize_changeset_dependent_auto_drafts' ); |
1153 add_action( 'delete_post', '_wp_delete_customize_changeset_dependent_auto_drafts' ); |
1159 } |
1154 } |
1160 |
1155 |
1161 /** |
1156 /** |
1162 * Handle menu config after theme change. |
1157 * Handles menu config after theme change. |
1163 * |
1158 * |
1164 * @access private |
1159 * @access private |
1165 * @since 4.9.0 |
1160 * @since 4.9.0 |
1166 */ |
1161 */ |
1167 function _wp_menus_changed() { |
1162 function _wp_menus_changed() { |