wp/wp-includes/class-wp-customize-nav-menus.php
changeset 16 a86126ab1dd4
parent 9 177826044cd9
child 18 be944660c56a
equal deleted inserted replaced
15:3d4e9c994f10 16:a86126ab1dd4
    37 	/**
    37 	/**
    38 	 * Constructor.
    38 	 * Constructor.
    39 	 *
    39 	 *
    40 	 * @since 4.3.0
    40 	 * @since 4.3.0
    41 	 *
    41 	 *
    42 	 * @param object $manager An instance of the WP_Customize_Manager class.
    42 	 * @param WP_Customize_Manager $manager Customizer bootstrap instance.
    43 	 */
    43 	 */
    44 	public function __construct( $manager ) {
    44 	public function __construct( $manager ) {
    45 		$this->manager                     = $manager;
    45 		$this->manager                     = $manager;
    46 		$this->original_nav_menu_locations = get_nav_menu_locations();
    46 		$this->original_nav_menu_locations = get_nav_menu_locations();
    47 
    47 
    74 	 * Adds a nonce for customizing menus.
    74 	 * Adds a nonce for customizing menus.
    75 	 *
    75 	 *
    76 	 * @since 4.5.0
    76 	 * @since 4.5.0
    77 	 *
    77 	 *
    78 	 * @param string[] $nonces Array of nonces.
    78 	 * @param string[] $nonces Array of nonces.
    79 	 * @return string[] $nonces Modified array of nonces.
    79 	 * @return string[] Modified array of nonces.
    80 	 */
    80 	 */
    81 	public function filter_nonces( $nonces ) {
    81 	public function filter_nonces( $nonces ) {
    82 		$nonces['customize-menus'] = wp_create_nonce( 'customize-menus' );
    82 		$nonces['customize-menus'] = wp_create_nonce( 'customize-menus' );
    83 		return $nonces;
    83 		return $nonces;
    84 	}
    84 	}
   133 	 *
   133 	 *
   134 	 * @param string $type   Optional. Accepts any custom object type and has built-in support for
   134 	 * @param string $type   Optional. Accepts any custom object type and has built-in support for
   135 	 *                         'post_type' and 'taxonomy'. Default is 'post_type'.
   135 	 *                         'post_type' and 'taxonomy'. Default is 'post_type'.
   136 	 * @param string $object Optional. Accepts any registered taxonomy or post type name. Default is 'page'.
   136 	 * @param string $object Optional. Accepts any registered taxonomy or post type name. Default is 'page'.
   137 	 * @param int    $page   Optional. The page number used to generate the query offset. Default is '0'.
   137 	 * @param int    $page   Optional. The page number used to generate the query offset. Default is '0'.
   138 	 * @return WP_Error|array Returns either a WP_Error object or an array of menu items.
   138 	 * @return array|WP_Error An array of menu items on success, a WP_Error object on failure.
   139 	 */
   139 	 */
   140 	public function load_available_items_query( $type = 'post_type', $object = 'page', $page = 0 ) {
   140 	public function load_available_items_query( $type = 'post_type', $object = 'page', $page = 0 ) {
   141 		$items = array();
   141 		$items = array();
   142 
   142 
   143 		if ( 'post_type' === $type ) {
   143 		if ( 'post_type' === $type ) {
   144 			$post_type = get_post_type_object( $object );
   144 			$post_type = get_post_type_object( $object );
   145 			if ( ! $post_type ) {
   145 			if ( ! $post_type ) {
   146 				return new WP_Error( 'nav_menus_invalid_post_type' );
   146 				return new WP_Error( 'nav_menus_invalid_post_type' );
   147 			}
   147 			}
   148 
   148 
       
   149 			/*
       
   150 			 * If we're dealing with pages, let's prioritize the Front Page,
       
   151 			 * Posts Page and Privacy Policy Page at the top of the list.
       
   152 			 */
       
   153 			$important_pages   = array();
       
   154 			$suppress_page_ids = array();
   149 			if ( 0 === $page && 'page' === $object ) {
   155 			if ( 0 === $page && 'page' === $object ) {
   150 				// Add "Home" link. Treat as a page, but switch to custom on add.
   156 				// Insert Front Page or custom "Home" link.
   151 				$items[] = array(
   157 				$front_page = 'page' === get_option( 'show_on_front' ) ? (int) get_option( 'page_on_front' ) : 0;
   152 					'id'         => 'home',
   158 				if ( ! empty( $front_page ) ) {
   153 					'title'      => _x( 'Home', 'nav menu home label' ),
   159 					$front_page_obj      = get_post( $front_page );
   154 					'type'       => 'custom',
   160 					$important_pages[]   = $front_page_obj;
   155 					'type_label' => __( 'Custom Link' ),
   161 					$suppress_page_ids[] = $front_page_obj->ID;
   156 					'object'     => '',
   162 				} else {
   157 					'url'        => home_url(),
   163 					// Add "Home" link. Treat as a page, but switch to custom on add.
   158 				);
   164 					$items[] = array(
       
   165 						'id'         => 'home',
       
   166 						'title'      => _x( 'Home', 'nav menu home label' ),
       
   167 						'type'       => 'custom',
       
   168 						'type_label' => __( 'Custom Link' ),
       
   169 						'object'     => '',
       
   170 						'url'        => home_url(),
       
   171 					);
       
   172 				}
       
   173 
       
   174 				// Insert Posts Page.
       
   175 				$posts_page = 'page' === get_option( 'show_on_front' ) ? (int) get_option( 'page_for_posts' ) : 0;
       
   176 				if ( ! empty( $posts_page ) ) {
       
   177 					$posts_page_obj      = get_post( $posts_page );
       
   178 					$important_pages[]   = $posts_page_obj;
       
   179 					$suppress_page_ids[] = $posts_page_obj->ID;
       
   180 				}
       
   181 
       
   182 				// Insert Privacy Policy Page.
       
   183 				$privacy_policy_page_id = (int) get_option( 'wp_page_for_privacy_policy' );
       
   184 				if ( ! empty( $privacy_policy_page_id ) ) {
       
   185 					$privacy_policy_page = get_post( $privacy_policy_page_id );
       
   186 					if ( $privacy_policy_page instanceof WP_Post && 'publish' === $privacy_policy_page->post_status ) {
       
   187 						$important_pages[]   = $privacy_policy_page;
       
   188 						$suppress_page_ids[] = $privacy_policy_page->ID;
       
   189 					}
       
   190 				}
   159 			} elseif ( 'post' !== $object && 0 === $page && $post_type->has_archive ) {
   191 			} elseif ( 'post' !== $object && 0 === $page && $post_type->has_archive ) {
   160 				// Add a post type archive link.
   192 				// Add a post type archive link.
   161 				$items[] = array(
   193 				$items[] = array(
   162 					'id'         => $object . '-archive',
   194 					'id'         => $object . '-archive',
   163 					'title'      => $post_type->labels->archives,
   195 					'title'      => $post_type->labels->archives,
   177 						$posts[] = $auto_draft_post;
   209 						$posts[] = $auto_draft_post;
   178 					}
   210 					}
   179 				}
   211 				}
   180 			}
   212 			}
   181 
   213 
       
   214 			$args = array(
       
   215 				'numberposts' => 10,
       
   216 				'offset'      => 10 * $page,
       
   217 				'orderby'     => 'date',
       
   218 				'order'       => 'DESC',
       
   219 				'post_type'   => $object,
       
   220 			);
       
   221 
       
   222 			// Add suppression array to arguments for get_posts.
       
   223 			if ( ! empty( $suppress_page_ids ) ) {
       
   224 				$args['post__not_in'] = $suppress_page_ids;
       
   225 			}
       
   226 
   182 			$posts = array_merge(
   227 			$posts = array_merge(
   183 				$posts,
   228 				$posts,
   184 				get_posts(
   229 				$important_pages,
   185 					array(
   230 				get_posts( $args )
   186 						'numberposts' => 10,
       
   187 						'offset'      => 10 * $page,
       
   188 						'orderby'     => 'date',
       
   189 						'order'       => 'DESC',
       
   190 						'post_type'   => $object,
       
   191 					)
       
   192 				)
       
   193 			);
   231 			);
   194 
   232 
   195 			foreach ( $posts as $post ) {
   233 			foreach ( $posts as $post ) {
   196 				$post_title = $post->post_title;
   234 				$post_title = $post->post_title;
   197 				if ( '' === $post_title ) {
   235 				if ( '' === $post_title ) {
   198 					/* translators: %d: ID of a post */
   236 					/* translators: %d: ID of a post. */
   199 					$post_title = sprintf( __( '#%d (no title)' ), $post->ID );
   237 					$post_title = sprintf( __( '#%d (no title)' ), $post->ID );
   200 				}
   238 				}
       
   239 
       
   240 				$post_type_label = get_post_type_object( $post->post_type )->labels->singular_name;
       
   241 				$post_states     = get_post_states( $post );
       
   242 				if ( ! empty( $post_states ) ) {
       
   243 					$post_type_label = implode( ',', $post_states );
       
   244 				}
       
   245 
   201 				$items[] = array(
   246 				$items[] = array(
   202 					'id'         => "post-{$post->ID}",
   247 					'id'         => "post-{$post->ID}",
   203 					'title'      => html_entity_decode( $post_title, ENT_QUOTES, get_bloginfo( 'charset' ) ),
   248 					'title'      => html_entity_decode( $post_title, ENT_QUOTES, get_bloginfo( 'charset' ) ),
   204 					'type'       => 'post_type',
   249 					'type'       => 'post_type',
   205 					'type_label' => get_post_type_object( $post->post_type )->labels->singular_name,
   250 					'type_label' => $post_type_label,
   206 					'object'     => $post->post_type,
   251 					'object'     => $post->post_type,
   207 					'object_id'  => intval( $post->ID ),
   252 					'object_id'  => intval( $post->ID ),
   208 					'url'        => get_permalink( intval( $post->ID ) ),
   253 					'url'        => get_permalink( intval( $post->ID ) ),
   209 				);
   254 				);
   210 			}
   255 			}
   211 		} elseif ( 'taxonomy' === $type ) {
   256 		} elseif ( 'taxonomy' === $type ) {
   212 			$terms = get_terms(
   257 			$terms = get_terms(
   213 				$object,
       
   214 				array(
   258 				array(
       
   259 					'taxonomy'     => $object,
   215 					'child_of'     => 0,
   260 					'child_of'     => 0,
   216 					'exclude'      => '',
   261 					'exclude'      => '',
   217 					'hide_empty'   => false,
   262 					'hide_empty'   => false,
   218 					'hierarchical' => 1,
   263 					'hierarchical' => 1,
   219 					'include'      => '',
   264 					'include'      => '',
   222 					'order'        => 'DESC',
   267 					'order'        => 'DESC',
   223 					'orderby'      => 'count',
   268 					'orderby'      => 'count',
   224 					'pad_counts'   => false,
   269 					'pad_counts'   => false,
   225 				)
   270 				)
   226 			);
   271 			);
       
   272 
   227 			if ( is_wp_error( $terms ) ) {
   273 			if ( is_wp_error( $terms ) ) {
   228 				return $terms;
   274 				return $terms;
   229 			}
   275 			}
   230 
   276 
   231 			foreach ( $terms as $term ) {
   277 			foreach ( $terms as $term ) {
   346 
   392 
   347 		// Create items for posts.
   393 		// Create items for posts.
   348 		foreach ( $posts as $post ) {
   394 		foreach ( $posts as $post ) {
   349 			$post_title = $post->post_title;
   395 			$post_title = $post->post_title;
   350 			if ( '' === $post_title ) {
   396 			if ( '' === $post_title ) {
   351 				/* translators: %d: ID of a post */
   397 				/* translators: %d: ID of a post. */
   352 				$post_title = sprintf( __( '#%d (no title)' ), $post->ID );
   398 				$post_title = sprintf( __( '#%d (no title)' ), $post->ID );
   353 			}
   399 			}
       
   400 
       
   401 			$post_type_label = $post_type_objects[ $post->post_type ]->labels->singular_name;
       
   402 			$post_states     = get_post_states( $post );
       
   403 			if ( ! empty( $post_states ) ) {
       
   404 				$post_type_label = implode( ',', $post_states );
       
   405 			}
       
   406 
   354 			$items[] = array(
   407 			$items[] = array(
   355 				'id'         => 'post-' . $post->ID,
   408 				'id'         => 'post-' . $post->ID,
   356 				'title'      => html_entity_decode( $post_title, ENT_QUOTES, get_bloginfo( 'charset' ) ),
   409 				'title'      => html_entity_decode( $post_title, ENT_QUOTES, get_bloginfo( 'charset' ) ),
   357 				'type'       => 'post_type',
   410 				'type'       => 'post_type',
   358 				'type_label' => $post_type_objects[ $post->post_type ]->labels->singular_name,
   411 				'type_label' => $post_type_label,
   359 				'object'     => $post->post_type,
   412 				'object'     => $post->post_type,
   360 				'object_id'  => intval( $post->ID ),
   413 				'object_id'  => intval( $post->ID ),
   361 				'url'        => get_permalink( intval( $post->ID ) ),
   414 				'url'        => get_permalink( intval( $post->ID ) ),
   362 			);
   415 			);
   363 		}
   416 		}
   364 
   417 
   365 		// Query taxonomy terms.
   418 		// Query taxonomy terms.
   366 		$taxonomies = get_taxonomies( array( 'show_in_nav_menus' => true ), 'names' );
   419 		$taxonomies = get_taxonomies( array( 'show_in_nav_menus' => true ), 'names' );
   367 		$terms      = get_terms(
   420 		$terms      = get_terms(
   368 			$taxonomies,
       
   369 			array(
   421 			array(
       
   422 				'taxonomies' => $taxonomies,
   370 				'name__like' => $args['s'],
   423 				'name__like' => $args['s'],
   371 				'number'     => 20,
   424 				'number'     => 20,
       
   425 				'hide_empty' => false,
   372 				'offset'     => 20 * ( $args['pagenum'] - 1 ),
   426 				'offset'     => 20 * ( $args['pagenum'] - 1 ),
   373 			)
   427 			)
   374 		);
   428 		);
   375 
   429 
   376 		// Check if any taxonomies were found.
   430 		// Check if any taxonomies were found.
   388 			}
   442 			}
   389 		}
   443 		}
   390 
   444 
   391 		// Add "Home" link if search term matches. Treat as a page, but switch to custom on add.
   445 		// Add "Home" link if search term matches. Treat as a page, but switch to custom on add.
   392 		if ( isset( $args['s'] ) ) {
   446 		if ( isset( $args['s'] ) ) {
   393 			$title   = _x( 'Home', 'nav menu home label' );
   447 			// Only insert custom "Home" link if there's no Front Page
   394 			$matches = function_exists( 'mb_stripos' ) ? false !== mb_stripos( $title, $args['s'] ) : false !== stripos( $title, $args['s'] );
   448 			$front_page = 'page' === get_option( 'show_on_front' ) ? (int) get_option( 'page_on_front' ) : 0;
   395 			if ( $matches ) {
   449 			if ( empty( $front_page ) ) {
   396 				$items[] = array(
   450 				$title   = _x( 'Home', 'nav menu home label' );
   397 					'id'         => 'home',
   451 				$matches = function_exists( 'mb_stripos' ) ? false !== mb_stripos( $title, $args['s'] ) : false !== stripos( $title, $args['s'] );
   398 					'title'      => $title,
   452 				if ( $matches ) {
   399 					'type'       => 'custom',
   453 					$items[] = array(
   400 					'type_label' => __( 'Custom Link' ),
   454 						'id'         => 'home',
   401 					'object'     => '',
   455 						'title'      => $title,
   402 					'url'        => home_url(),
   456 						'type'       => 'custom',
   403 				);
   457 						'type_label' => __( 'Custom Link' ),
       
   458 						'object'     => '',
       
   459 						'url'        => home_url(),
       
   460 					);
       
   461 				}
   404 			}
   462 			}
   405 		}
   463 		}
   406 
   464 
   407 		/**
   465 		/**
   408 		 * Filters the available menu items during a search request.
   466 		 * Filters the available menu items during a search request.
   431 
   489 
   432 		$num_locations = count( get_registered_nav_menus() );
   490 		$num_locations = count( get_registered_nav_menus() );
   433 		if ( 1 === $num_locations ) {
   491 		if ( 1 === $num_locations ) {
   434 			$locations_description = __( 'Your theme can display menus in one location.' );
   492 			$locations_description = __( 'Your theme can display menus in one location.' );
   435 		} else {
   493 		} else {
   436 			/* translators: %s: number of menu locations */
   494 			/* translators: %s: Number of menu locations. */
   437 			$locations_description = sprintf( _n( 'Your theme can display menus in %s location.', 'Your theme can display menus in %s locations.', $num_locations ), number_format_i18n( $num_locations ) );
   495 			$locations_description = sprintf( _n( 'Your theme can display menus in %s location.', 'Your theme can display menus in %s locations.', $num_locations ), number_format_i18n( $num_locations ) );
   438 		}
   496 		}
   439 
   497 
   440 		// Pass data to JS.
   498 		// Pass data to JS.
   441 		$settings = array(
   499 		$settings = array(
   444 			'l10n'                     => array(
   502 			'l10n'                     => array(
   445 				'untitled'               => _x( '(no label)', 'missing menu item navigation label' ),
   503 				'untitled'               => _x( '(no label)', 'missing menu item navigation label' ),
   446 				'unnamed'                => _x( '(unnamed)', 'Missing menu name.' ),
   504 				'unnamed'                => _x( '(unnamed)', 'Missing menu name.' ),
   447 				'custom_label'           => __( 'Custom Link' ),
   505 				'custom_label'           => __( 'Custom Link' ),
   448 				'page_label'             => get_post_type_object( 'page' )->labels->singular_name,
   506 				'page_label'             => get_post_type_object( 'page' )->labels->singular_name,
   449 				/* translators: %s:      menu location */
   507 				/* translators: %s: Menu location. */
   450 				'menuLocation'           => _x( '(Currently set to: %s)', 'menu' ),
   508 				'menuLocation'           => _x( '(Currently set to: %s)', 'menu' ),
   451 				'locationsTitle'         => 1 === $num_locations ? __( 'Menu Location' ) : __( 'Menu Locations' ),
   509 				'locationsTitle'         => 1 === $num_locations ? __( 'Menu Location' ) : __( 'Menu Locations' ),
   452 				'locationsDescription'   => $locations_description,
   510 				'locationsDescription'   => $locations_description,
   453 				'menuNameLabel'          => __( 'Menu Name' ),
   511 				'menuNameLabel'          => __( 'Menu Name' ),
   454 				'newMenuNameDescription' => __( 'If your theme has multiple menus, giving them clear names will help you manage them.' ),
   512 				'newMenuNameDescription' => __( 'If your theme has multiple menus, giving them clear names will help you manage them.' ),
   458 				'menuDeleted'            => __( 'Menu deleted' ),
   516 				'menuDeleted'            => __( 'Menu deleted' ),
   459 				'movedUp'                => __( 'Menu item moved up' ),
   517 				'movedUp'                => __( 'Menu item moved up' ),
   460 				'movedDown'              => __( 'Menu item moved down' ),
   518 				'movedDown'              => __( 'Menu item moved down' ),
   461 				'movedLeft'              => __( 'Menu item moved out of submenu' ),
   519 				'movedLeft'              => __( 'Menu item moved out of submenu' ),
   462 				'movedRight'             => __( 'Menu item is now a sub-item' ),
   520 				'movedRight'             => __( 'Menu item is now a sub-item' ),
   463 				/* translators: ▸ is the unicode right-pointing triangle, and %s is the section title in the Customizer */
   521 				/* translators: ▸ is the unicode right-pointing triangle. %s: Section title in the Customizer. */
   464 				'customizingMenus'       => sprintf( __( 'Customizing ▸ %s' ), esc_html( $this->manager->get_panel( 'nav_menus' )->title ) ),
   522 				'customizingMenus'       => sprintf( __( 'Customizing ▸ %s' ), esc_html( $this->manager->get_panel( 'nav_menus' )->title ) ),
   465 				/* translators: %s: title of menu item which is invalid */
   523 				/* translators: %s: Title of an invalid menu item. */
   466 				'invalidTitleTpl'        => __( '%s (Invalid)' ),
   524 				'invalidTitleTpl'        => __( '%s (Invalid)' ),
   467 				/* translators: %s: title of menu item in draft status */
   525 				/* translators: %s: Title of a menu item in draft status. */
   468 				'pendingTitleTpl'        => __( '%s (Pending)' ),
   526 				'pendingTitleTpl'        => __( '%s (Pending)' ),
       
   527 				/* translators: %d: Number of menu items found. */
   469 				'itemsFound'             => __( 'Number of items found: %d' ),
   528 				'itemsFound'             => __( 'Number of items found: %d' ),
       
   529 				/* translators: %d: Number of additional menu items found. */
   470 				'itemsFoundMore'         => __( 'Additional items found: %d' ),
   530 				'itemsFoundMore'         => __( 'Additional items found: %d' ),
   471 				'itemsLoadingMore'       => __( 'Loading more results... please wait.' ),
   531 				'itemsLoadingMore'       => __( 'Loading more results... please wait.' ),
   472 				'reorderModeOn'          => __( 'Reorder mode enabled' ),
   532 				'reorderModeOn'          => __( 'Reorder mode enabled' ),
   473 				'reorderModeOff'         => __( 'Reorder mode closed' ),
   533 				'reorderModeOff'         => __( 'Reorder mode closed' ),
   474 				'reorderLabelOn'         => esc_attr__( 'Reorder menu items' ),
   534 				'reorderLabelOn'         => esc_attr__( 'Reorder menu items' ),
   490 		$nav_menus_l10n = array(
   550 		$nav_menus_l10n = array(
   491 			'oneThemeLocationNoMenus' => null,
   551 			'oneThemeLocationNoMenus' => null,
   492 			'moveUp'                  => __( 'Move up one' ),
   552 			'moveUp'                  => __( 'Move up one' ),
   493 			'moveDown'                => __( 'Move down one' ),
   553 			'moveDown'                => __( 'Move down one' ),
   494 			'moveToTop'               => __( 'Move to the top' ),
   554 			'moveToTop'               => __( 'Move to the top' ),
   495 			/* translators: %s: previous item name */
   555 			/* translators: %s: Previous item name. */
   496 			'moveUnder'               => __( 'Move under %s' ),
   556 			'moveUnder'               => __( 'Move under %s' ),
   497 			/* translators: %s: previous item name */
   557 			/* translators: %s: Previous item name. */
   498 			'moveOutFrom'             => __( 'Move out from under %s' ),
   558 			'moveOutFrom'             => __( 'Move out from under %s' ),
   499 			/* translators: %s: previous item name */
   559 			/* translators: %s: Previous item name. */
   500 			'under'                   => __( 'Under %s' ),
   560 			'under'                   => __( 'Under %s' ),
   501 			/* translators: %s: previous item name */
   561 			/* translators: %s: Previous item name. */
   502 			'outFrom'                 => __( 'Out from under %s' ),
   562 			'outFrom'                 => __( 'Out from under %s' ),
   503 			/* translators: 1: item name, 2: item position, 3: total number of items */
   563 			/* translators: 1: Item name, 2: Item position, 3: Total number of items. */
   504 			'menuFocus'               => __( '%1$s. Menu item %2$d of %3$d.' ),
   564 			'menuFocus'               => __( '%1$s. Menu item %2$d of %3$d.' ),
   505 			/* translators: 1: item name, 2: item position, 3: parent item name */
   565 			/* translators: 1: Item name, 2: Item position, 3: Parent item name. */
   506 			'subMenuFocus'            => __( '%1$s. Sub item number %2$d under %3$s.' ),
   566 			'subMenuFocus'            => __( '%1$s. Sub item number %2$d under %3$s.' ),
   507 		);
   567 		);
   508 		wp_localize_script( 'nav-menu', 'menus', $nav_menus_l10n );
   568 		wp_localize_script( 'nav-menu', 'menus', $nav_menus_l10n );
   509 	}
   569 	}
   510 
   570 
   588 		$this->manager->register_control_type( 'WP_Customize_Nav_Menu_Item_Control' );
   648 		$this->manager->register_control_type( 'WP_Customize_Nav_Menu_Item_Control' );
   589 
   649 
   590 		// Create a panel for Menus.
   650 		// Create a panel for Menus.
   591 		$description = '<p>' . __( 'This panel is used for managing navigation menus for content you have already published on your site. You can create menus and add items for existing content such as pages, posts, categories, tags, formats, or custom links.' ) . '</p>';
   651 		$description = '<p>' . __( 'This panel is used for managing navigation menus for content you have already published on your site. You can create menus and add items for existing content such as pages, posts, categories, tags, formats, or custom links.' ) . '</p>';
   592 		if ( current_theme_supports( 'widgets' ) ) {
   652 		if ( current_theme_supports( 'widgets' ) ) {
   593 			/* translators: URL to the widgets panel of the customizer */
   653 			$description .= '<p>' . sprintf(
   594 			$description .= '<p>' . sprintf( __( 'Menus can be displayed in locations defined by your theme or in <a href="%s">widget areas</a> by adding a &#8220;Navigation Menu&#8221; widget.' ), "javascript:wp.customize.panel( 'widgets' ).focus();" ) . '</p>';
   654 				/* translators: %s: URL to the Widgets panel of the Customizer. */
       
   655 				__( 'Menus can be displayed in locations defined by your theme or in <a href="%s">widget areas</a> by adding a &#8220;Navigation Menu&#8221; widget.' ),
       
   656 				"javascript:wp.customize.panel( 'widgets' ).focus();"
       
   657 			) . '</p>';
   595 		} else {
   658 		} else {
   596 			$description .= '<p>' . __( 'Menus can be displayed in locations defined by your theme.' ) . '</p>';
   659 			$description .= '<p>' . __( 'Menus can be displayed in locations defined by your theme.' ) . '</p>';
   597 		}
   660 		}
   598 
   661 
   599 		/*
   662 		/*
   617 		$locations     = get_registered_nav_menus();
   680 		$locations     = get_registered_nav_menus();
   618 		$num_locations = count( $locations );
   681 		$num_locations = count( $locations );
   619 		if ( 1 == $num_locations ) {
   682 		if ( 1 == $num_locations ) {
   620 			$description = '<p>' . __( 'Your theme can display menus in one location. Select which menu you would like to use.' ) . '</p>';
   683 			$description = '<p>' . __( 'Your theme can display menus in one location. Select which menu you would like to use.' ) . '</p>';
   621 		} else {
   684 		} else {
   622 			/* translators: %s: number of menu locations */
   685 			/* translators: %s: Number of menu locations. */
   623 			$description = '<p>' . sprintf( _n( 'Your theme can display menus in %s location. Select which menu you would like to use.', 'Your theme can display menus in %s locations. Select which menu appears in each location.', $num_locations ), number_format_i18n( $num_locations ) ) . '</p>';
   686 			$description = '<p>' . sprintf( _n( 'Your theme can display menus in %s location. Select which menu you would like to use.', 'Your theme can display menus in %s locations. Select which menu appears in each location.', $num_locations ), number_format_i18n( $num_locations ) ) . '</p>';
   624 		}
   687 		}
   625 
   688 
   626 		if ( current_theme_supports( 'widgets' ) ) {
   689 		if ( current_theme_supports( 'widgets' ) ) {
   627 			/* translators: URL to the widgets panel of the customizer */
   690 			/* translators: URL to the Widgets panel of the Customizer. */
   628 			$description .= '<p>' . sprintf( __( 'If your theme has widget areas, you can also add menus there. Visit the <a href="%s">Widgets panel</a> and add a &#8220;Navigation Menu widget&#8221; to display a menu in a sidebar or footer.' ), "javascript:wp.customize.panel( 'widgets' ).focus();" ) . '</p>';
   691 			$description .= '<p>' . sprintf( __( 'If your theme has widget areas, you can also add menus there. Visit the <a href="%s">Widgets panel</a> and add a &#8220;Navigation Menu widget&#8221; to display a menu in a sidebar or footer.' ), "javascript:wp.customize.panel( 'widgets' ).focus();" ) . '</p>';
   629 		}
   692 		}
   630 
   693 
   631 		$this->manager->add_section(
   694 		$this->manager->add_section(
   632 			'menu_locations',
   695 			'menu_locations',
   694 					)
   757 					)
   695 				)
   758 				)
   696 			);
   759 			);
   697 		}
   760 		}
   698 
   761 
       
   762 		// Used to denote post states for special pages.
       
   763 		if ( ! function_exists( 'get_post_states' ) ) {
       
   764 			require_once ABSPATH . 'wp-admin/includes/template.php';
       
   765 		}
       
   766 
   699 		// Register each menu as a Customizer section, and add each menu item to each menu.
   767 		// Register each menu as a Customizer section, and add each menu item to each menu.
   700 		foreach ( $menus as $menu ) {
   768 		foreach ( $menus as $menu ) {
   701 			$menu_id = $menu->term_id;
   769 			$menu_id = $menu->term_id;
   702 
   770 
   703 			// Create a section for each menu.
   771 			// Create a section for each menu.
   876 	public function insert_auto_draft_post( $postarr ) {
   944 	public function insert_auto_draft_post( $postarr ) {
   877 		if ( ! isset( $postarr['post_type'] ) ) {
   945 		if ( ! isset( $postarr['post_type'] ) ) {
   878 			return new WP_Error( 'unknown_post_type', __( 'Invalid post type.' ) );
   946 			return new WP_Error( 'unknown_post_type', __( 'Invalid post type.' ) );
   879 		}
   947 		}
   880 		if ( empty( $postarr['post_title'] ) ) {
   948 		if ( empty( $postarr['post_title'] ) ) {
   881 			return new WP_Error( 'empty_title', __( 'Empty title' ) );
   949 			return new WP_Error( 'empty_title', __( 'Empty title.' ) );
   882 		}
   950 		}
   883 		if ( ! empty( $postarr['post_status'] ) ) {
   951 		if ( ! empty( $postarr['post_status'] ) ) {
   884 			return new WP_Error( 'status_forbidden', __( 'Status is forbidden' ) );
   952 			return new WP_Error( 'status_forbidden', __( 'Status is forbidden.' ) );
   885 		}
   953 		}
   886 
   954 
   887 		/*
   955 		/*
   888 		 * If the changeset is a draft, this will change to draft the next time the changeset
   956 		 * If the changeset is a draft, this will change to draft the next time the changeset
   889 		 * is updated; otherwise, auto-draft will persist in autosave revisions, until save.
   957 		 * is updated; otherwise, auto-draft will persist in autosave revisions, until save.
   969 			} else {
  1037 			} else {
   970 				$singular_name = __( 'Post' );
  1038 				$singular_name = __( 'Post' );
   971 			}
  1039 			}
   972 
  1040 
   973 			$data = array(
  1041 			$data = array(
   974 				/* translators: 1: post type name, 2: error message */
  1042 				/* translators: 1: Post type name, 2: Error message. */
   975 				'message' => sprintf( __( '%1$s could not be created: %2$s' ), $singular_name, $error->get_error_message() ),
  1043 				'message' => sprintf( __( '%1$s could not be created: %2$s' ), $singular_name, $error->get_error_message() ),
   976 			);
  1044 			);
   977 			wp_send_json_error( $data );
  1045 			wp_send_json_error( $data );
   978 		} else {
  1046 		} else {
   979 			$post = $r;
  1047 			$post = $r;
  1003 							<span class="menu-item-title<# if ( ! data.title ) { #> no-title<# } #>">{{ data.title || wp.customize.Menus.data.l10n.untitled }}</span>
  1071 							<span class="menu-item-title<# if ( ! data.title ) { #> no-title<# } #>">{{ data.title || wp.customize.Menus.data.l10n.untitled }}</span>
  1004 						</span>
  1072 						</span>
  1005 						<button type="button" class="button-link item-add">
  1073 						<button type="button" class="button-link item-add">
  1006 							<span class="screen-reader-text">
  1074 							<span class="screen-reader-text">
  1007 							<?php
  1075 							<?php
  1008 								/* translators: 1: title of a menu item, 2: type of a menu item */
  1076 								/* translators: 1: Title of a menu item, 2: Type of a menu item. */
  1009 								printf( __( 'Add to menu: %1$s (%2$s)' ), '{{ data.title || wp.customize.Menus.data.l10n.untitled }}', '{{ data.type_label }}' );
  1077 								printf( __( 'Add to menu: %1$s (%2$s)' ), '{{ data.title || wp.customize.Menus.data.l10n.untitled }}', '{{ data.type_label }}' );
  1010 							?>
  1078 							?>
  1011 							</span>
  1079 							</span>
  1012 						</button>
  1080 						</button>
  1013 					</div>
  1081 					</div>
  1062 		</script>
  1130 		</script>
  1063 		<?php
  1131 		<?php
  1064 	}
  1132 	}
  1065 
  1133 
  1066 	/**
  1134 	/**
  1067 	 * Print the html template used to render the add-menu-item frame.
  1135 	 * Print the HTML template used to render the add-menu-item frame.
  1068 	 *
  1136 	 *
  1069 	 * @since 4.3.0
  1137 	 * @since 4.3.0
  1070 	 */
  1138 	 */
  1071 	public function available_items_template() {
  1139 	public function available_items_template() {
  1072 		?>
  1140 		?>
  1076 					<span class="screen-reader-text"><?php _e( 'Back' ); ?></span>
  1144 					<span class="screen-reader-text"><?php _e( 'Back' ); ?></span>
  1077 				</button>
  1145 				</button>
  1078 				<h3>
  1146 				<h3>
  1079 					<span class="customize-action">
  1147 					<span class="customize-action">
  1080 						<?php
  1148 						<?php
  1081 							/* translators: &#9656; is the unicode right-pointing triangle, and %s is the section title in the Customizer */
  1149 							/* translators: &#9656; is the unicode right-pointing triangle. %s: Section title in the Customizer. */
  1082 							printf( __( 'Customizing &#9656; %s' ), esc_html( $this->manager->get_panel( 'nav_menus' )->title ) );
  1150 							printf( __( 'Customizing &#9656; %s' ), esc_html( $this->manager->get_panel( 'nav_menus' )->title ) );
  1083 						?>
  1151 						?>
  1084 					</span>
  1152 					</span>
  1085 					<?php _e( 'Add Menu Items' ); ?>
  1153 					<?php _e( 'Add Menu Items' ); ?>
  1086 				</h3>
  1154 				</h3>
  1140 				<span class="spinner"></span>
  1208 				<span class="spinner"></span>
  1141 				<span class="no-items"><?php _e( 'No items' ); ?></span>
  1209 				<span class="no-items"><?php _e( 'No items' ); ?></span>
  1142 				<button type="button" class="button-link" aria-expanded="false">
  1210 				<button type="button" class="button-link" aria-expanded="false">
  1143 					<span class="screen-reader-text">
  1211 					<span class="screen-reader-text">
  1144 					<?php
  1212 					<?php
  1145 						/* translators: %s: Title of a section with menu items */
  1213 						/* translators: %s: Title of a section with menu items. */
  1146 						printf( __( 'Toggle section: %s' ), esc_html( $available_item_type['title'] ) );
  1214 						printf( __( 'Toggle section: %s' ), esc_html( $available_item_type['title'] ) );
  1147 					?>
  1215 					?>
  1148 						</span>
  1216 						</span>
  1149 					<span class="toggle-indicator" aria-hidden="true"></span>
  1217 					<span class="toggle-indicator" aria-hidden="true"></span>
  1150 				</button>
  1218 				</button>
  1185 			</h4>
  1253 			</h4>
  1186 			<div class="accordion-section-content customlinkdiv">
  1254 			<div class="accordion-section-content customlinkdiv">
  1187 				<input type="hidden" value="custom" id="custom-menu-item-type" name="menu-item[-1][menu-item-type]" />
  1255 				<input type="hidden" value="custom" id="custom-menu-item-type" name="menu-item[-1][menu-item-type]" />
  1188 				<p id="menu-item-url-wrap" class="wp-clearfix">
  1256 				<p id="menu-item-url-wrap" class="wp-clearfix">
  1189 					<label class="howto" for="custom-menu-item-url"><?php _e( 'URL' ); ?></label>
  1257 					<label class="howto" for="custom-menu-item-url"><?php _e( 'URL' ); ?></label>
  1190 					<input id="custom-menu-item-url" name="menu-item[-1][menu-item-url]" type="text" class="code menu-item-textbox" value="http://">
  1258 					<input id="custom-menu-item-url" name="menu-item[-1][menu-item-url]" type="text" class="code menu-item-textbox" placeholder="https://">
  1191 				</p>
  1259 				</p>
  1192 				<p id="menu-item-name-wrap" class="wp-clearfix">
  1260 				<p id="menu-item-name-wrap" class="wp-clearfix">
  1193 					<label class="howto" for="custom-menu-item-name"><?php _e( 'Link Text' ); ?></label>
  1261 					<label class="howto" for="custom-menu-item-name"><?php _e( 'Link Text' ); ?></label>
  1194 					<input id="custom-menu-item-name" name="menu-item[-1][menu-item-title]" type="text" class="regular-text menu-item-textbox">
  1262 					<input id="custom-menu-item-name" name="menu-item[-1][menu-item-title]" type="text" class="regular-text menu-item-textbox">
  1195 				</p>
  1263 				</p>
  1275 	 * Sanitize post IDs for posts created for nav menu items to be published.
  1343 	 * Sanitize post IDs for posts created for nav menu items to be published.
  1276 	 *
  1344 	 *
  1277 	 * @since 4.7.0
  1345 	 * @since 4.7.0
  1278 	 *
  1346 	 *
  1279 	 * @param array $value Post IDs.
  1347 	 * @param array $value Post IDs.
  1280 	 * @returns array Post IDs.
  1348 	 * @return array Post IDs.
  1281 	 */
  1349 	 */
  1282 	public function sanitize_nav_menus_created_posts( $value ) {
  1350 	public function sanitize_nav_menus_created_posts( $value ) {
  1283 		$post_ids = array();
  1351 		$post_ids = array();
  1284 		foreach ( wp_parse_id_list( $value ) as $post_id ) {
  1352 		foreach ( wp_parse_id_list( $value ) as $post_id ) {
  1285 			if ( empty( $post_id ) ) {
  1353 			if ( empty( $post_id ) ) {
  1291 			}
  1359 			}
  1292 			$post_type_obj = get_post_type_object( $post->post_type );
  1360 			$post_type_obj = get_post_type_object( $post->post_type );
  1293 			if ( ! $post_type_obj ) {
  1361 			if ( ! $post_type_obj ) {
  1294 				continue;
  1362 				continue;
  1295 			}
  1363 			}
  1296 			if ( ! current_user_can( $post_type_obj->cap->publish_posts ) || ! current_user_can( $post_type_obj->cap->edit_post, $post_id ) ) {
  1364 			if ( ! current_user_can( $post_type_obj->cap->publish_posts ) || ! current_user_can( 'edit_post', $post_id ) ) {
  1297 				continue;
  1365 				continue;
  1298 			}
  1366 			}
  1299 			$post_ids[] = $post->ID;
  1367 			$post_ids[] = $post->ID;
  1300 		}
  1368 		}
  1301 		return $post_ids;
  1369 		return $post_ids;
  1344 
  1412 
  1345 	/**
  1413 	/**
  1346 	 * Keep track of the arguments that are being passed to wp_nav_menu().
  1414 	 * Keep track of the arguments that are being passed to wp_nav_menu().
  1347 	 *
  1415 	 *
  1348 	 * @since 4.3.0
  1416 	 * @since 4.3.0
       
  1417 	 *
  1349 	 * @see wp_nav_menu()
  1418 	 * @see wp_nav_menu()
  1350 	 * @see WP_Customize_Widgets::filter_dynamic_sidebar_params()
  1419 	 * @see WP_Customize_Widgets::filter_dynamic_sidebar_params()
  1351 	 *
  1420 	 *
  1352 	 * @param array $args An array containing wp_nav_menu() arguments.
  1421 	 * @param array $args An array containing wp_nav_menu() arguments.
  1353 	 * @return array Arguments.
  1422 	 * @return array Arguments.