wp/wp-admin/includes/template.php
changeset 7 cf61fcea0001
parent 5 5e2f62d02dcd
child 9 177826044cd9
equal deleted inserted replaced
6:490d5cc509ed 7:cf61fcea0001
     5  * A Big Mess. Also some neat functions that are nicely written.
     5  * A Big Mess. Also some neat functions that are nicely written.
     6  *
     6  *
     7  * @package WordPress
     7  * @package WordPress
     8  * @subpackage Administration
     8  * @subpackage Administration
     9  */
     9  */
       
    10 
       
    11 /** Walker_Category_Checklist class */
       
    12 require_once( ABSPATH . 'wp-admin/includes/class-walker-category-checklist.php' );
       
    13 
       
    14 /** WP_Internal_Pointers class */
       
    15 require_once( ABSPATH . 'wp-admin/includes/class-wp-internal-pointers.php' );
    10 
    16 
    11 //
    17 //
    12 // Category Checklists
    18 // Category Checklists
    13 //
    19 //
    14 
       
    15 /**
       
    16  * Walker to output an unordered list of category checkbox input elements.
       
    17  *
       
    18  * @since 2.5.1
       
    19  *
       
    20  * @see Walker
       
    21  * @see wp_category_checklist()
       
    22  * @see wp_terms_checklist()
       
    23  */
       
    24 class Walker_Category_Checklist extends Walker {
       
    25 	public $tree_type = 'category';
       
    26 	public $db_fields = array ('parent' => 'parent', 'id' => 'term_id'); //TODO: decouple this
       
    27 
       
    28 	/**
       
    29 	 * Starts the list before the elements are added.
       
    30 	 *
       
    31 	 * @see Walker:start_lvl()
       
    32 	 *
       
    33 	 * @since 2.5.1
       
    34 	 *
       
    35 	 * @param string $output Passed by reference. Used to append additional content.
       
    36 	 * @param int    $depth  Depth of category. Used for tab indentation.
       
    37 	 * @param array  $args   An array of arguments. @see wp_terms_checklist()
       
    38 	 */
       
    39 	public function start_lvl( &$output, $depth = 0, $args = array() ) {
       
    40 		$indent = str_repeat("\t", $depth);
       
    41 		$output .= "$indent<ul class='children'>\n";
       
    42 	}
       
    43 
       
    44 	/**
       
    45 	 * Ends the list of after the elements are added.
       
    46 	 *
       
    47 	 * @see Walker::end_lvl()
       
    48 	 *
       
    49 	 * @since 2.5.1
       
    50 	 *
       
    51 	 * @param string $output Passed by reference. Used to append additional content.
       
    52 	 * @param int    $depth  Depth of category. Used for tab indentation.
       
    53 	 * @param array  $args   An array of arguments. @see wp_terms_checklist()
       
    54 	 */
       
    55 	public function end_lvl( &$output, $depth = 0, $args = array() ) {
       
    56 		$indent = str_repeat("\t", $depth);
       
    57 		$output .= "$indent</ul>\n";
       
    58 	}
       
    59 
       
    60 	/**
       
    61 	 * Start the element output.
       
    62 	 *
       
    63 	 * @see Walker::start_el()
       
    64 	 *
       
    65 	 * @since 2.5.1
       
    66 	 *
       
    67 	 * @param string $output   Passed by reference. Used to append additional content.
       
    68 	 * @param object $category The current term object.
       
    69 	 * @param int    $depth    Depth of the term in reference to parents. Default 0.
       
    70 	 * @param array  $args     An array of arguments. @see wp_terms_checklist()
       
    71 	 * @param int    $id       ID of the current term.
       
    72 	 */
       
    73 	public function start_el( &$output, $category, $depth = 0, $args = array(), $id = 0 ) {
       
    74 		if ( empty( $args['taxonomy'] ) ) {
       
    75 			$taxonomy = 'category';
       
    76 		} else {
       
    77 			$taxonomy = $args['taxonomy'];
       
    78 		}
       
    79 
       
    80 		if ( $taxonomy == 'category' ) {
       
    81 			$name = 'post_category';
       
    82 		} else {
       
    83 			$name = 'tax_input[' . $taxonomy . ']';
       
    84 		}
       
    85 
       
    86 		$args['popular_cats'] = empty( $args['popular_cats'] ) ? array() : $args['popular_cats'];
       
    87 		$class = in_array( $category->term_id, $args['popular_cats'] ) ? ' class="popular-category"' : '';
       
    88 
       
    89 		$args['selected_cats'] = empty( $args['selected_cats'] ) ? array() : $args['selected_cats'];
       
    90 
       
    91 		/** This filter is documented in wp-includes/category-template.php */
       
    92 		if ( ! empty( $args['list_only'] ) ) {
       
    93 			$aria_cheched = 'false';
       
    94 			$inner_class = 'category';
       
    95 
       
    96 			if ( in_array( $category->term_id, $args['selected_cats'] ) ) {
       
    97 				$inner_class .= ' selected';
       
    98 				$aria_cheched = 'true';
       
    99 			}
       
   100 
       
   101 			$output .= "\n" . '<li' . $class . '>' .
       
   102 				'<div class="' . $inner_class . '" data-term-id=' . $category->term_id .
       
   103 				' tabindex="0" role="checkbox" aria-checked="' . $aria_cheched . '">' .
       
   104 				esc_html( apply_filters( 'the_category', $category->name ) ) . '</div>';
       
   105 		} else {
       
   106 			$output .= "\n<li id='{$taxonomy}-{$category->term_id}'$class>" .
       
   107 				'<label class="selectit"><input value="' . $category->term_id . '" type="checkbox" name="'.$name.'[]" id="in-'.$taxonomy.'-' . $category->term_id . '"' .
       
   108 				checked( in_array( $category->term_id, $args['selected_cats'] ), true, false ) .
       
   109 				disabled( empty( $args['disabled'] ), false, false ) . ' /> ' .
       
   110 				esc_html( apply_filters( 'the_category', $category->name ) ) . '</label>';
       
   111 		}
       
   112 	}
       
   113 
       
   114 	/**
       
   115 	 * Ends the element output, if needed.
       
   116 	 *
       
   117 	 * @see Walker::end_el()
       
   118 	 *
       
   119 	 * @since 2.5.1
       
   120 	 *
       
   121 	 * @param string $output   Passed by reference. Used to append additional content.
       
   122 	 * @param object $category The current term object.
       
   123 	 * @param int    $depth    Depth of the term in reference to parents. Default 0.
       
   124 	 * @param array  $args     An array of arguments. @see wp_terms_checklist()
       
   125 	 */
       
   126 	public function end_el( &$output, $category, $depth = 0, $args = array() ) {
       
   127 		$output .= "</li>\n";
       
   128 	}
       
   129 }
       
   130 
    20 
   131 /**
    21 /**
   132  * Output an unordered list of checkbox input elements labeled with category names.
    22  * Output an unordered list of checkbox input elements labeled with category names.
   133  *
    23  *
   134  * @since 2.5.1
    24  * @since 2.5.1
   162  * Output an unordered list of checkbox input elements labelled with term names.
    52  * Output an unordered list of checkbox input elements labelled with term names.
   163  *
    53  *
   164  * Taxonomy-independent version of wp_category_checklist().
    54  * Taxonomy-independent version of wp_category_checklist().
   165  *
    55  *
   166  * @since 3.0.0
    56  * @since 3.0.0
       
    57  * @since 4.4.0 Introduced the `$echo` argument.
   167  *
    58  *
   168  * @param int          $post_id Optional. Post ID. Default 0.
    59  * @param int          $post_id Optional. Post ID. Default 0.
   169  * @param array|string $args {
    60  * @param array|string $args {
   170  *     Optional. Array or string of arguments for generating a terms checklist. Default empty array.
    61  *     Optional. Array or string of arguments for generating a terms checklist. Default empty array.
   171  *
    62  *
   177  *     @type object $walker               Walker object to use to build the output.
    68  *     @type object $walker               Walker object to use to build the output.
   178  *                                        Default is a Walker_Category_Checklist instance.
    69  *                                        Default is a Walker_Category_Checklist instance.
   179  *     @type string $taxonomy             Taxonomy to generate the checklist for. Default 'category'.
    70  *     @type string $taxonomy             Taxonomy to generate the checklist for. Default 'category'.
   180  *     @type bool   $checked_ontop        Whether to move checked items out of the hierarchy and to
    71  *     @type bool   $checked_ontop        Whether to move checked items out of the hierarchy and to
   181  *                                        the top of the list. Default true.
    72  *                                        the top of the list. Default true.
       
    73  *     @type bool   $echo                 Whether to echo the generated markup. False to return the markup instead
       
    74  *                                        of echoing it. Default true.
   182  * }
    75  * }
   183  */
    76  */
   184 function wp_terms_checklist( $post_id = 0, $args = array() ) {
    77 function wp_terms_checklist( $post_id = 0, $args = array() ) {
   185  	$defaults = array(
    78  	$defaults = array(
   186 		'descendants_and_self' => 0,
    79 		'descendants_and_self' => 0,
   187 		'selected_cats' => false,
    80 		'selected_cats' => false,
   188 		'popular_cats' => false,
    81 		'popular_cats' => false,
   189 		'walker' => null,
    82 		'walker' => null,
   190 		'taxonomy' => 'category',
    83 		'taxonomy' => 'category',
   191 		'checked_ontop' => true
    84 		'checked_ontop' => true,
       
    85 		'echo' => true,
   192 	);
    86 	);
   193 
    87 
   194 	/**
    88 	/**
   195 	 * Filter the taxonomy terms checklist arguments.
    89 	 * Filters the taxonomy terms checklist arguments.
   196 	 *
    90 	 *
   197 	 * @since 3.4.0
    91 	 * @since 3.4.0
   198 	 *
    92 	 *
   199 	 * @see wp_terms_checklist()
    93 	 * @see wp_terms_checklist()
   200 	 *
    94 	 *
   249 		array_unshift( $categories, $self );
   143 		array_unshift( $categories, $self );
   250 	} else {
   144 	} else {
   251 		$categories = (array) get_terms( $taxonomy, array( 'get' => 'all' ) );
   145 		$categories = (array) get_terms( $taxonomy, array( 'get' => 'all' ) );
   252 	}
   146 	}
   253 
   147 
       
   148 	$output = '';
       
   149 
   254 	if ( $r['checked_ontop'] ) {
   150 	if ( $r['checked_ontop'] ) {
   255 		// Post process $categories rather than adding an exclude to the get_terms() query to keep the query the same across all posts (for any query cache)
   151 		// Post process $categories rather than adding an exclude to the get_terms() query to keep the query the same across all posts (for any query cache)
   256 		$checked_categories = array();
   152 		$checked_categories = array();
   257 		$keys = array_keys( $categories );
   153 		$keys = array_keys( $categories );
   258 
   154 
   259 		foreach( $keys as $k ) {
   155 		foreach ( $keys as $k ) {
   260 			if ( in_array( $categories[$k]->term_id, $args['selected_cats'] ) ) {
   156 			if ( in_array( $categories[$k]->term_id, $args['selected_cats'] ) ) {
   261 				$checked_categories[] = $categories[$k];
   157 				$checked_categories[] = $categories[$k];
   262 				unset( $categories[$k] );
   158 				unset( $categories[$k] );
   263 			}
   159 			}
   264 		}
   160 		}
   265 
   161 
   266 		// Put checked cats on top
   162 		// Put checked cats on top
   267 		echo call_user_func_array( array( $walker, 'walk' ), array( $checked_categories, 0, $args ) );
   163 		$output .= call_user_func_array( array( $walker, 'walk' ), array( $checked_categories, 0, $args ) );
   268 	}
   164 	}
   269 	// Then the rest of them
   165 	// Then the rest of them
   270 	echo call_user_func_array( array( $walker, 'walk' ), array( $categories, 0, $args ) );
   166 	$output .= call_user_func_array( array( $walker, 'walk' ), array( $categories, 0, $args ) );
       
   167 
       
   168 	if ( $r['echo'] ) {
       
   169 		echo $output;
       
   170 	}
       
   171 
       
   172 	return $output;
   271 }
   173 }
   272 
   174 
   273 /**
   175 /**
   274  * Retrieve a list of the most popular terms from the specified taxonomy.
   176  * Retrieve a list of the most popular terms from the specified taxonomy.
   275  *
   177  *
   299 	$tax = get_taxonomy($taxonomy);
   201 	$tax = get_taxonomy($taxonomy);
   300 
   202 
   301 	$popular_ids = array();
   203 	$popular_ids = array();
   302 	foreach ( (array) $terms as $term ) {
   204 	foreach ( (array) $terms as $term ) {
   303 		$popular_ids[] = $term->term_id;
   205 		$popular_ids[] = $term->term_id;
   304 		if ( !$echo ) // hack for AJAX use
   206 		if ( !$echo ) // Hack for Ajax use.
   305 			continue;
   207 			continue;
   306 		$id = "popular-$taxonomy-$term->term_id";
   208 		$id = "popular-$taxonomy-$term->term_id";
   307 		$checked = in_array( $term->term_id, $checked_terms ) ? 'checked="checked"' : '';
   209 		$checked = in_array( $term->term_id, $checked_terms ) ? 'checked="checked"' : '';
   308 		?>
   210 		?>
   309 
   211 
   310 		<li id="<?php echo $id; ?>" class="popular-category">
   212 		<li id="<?php echo $id; ?>" class="popular-category">
   311 			<label class="selectit">
   213 			<label class="selectit">
   312 				<input id="in-<?php echo $id; ?>" type="checkbox" <?php echo $checked; ?> value="<?php echo (int) $term->term_id; ?>" <?php disabled( ! current_user_can( $tax->cap->assign_terms ) ); ?> />
   214 				<input id="in-<?php echo $id; ?>" type="checkbox" <?php echo $checked; ?> value="<?php echo (int) $term->term_id; ?>" <?php disabled( ! current_user_can( $tax->cap->assign_terms ) ); ?> />
   313 				<?php
   215 				<?php
   314 				/** This filter is documented in wp-includes/category-template.php */
   216 				/** This filter is documented in wp-includes/category-template.php */
   315 				echo esc_html( apply_filters( 'the_category', $term->name ) );
   217 				echo esc_html( apply_filters( 'the_category', $term->name, '', '' ) );
   316 				?>
   218 				?>
   317 			</label>
   219 			</label>
   318 		</li>
   220 		</li>
   319 
   221 
   320 		<?php
   222 		<?php
   321 	}
   223 	}
   322 	return $popular_ids;
   224 	return $popular_ids;
   323 }
   225 }
   324 
   226 
   325 /**
   227 /**
   326  * {@internal Missing Short Description}}
   228  * Outputs a link category checklist element.
   327  *
   229  *
   328  * @since 2.5.1
   230  * @since 2.5.1
   329  *
   231  *
   330  * @param int $link_id
   232  * @param int $link_id
   331  */
   233  */
   351 
   253 
   352 	foreach ( $categories as $category ) {
   254 	foreach ( $categories as $category ) {
   353 		$cat_id = $category->term_id;
   255 		$cat_id = $category->term_id;
   354 
   256 
   355 		/** This filter is documented in wp-includes/category-template.php */
   257 		/** This filter is documented in wp-includes/category-template.php */
   356 		$name = esc_html( apply_filters( 'the_category', $category->name ) );
   258 		$name = esc_html( apply_filters( 'the_category', $category->name, '', '' ) );
   357 		$checked = in_array( $cat_id, $checked_categories ) ? ' checked="checked"' : '';
   259 		$checked = in_array( $cat_id, $checked_categories ) ? ' checked="checked"' : '';
   358 		echo '<li id="link-category-', $cat_id, '"><label for="in-link-category-', $cat_id, '" class="selectit"><input value="', $cat_id, '" type="checkbox" name="link_category[]" id="in-link-category-', $cat_id, '"', $checked, '/> ', $name, "</label></li>";
   260 		echo '<li id="link-category-', $cat_id, '"><label for="in-link-category-', $cat_id, '" class="selectit"><input value="', $cat_id, '" type="checkbox" name="link_category[]" id="in-link-category-', $cat_id, '"', $checked, '/> ', $name, "</label></li>";
   359 	}
   261 	}
   360 }
   262 }
   361 
   263 
   374 	$title = esc_textarea( trim( $post->post_title ) );
   276 	$title = esc_textarea( trim( $post->post_title ) );
   375 
   277 
   376 	/** This filter is documented in wp-admin/edit-tag-form.php */
   278 	/** This filter is documented in wp-admin/edit-tag-form.php */
   377 	echo '
   279 	echo '
   378 <div class="hidden" id="inline_' . $post->ID . '">
   280 <div class="hidden" id="inline_' . $post->ID . '">
   379 	<div class="post_title">' . $title . '</div>
   281 	<div class="post_title">' . $title . '</div>' .
   380 	<div class="post_name">' . apply_filters( 'editable_slug', $post->post_name ) . '</div>
   282 	/** This filter is documented in wp-admin/edit-tag-form.php */
       
   283 	'<div class="post_name">' . apply_filters( 'editable_slug', $post->post_name, $post ) . '</div>
   381 	<div class="post_author">' . $post->post_author . '</div>
   284 	<div class="post_author">' . $post->post_author . '</div>
   382 	<div class="comment_status">' . esc_html( $post->comment_status ) . '</div>
   285 	<div class="comment_status">' . esc_html( $post->comment_status ) . '</div>
   383 	<div class="ping_status">' . esc_html( $post->ping_status ) . '</div>
   286 	<div class="ping_status">' . esc_html( $post->ping_status ) . '</div>
   384 	<div class="_status">' . esc_html( $post->post_status ) . '</div>
   287 	<div class="_status">' . esc_html( $post->post_status ) . '</div>
   385 	<div class="jj">' . mysql2date( 'd', $post->post_date, false ) . '</div>
   288 	<div class="jj">' . mysql2date( 'd', $post->post_date, false ) . '</div>
   388 	<div class="hh">' . mysql2date( 'H', $post->post_date, false ) . '</div>
   291 	<div class="hh">' . mysql2date( 'H', $post->post_date, false ) . '</div>
   389 	<div class="mn">' . mysql2date( 'i', $post->post_date, false ) . '</div>
   292 	<div class="mn">' . mysql2date( 'i', $post->post_date, false ) . '</div>
   390 	<div class="ss">' . mysql2date( 's', $post->post_date, false ) . '</div>
   293 	<div class="ss">' . mysql2date( 's', $post->post_date, false ) . '</div>
   391 	<div class="post_password">' . esc_html( $post->post_password ) . '</div>';
   294 	<div class="post_password">' . esc_html( $post->post_password ) . '</div>';
   392 
   295 
   393 	if ( $post_type_object->hierarchical )
   296 	if ( $post_type_object->hierarchical ) {
   394 		echo '<div class="post_parent">' . $post->post_parent . '</div>';
   297 		echo '<div class="post_parent">' . $post->post_parent . '</div>';
   395 
   298 	}
   396 	if ( $post->post_type == 'page' )
   299 
   397 		echo '<div class="page_template">' . esc_html( get_post_meta( $post->ID, '_wp_page_template', true ) ) . '</div>';
   300 	echo '<div class="page_template">' . ( $post->page_template ? esc_html( $post->page_template ) : 'default' ) . '</div>';
   398 
   301 
   399 	if ( post_type_supports( $post->post_type, 'page-attributes' ) )
   302 	if ( post_type_supports( $post->post_type, 'page-attributes' ) ) {
   400 		echo '<div class="menu_order">' . $post->menu_order . '</div>';
   303 		echo '<div class="menu_order">' . $post->menu_order . '</div>';
       
   304 	}
   401 
   305 
   402 	$taxonomy_names = get_object_taxonomies( $post->post_type );
   306 	$taxonomy_names = get_object_taxonomies( $post->post_type );
   403 	foreach ( $taxonomy_names as $taxonomy_name) {
   307 	foreach ( $taxonomy_names as $taxonomy_name) {
   404 		$taxonomy = get_taxonomy( $taxonomy_name );
   308 		$taxonomy = get_taxonomy( $taxonomy_name );
   405 
   309 
   406 		if ( $taxonomy->hierarchical && $taxonomy->show_ui ) {
   310 		if ( $taxonomy->hierarchical && $taxonomy->show_ui ) {
   407 
   311 
   408 			$terms = get_object_term_cache( $post->ID, $taxonomy_name );
   312 			$terms = get_object_term_cache( $post->ID, $taxonomy_name );
   409 			if ( false === $terms ) {
   313 			if ( false === $terms ) {
   410 				$terms = wp_get_object_terms( $post->ID, $taxonomy_name );
   314 				$terms = wp_get_object_terms( $post->ID, $taxonomy_name );
   411 				wp_cache_add( $post->ID, $terms, $taxonomy_name . '_relationships' );
   315 				wp_cache_add( $post->ID, wp_list_pluck( $terms, 'term_id' ), $taxonomy_name . '_relationships' );
   412 			}
   316 			}
   413 			$term_ids = empty( $terms ) ? array() : wp_list_pluck( $terms, 'term_id' );
   317 			$term_ids = empty( $terms ) ? array() : wp_list_pluck( $terms, 'term_id' );
   414 
   318 
   415 			echo '<div class="post_category" id="' . $taxonomy_name . '_' . $post->ID . '">' . implode( ',', $term_ids ) . '</div>';
   319 			echo '<div class="post_category" id="' . $taxonomy_name . '_' . $post->ID . '">' . implode( ',', $term_ids ) . '</div>';
   416 
   320 
   417 		} elseif ( $taxonomy->show_ui ) {
   321 		} elseif ( $taxonomy->show_ui ) {
   418 
   322 
       
   323 			$terms_to_edit = get_terms_to_edit( $post->ID, $taxonomy_name );
       
   324 			if ( ! is_string( $terms_to_edit ) ) {
       
   325 				$terms_to_edit = '';
       
   326 			}
       
   327 
   419 			echo '<div class="tags_input" id="'.$taxonomy_name.'_'.$post->ID.'">'
   328 			echo '<div class="tags_input" id="'.$taxonomy_name.'_'.$post->ID.'">'
   420 				. esc_html( str_replace( ',', ', ', get_terms_to_edit( $post->ID, $taxonomy_name ) ) ) . '</div>';
   329 				. esc_html( str_replace( ',', ', ', $terms_to_edit ) ) . '</div>';
   421 
   330 
   422 		}
   331 		}
   423 	}
   332 	}
   424 
   333 
   425 	if ( !$post_type_object->hierarchical )
   334 	if ( !$post_type_object->hierarchical )
   426 		echo '<div class="sticky">' . (is_sticky($post->ID) ? 'sticky' : '') . '</div>';
   335 		echo '<div class="sticky">' . (is_sticky($post->ID) ? 'sticky' : '') . '</div>';
   427 
   336 
   428 	if ( post_type_supports( $post->post_type, 'post-formats' ) )
   337 	if ( post_type_supports( $post->post_type, 'post-formats' ) )
   429 		echo '<div class="post_format">' . esc_html( get_post_format( $post->ID ) ) . '</div>';
   338 		echo '<div class="post_format">' . esc_html( get_post_format( $post->ID ) ) . '</div>';
   430 
   339 
       
   340 	/**
       
   341 	 * Fires after outputting the fields for the inline editor for posts and pages.
       
   342 	 *
       
   343 	 * @since 4.9.8
       
   344 	 *
       
   345 	 * @param WP_Post      $post             The current post object.
       
   346 	 * @param WP_Post_Type $post_type_object The current post's post type object.
       
   347 	 */
       
   348 	do_action( 'add_inline_data', $post, $post_type_object );
       
   349 
   431 	echo '</div>';
   350 	echo '</div>';
   432 }
   351 }
   433 
   352 
   434 /**
   353 /**
   435  * {@internal Missing Short Description}}
   354  * Outputs the in-line comment reply-to form in the Comments list table.
   436  *
   355  *
   437  * @since 2.7.0
   356  * @since 2.7.0
   438  *
   357  *
   439  * @param int $position
   358  * @global WP_List_Table $wp_list_table
   440  * @param bool $checkbox
   359  *
       
   360  * @param int    $position
       
   361  * @param bool   $checkbox
   441  * @param string $mode
   362  * @param string $mode
   442  * @param bool $table_row
   363  * @param bool   $table_row
   443  */
   364  */
   444 function wp_comment_reply( $position = 1, $checkbox = false, $mode = 'single', $table_row = true ) {
   365 function wp_comment_reply( $position = 1, $checkbox = false, $mode = 'single', $table_row = true ) {
   445 	global $wp_list_table;
   366 	global $wp_list_table;
   446 	/**
   367 	/**
   447 	 * Filter the in-line comment reply-to form output in the Comments
   368 	 * Filters the in-line comment reply-to form output in the Comments
   448 	 * list table.
   369 	 * list table.
   449 	 *
   370 	 *
   450 	 * Returning a non-empty value here will short-circuit display
   371 	 * Returning a non-empty value here will short-circuit display
   451 	 * of the in-line comment-reply form in the Comments list table,
   372 	 * of the in-line comment-reply form in the Comments list table,
   452 	 * echoing the returned value instead.
   373 	 * echoing the returned value instead.
   474 	}
   395 	}
   475 
   396 
   476 ?>
   397 ?>
   477 <form method="get">
   398 <form method="get">
   478 <?php if ( $table_row ) : ?>
   399 <?php if ( $table_row ) : ?>
   479 <table style="display:none;"><tbody id="com-reply"><tr id="replyrow" style="display:none;"><td colspan="<?php echo $wp_list_table->get_column_count(); ?>" class="colspanchange">
   400 <table style="display:none;"><tbody id="com-reply"><tr id="replyrow" class="inline-edit-row" style="display:none;"><td colspan="<?php echo $wp_list_table->get_column_count(); ?>" class="colspanchange">
   480 <?php else : ?>
   401 <?php else : ?>
   481 <div id="com-reply" style="display:none;"><div id="replyrow" style="display:none;">
   402 <div id="com-reply" style="display:none;"><div id="replyrow" style="display:none;">
   482 <?php endif; ?>
   403 <?php endif; ?>
   483 	<div id="replyhead" style="display:none;"><h5><?php _e( 'Reply to Comment' ); ?></h5></div>
   404 	<fieldset class="comment-reply">
   484 	<div id="addhead" style="display:none;"><h5><?php _e('Add new Comment'); ?></h5></div>
   405 	<legend>
   485 	<div id="edithead" style="display:none;">
   406 		<span class="hidden" id="editlegend"><?php _e( 'Edit Comment' ); ?></span>
   486 		<div class="inside">
   407 		<span class="hidden" id="replyhead"><?php _e( 'Reply to Comment' ); ?></span>
   487 		<label for="author"><?php _e('Name') ?></label>
   408 		<span class="hidden" id="addhead"><?php _e( 'Add new Comment' ); ?></span>
   488 		<input type="text" name="newcomment_author" size="50" value="" id="author" />
   409 	</legend>
   489 		</div>
       
   490 
       
   491 		<div class="inside">
       
   492 		<label for="author-email"><?php _e('E-mail') ?></label>
       
   493 		<input type="text" name="newcomment_author_email" size="50" value="" id="author-email" />
       
   494 		</div>
       
   495 
       
   496 		<div class="inside">
       
   497 		<label for="author-url"><?php _e('URL') ?></label>
       
   498 		<input type="text" id="author-url" name="newcomment_author_url" class="code" size="103" value="" />
       
   499 		</div>
       
   500 		<div style="clear:both;"></div>
       
   501 	</div>
       
   502 
   410 
   503 	<div id="replycontainer">
   411 	<div id="replycontainer">
       
   412 	<label for="replycontent" class="screen-reader-text"><?php _e( 'Comment' ); ?></label>
   504 	<?php
   413 	<?php
   505 	$quicktags_settings = array( 'buttons' => 'strong,em,link,block,del,ins,img,ul,ol,li,code,close' );
   414 	$quicktags_settings = array( 'buttons' => 'strong,em,link,block,del,ins,img,ul,ol,li,code,close' );
   506 	wp_editor( '', 'replycontent', array( 'media_buttons' => false, 'tinymce' => false, 'quicktags' => $quicktags_settings ) );
   415 	wp_editor( '', 'replycontent', array( 'media_buttons' => false, 'tinymce' => false, 'quicktags' => $quicktags_settings ) );
   507 	?>
   416 	?>
   508 	</div>
   417 	</div>
   509 
   418 
   510 	<p id="replysubmit" class="submit">
   419 	<div id="edithead" style="display:none;">
   511 	<a href="#comments-form" class="save button-primary alignright">
   420 		<div class="inside">
   512 	<span id="addbtn" style="display:none;"><?php _e('Add Comment'); ?></span>
   421 		<label for="author-name"><?php _e( 'Name' ) ?></label>
   513 	<span id="savebtn" style="display:none;"><?php _e('Update Comment'); ?></span>
   422 		<input type="text" name="newcomment_author" size="50" value="" id="author-name" />
   514 	<span id="replybtn" style="display:none;"><?php _e('Submit Reply'); ?></span></a>
   423 		</div>
   515 	<a href="#comments-form" class="cancel button-secondary alignleft"><?php _e('Cancel'); ?></a>
   424 
   516 	<span class="waiting spinner"></span>
   425 		<div class="inside">
   517 	<span class="error" style="display:none;"></span>
   426 		<label for="author-email"><?php _e('Email') ?></label>
   518 	<br class="clear" />
   427 		<input type="text" name="newcomment_author_email" size="50" value="" id="author-email" />
   519 	</p>
   428 		</div>
       
   429 
       
   430 		<div class="inside">
       
   431 		<label for="author-url"><?php _e('URL') ?></label>
       
   432 		<input type="text" id="author-url" name="newcomment_author_url" class="code" size="103" value="" />
       
   433 		</div>
       
   434 	</div>
       
   435 
       
   436 	<div id="replysubmit" class="submit">
       
   437 		<p>
       
   438 			<a href="#comments-form" class="save button button-primary alignright">
       
   439 				<span id="addbtn" style="display: none;"><?php _e( 'Add Comment' ); ?></span>
       
   440 				<span id="savebtn" style="display: none;"><?php _e( 'Update Comment' ); ?></span>
       
   441 				<span id="replybtn" style="display: none;"><?php _e( 'Submit Reply' ); ?></span>
       
   442 			</a>
       
   443 			<a href="#comments-form" class="cancel button alignleft"><?php _e( 'Cancel' ); ?></a>
       
   444 			<span class="waiting spinner"></span>
       
   445 		</p>
       
   446 		<br class="clear" />
       
   447 		<div class="notice notice-error notice-alt inline hidden">
       
   448 			<p class="error"></p>
       
   449 		</div>
       
   450 	</div>
   520 
   451 
   521 	<input type="hidden" name="action" id="action" value="" />
   452 	<input type="hidden" name="action" id="action" value="" />
   522 	<input type="hidden" name="comment_ID" id="comment_ID" value="" />
   453 	<input type="hidden" name="comment_ID" id="comment_ID" value="" />
   523 	<input type="hidden" name="comment_post_ID" id="comment_post_ID" value="" />
   454 	<input type="hidden" name="comment_post_ID" id="comment_post_ID" value="" />
   524 	<input type="hidden" name="status" id="status" value="" />
   455 	<input type="hidden" name="status" id="status" value="" />
   528 	<?php
   459 	<?php
   529 		wp_nonce_field( 'replyto-comment', '_ajax_nonce-replyto-comment', false );
   460 		wp_nonce_field( 'replyto-comment', '_ajax_nonce-replyto-comment', false );
   530 		if ( current_user_can( 'unfiltered_html' ) )
   461 		if ( current_user_can( 'unfiltered_html' ) )
   531 			wp_nonce_field( 'unfiltered-html-comment', '_wp_unfiltered_html_comment', false );
   462 			wp_nonce_field( 'unfiltered-html-comment', '_wp_unfiltered_html_comment', false );
   532 	?>
   463 	?>
       
   464 	</fieldset>
   533 <?php if ( $table_row ) : ?>
   465 <?php if ( $table_row ) : ?>
   534 </td></tr></tbody></table>
   466 </td></tr></tbody></table>
   535 <?php else : ?>
   467 <?php else : ?>
   536 </div></div>
   468 </div></div>
   537 <?php endif; ?>
   469 <?php endif; ?>
   554 </div>
   486 </div>
   555 <?php
   487 <?php
   556 }
   488 }
   557 
   489 
   558 /**
   490 /**
   559  * {@internal Missing Short Description}}
   491  * Outputs a post's public meta data in the Custom Fields meta box.
   560  *
   492  *
   561  * @since 1.2.0
   493  * @since 1.2.0
   562  *
   494  *
   563  * @param array $meta
   495  * @param array $meta
   564  */
   496  */
   597 </table>
   529 </table>
   598 <?php
   530 <?php
   599 }
   531 }
   600 
   532 
   601 /**
   533 /**
   602  * {@internal Missing Short Description}}
   534  * Outputs a single row of public meta data in the Custom Fields meta box.
   603  *
   535  *
   604  * @since 2.5.0
   536  * @since 2.5.0
       
   537  *
       
   538  * @staticvar string $update_nonce
   605  *
   539  *
   606  * @param array $entry
   540  * @param array $entry
   607  * @param int   $count
   541  * @param int   $count
   608  * @return string
   542  * @return string
   609  */
   543  */
   610 function _list_meta_row( $entry, &$count ) {
   544 function _list_meta_row( $entry, &$count ) {
   611 	static $update_nonce = false;
   545 	static $update_nonce = '';
   612 
   546 
   613 	if ( is_protected_meta( $entry['meta_key'], 'post' ) )
   547 	if ( is_protected_meta( $entry['meta_key'], 'post' ) )
   614 		return '';
   548 		return '';
   615 
   549 
   616 	if ( !$update_nonce )
   550 	if ( ! $update_nonce )
   617 		$update_nonce = wp_create_nonce( 'add-meta' );
   551 		$update_nonce = wp_create_nonce( 'add-meta' );
   618 
   552 
   619 	$r = '';
   553 	$r = '';
   620 	++ $count;
   554 	++ $count;
   621 
   555 
   654 /**
   588 /**
   655  * Prints the form in the Custom Fields meta box.
   589  * Prints the form in the Custom Fields meta box.
   656  *
   590  *
   657  * @since 1.2.0
   591  * @since 1.2.0
   658  *
   592  *
       
   593  * @global wpdb $wpdb WordPress database abstraction object.
       
   594  *
   659  * @param WP_Post $post Optional. The post being edited.
   595  * @param WP_Post $post Optional. The post being edited.
   660  */
   596  */
   661 function meta_form( $post = null ) {
   597 function meta_form( $post = null ) {
   662 	global $wpdb;
   598 	global $wpdb;
   663 	$post = get_post( $post );
   599 	$post = get_post( $post );
   664 
   600 
   665 	/**
   601 	/**
   666 	 * Filter the number of custom fields to retrieve for the drop-down
   602 	 * Filters values for the meta key dropdown in the Custom Fields meta box.
   667 	 * in the Custom Fields meta box.
       
   668 	 *
   603 	 *
   669 	 * @since 2.1.0
   604 	 * Returning a non-null value will effectively short-circuit and avoid a
       
   605 	 * potentially expensive query against postmeta.
   670 	 *
   606 	 *
   671 	 * @param int $limit Number of custom fields to retrieve. Default 30.
   607 	 * @since 4.4.0
       
   608 	 *
       
   609 	 * @param array|null $keys Pre-defined meta keys to be used in place of a postmeta query. Default null.
       
   610 	 * @param WP_Post    $post The current post object.
   672 	 */
   611 	 */
   673 	$limit = apply_filters( 'postmeta_form_limit', 30 );
   612 	$keys = apply_filters( 'postmeta_form_keys', null, $post );
   674 	$sql = "SELECT meta_key
   613 
   675 		FROM $wpdb->postmeta
   614 	if ( null === $keys ) {
   676 		GROUP BY meta_key
   615 		/**
   677 		HAVING meta_key NOT LIKE %s
   616 		 * Filters the number of custom fields to retrieve for the drop-down
   678 		ORDER BY meta_key
   617 		 * in the Custom Fields meta box.
   679 		LIMIT %d";
   618 		 *
   680 	$keys = $wpdb->get_col( $wpdb->prepare( $sql, $wpdb->esc_like( '_' ) . '%', $limit ) );
   619 		 * @since 2.1.0
       
   620 		 *
       
   621 		 * @param int $limit Number of custom fields to retrieve. Default 30.
       
   622 		 */
       
   623 		$limit = apply_filters( 'postmeta_form_limit', 30 );
       
   624 		$sql = "SELECT DISTINCT meta_key
       
   625 			FROM $wpdb->postmeta
       
   626 			WHERE meta_key NOT BETWEEN '_' AND '_z'
       
   627 			HAVING meta_key NOT LIKE %s
       
   628 			ORDER BY meta_key
       
   629 			LIMIT %d";
       
   630 		$keys = $wpdb->get_col( $wpdb->prepare( $sql, $wpdb->esc_like( '_' ) . '%', $limit ) );
       
   631 	}
       
   632 
   681 	if ( $keys ) {
   633 	if ( $keys ) {
   682 		natcasesort( $keys );
   634 		natcasesort( $keys );
   683 		$meta_key_input_id = 'metakeyselect';
   635 		$meta_key_input_id = 'metakeyselect';
   684 	} else {
   636 	} else {
   685 		$meta_key_input_id = 'metakeyinput';
   637 		$meta_key_input_id = 'metakeyinput';
   720 <td><textarea id="metavalue" name="metavalue" rows="2" cols="25"></textarea></td>
   672 <td><textarea id="metavalue" name="metavalue" rows="2" cols="25"></textarea></td>
   721 </tr>
   673 </tr>
   722 
   674 
   723 <tr><td colspan="2">
   675 <tr><td colspan="2">
   724 <div class="submit">
   676 <div class="submit">
   725 <?php submit_button( __( 'Add Custom Field' ), 'secondary', 'addmeta', false, array( 'id' => 'newmeta-submit', 'data-wp-lists' => 'add:the-list:newmeta' ) ); ?>
   677 <?php submit_button( __( 'Add Custom Field' ), '', 'addmeta', false, array( 'id' => 'newmeta-submit', 'data-wp-lists' => 'add:the-list:newmeta' ) ); ?>
   726 </div>
   678 </div>
   727 <?php wp_nonce_field( 'add-meta', '_ajax_nonce-add-meta', false ); ?>
   679 <?php wp_nonce_field( 'add-meta', '_ajax_nonce-add-meta', false ); ?>
   728 </td></tr>
   680 </td></tr>
   729 </tbody>
   681 </tbody>
   730 </table>
   682 </table>
   734 
   686 
   735 /**
   687 /**
   736  * Print out HTML form date elements for editing post or comment publish date.
   688  * Print out HTML form date elements for editing post or comment publish date.
   737  *
   689  *
   738  * @since 0.71
   690  * @since 0.71
       
   691  * @since 4.4.0 Converted to use get_comment() instead of the global `$comment`.
       
   692  *
       
   693  * @global WP_Locale  $wp_locale
   739  *
   694  *
   740  * @param int|bool $edit      Accepts 1|true for editing the date, 0|false for adding the date.
   695  * @param int|bool $edit      Accepts 1|true for editing the date, 0|false for adding the date.
   741  * @param int|bool $for_post  Accepts 1|true for applying the date to a post, 0|false for a comment.
   696  * @param int|bool $for_post  Accepts 1|true for applying the date to a post, 0|false for a comment.
   742  * @param int      $tab_index The tabindex attribute to add. Default 0.
   697  * @param int      $tab_index The tabindex attribute to add. Default 0.
   743  * @param int|bool $multi     Optional. Whether the additional fields and buttons should be added.
   698  * @param int|bool $multi     Optional. Whether the additional fields and buttons should be added.
   744  *                            Default 0|false.
   699  *                            Default 0|false.
   745  */
   700  */
   746 function touch_time( $edit = 1, $for_post = 1, $tab_index = 0, $multi = 0 ) {
   701 function touch_time( $edit = 1, $for_post = 1, $tab_index = 0, $multi = 0 ) {
   747 	global $wp_locale, $comment;
   702 	global $wp_locale;
   748 	$post = get_post();
   703 	$post = get_post();
   749 
   704 
   750 	if ( $for_post )
   705 	if ( $for_post )
   751 		$edit = ! ( in_array($post->post_status, array('draft', 'pending') ) && (!$post->post_date_gmt || '0000-00-00 00:00:00' == $post->post_date_gmt ) );
   706 		$edit = ! ( in_array($post->post_status, array('draft', 'pending') ) && (!$post->post_date_gmt || '0000-00-00 00:00:00' == $post->post_date_gmt ) );
   752 
   707 
   756 
   711 
   757 	// todo: Remove this?
   712 	// todo: Remove this?
   758 	// echo '<label for="timestamp" style="display: block;"><input type="checkbox" class="checkbox" name="edit_date" value="1" id="timestamp"'.$tab_index_attribute.' /> '.__( 'Edit timestamp' ).'</label><br />';
   713 	// echo '<label for="timestamp" style="display: block;"><input type="checkbox" class="checkbox" name="edit_date" value="1" id="timestamp"'.$tab_index_attribute.' /> '.__( 'Edit timestamp' ).'</label><br />';
   759 
   714 
   760 	$time_adj = current_time('timestamp');
   715 	$time_adj = current_time('timestamp');
   761 	$post_date = ($for_post) ? $post->post_date : $comment->comment_date;
   716 	$post_date = ($for_post) ? $post->post_date : get_comment()->comment_date;
   762 	$jj = ($edit) ? mysql2date( 'd', $post_date, false ) : gmdate( 'd', $time_adj );
   717 	$jj = ($edit) ? mysql2date( 'd', $post_date, false ) : gmdate( 'd', $time_adj );
   763 	$mm = ($edit) ? mysql2date( 'm', $post_date, false ) : gmdate( 'm', $time_adj );
   718 	$mm = ($edit) ? mysql2date( 'm', $post_date, false ) : gmdate( 'm', $time_adj );
   764 	$aa = ($edit) ? mysql2date( 'Y', $post_date, false ) : gmdate( 'Y', $time_adj );
   719 	$aa = ($edit) ? mysql2date( 'Y', $post_date, false ) : gmdate( 'Y', $time_adj );
   765 	$hh = ($edit) ? mysql2date( 'H', $post_date, false ) : gmdate( 'H', $time_adj );
   720 	$hh = ($edit) ? mysql2date( 'H', $post_date, false ) : gmdate( 'H', $time_adj );
   766 	$mn = ($edit) ? mysql2date( 'i', $post_date, false ) : gmdate( 'i', $time_adj );
   721 	$mn = ($edit) ? mysql2date( 'i', $post_date, false ) : gmdate( 'i', $time_adj );
   770 	$cur_mm = gmdate( 'm', $time_adj );
   725 	$cur_mm = gmdate( 'm', $time_adj );
   771 	$cur_aa = gmdate( 'Y', $time_adj );
   726 	$cur_aa = gmdate( 'Y', $time_adj );
   772 	$cur_hh = gmdate( 'H', $time_adj );
   727 	$cur_hh = gmdate( 'H', $time_adj );
   773 	$cur_mn = gmdate( 'i', $time_adj );
   728 	$cur_mn = gmdate( 'i', $time_adj );
   774 
   729 
   775 	$month = '<label for="mm" class="screen-reader-text">' . __( 'Month' ) . '</label><select ' . ( $multi ? '' : 'id="mm" ' ) . 'name="mm"' . $tab_index_attribute . ">\n";
   730 	$month = '<label><span class="screen-reader-text">' . __( 'Month' ) . '</span><select ' . ( $multi ? '' : 'id="mm" ' ) . 'name="mm"' . $tab_index_attribute . ">\n";
   776 	for ( $i = 1; $i < 13; $i = $i +1 ) {
   731 	for ( $i = 1; $i < 13; $i = $i +1 ) {
   777 		$monthnum = zeroise($i, 2);
   732 		$monthnum = zeroise($i, 2);
   778 		$month .= "\t\t\t" . '<option value="' . $monthnum . '" ' . selected( $monthnum, $mm, false ) . '>';
   733 		$monthtext = $wp_locale->get_month_abbrev( $wp_locale->get_month( $i ) );
       
   734 		$month .= "\t\t\t" . '<option value="' . $monthnum . '" data-text="' . $monthtext . '" ' . selected( $monthnum, $mm, false ) . '>';
   779 		/* translators: 1: month number (01, 02, etc.), 2: month abbreviation */
   735 		/* translators: 1: month number (01, 02, etc.), 2: month abbreviation */
   780 		$month .= sprintf( __( '%1$s-%2$s' ), $monthnum, $wp_locale->get_month_abbrev( $wp_locale->get_month( $i ) ) ) . "</option>\n";
   736 		$month .= sprintf( __( '%1$s-%2$s' ), $monthnum, $monthtext ) . "</option>\n";
   781 	}
   737 	}
   782 	$month .= '</select>';
   738 	$month .= '</select></label>';
   783 
   739 
   784 	$day = '<label for="jj" class="screen-reader-text">' . __( 'Day' ) . '</label><input type="text" ' . ( $multi ? '' : 'id="jj" ' ) . 'name="jj" value="' . $jj . '" size="2" maxlength="2"' . $tab_index_attribute . ' autocomplete="off" />';
   740 	$day = '<label><span class="screen-reader-text">' . __( 'Day' ) . '</span><input type="text" ' . ( $multi ? '' : 'id="jj" ' ) . 'name="jj" value="' . $jj . '" size="2" maxlength="2"' . $tab_index_attribute . ' autocomplete="off" /></label>';
   785 	$year = '<label for="aa" class="screen-reader-text">' . __( 'Year' ) . '</label><input type="text" ' . ( $multi ? '' : 'id="aa" ' ) . 'name="aa" value="' . $aa . '" size="4" maxlength="4"' . $tab_index_attribute . ' autocomplete="off" />';
   741 	$year = '<label><span class="screen-reader-text">' . __( 'Year' ) . '</span><input type="text" ' . ( $multi ? '' : 'id="aa" ' ) . 'name="aa" value="' . $aa . '" size="4" maxlength="4"' . $tab_index_attribute . ' autocomplete="off" /></label>';
   786 	$hour = '<label for="hh" class="screen-reader-text">' . __( 'Hour' ) . '</label><input type="text" ' . ( $multi ? '' : 'id="hh" ' ) . 'name="hh" value="' . $hh . '" size="2" maxlength="2"' . $tab_index_attribute . ' autocomplete="off" />';
   742 	$hour = '<label><span class="screen-reader-text">' . __( 'Hour' ) . '</span><input type="text" ' . ( $multi ? '' : 'id="hh" ' ) . 'name="hh" value="' . $hh . '" size="2" maxlength="2"' . $tab_index_attribute . ' autocomplete="off" /></label>';
   787 	$minute = '<label for="mn" class="screen-reader-text">' . __( 'Minute' ) . '</label><input type="text" ' . ( $multi ? '' : 'id="mn" ' ) . 'name="mn" value="' . $mn . '" size="2" maxlength="2"' . $tab_index_attribute . ' autocomplete="off" />';
   743 	$minute = '<label><span class="screen-reader-text">' . __( 'Minute' ) . '</span><input type="text" ' . ( $multi ? '' : 'id="mn" ' ) . 'name="mn" value="' . $mn . '" size="2" maxlength="2"' . $tab_index_attribute . ' autocomplete="off" /></label>';
   788 
   744 
   789 	echo '<div class="timestamp-wrap">';
   745 	echo '<div class="timestamp-wrap">';
   790 	/* translators: 1: month, 2: day, 3: year, 4: hour, 5: minute */
   746 	/* translators: 1: month, 2: day, 3: year, 4: hour, 5: minute */
   791 	printf( __( '%1$s %2$s, %3$s @ %4$s : %5$s' ), $month, $day, $year, $hour, $minute );
   747 	printf( __( '%1$s %2$s, %3$s @ %4$s:%5$s' ), $month, $day, $year, $hour, $minute );
   792 
   748 
   793 	echo '</div><input type="hidden" id="ss" name="ss" value="' . $ss . '" />';
   749 	echo '</div><input type="hidden" id="ss" name="ss" value="' . $ss . '" />';
   794 
   750 
   795 	if ( $multi ) return;
   751 	if ( $multi ) return;
   796 
   752 
   820 
   776 
   821 /**
   777 /**
   822  * Print out option HTML elements for the page templates drop-down.
   778  * Print out option HTML elements for the page templates drop-down.
   823  *
   779  *
   824  * @since 1.5.0
   780  * @since 1.5.0
   825  *
   781  * @since 4.7.0 Added the `$post_type` parameter.
   826  * @param string $default Optional. The template file name. Default empty.
   782  *
   827  */
   783  * @param string $default   Optional. The template file name. Default empty.
   828 function page_template_dropdown( $default = '' ) {
   784  * @param string $post_type Optional. Post type to get templates for. Default 'post'.
   829 	$templates = get_page_templates( get_post() );
   785  */
       
   786 function page_template_dropdown( $default = '', $post_type = 'page' ) {
       
   787 	$templates = get_page_templates( null, $post_type );
   830 	ksort( $templates );
   788 	ksort( $templates );
   831 	foreach ( array_keys( $templates ) as $template ) {
   789 	foreach ( array_keys( $templates ) as $template ) {
   832 		$selected = selected( $default, $templates[ $template ], false );
   790 		$selected = selected( $default, $templates[ $template ], false );
   833 		echo "\n\t<option value='" . $templates[ $template ] . "' $selected>$template</option>";
   791 		echo "\n\t<option value='" . esc_attr( $templates[ $template ] ) . "' $selected>" . esc_html( $template ) . "</option>";
   834 	}
   792 	}
   835 }
   793 }
   836 
   794 
   837 /**
   795 /**
   838  * Print out option HTML elements for the page parents drop-down.
   796  * Print out option HTML elements for the page parents drop-down.
   839  *
   797  *
   840  * @since 1.5.0
   798  * @since 1.5.0
   841  *
   799  * @since 4.4.0 `$post` argument was added.
   842  * @param int $default Optional. The default page ID to be pre-selected. Default 0.
   800  *
   843  * @param int $parent  Optional. The parent page ID. Default 0.
   801  * @global wpdb $wpdb WordPress database abstraction object.
   844  * @param int $level   Optional. Page depth level. Default 0.
   802  *
       
   803  * @param int         $default Optional. The default page ID to be pre-selected. Default 0.
       
   804  * @param int         $parent  Optional. The parent page ID. Default 0.
       
   805  * @param int         $level   Optional. Page depth level. Default 0.
       
   806  * @param int|WP_Post $post    Post ID or WP_Post object.
   845  *
   807  *
   846  * @return null|false Boolean False if page has no children, otherwise print out html elements
   808  * @return null|false Boolean False if page has no children, otherwise print out html elements
   847  */
   809  */
   848 function parent_dropdown( $default = 0, $parent = 0, $level = 0 ) {
   810 function parent_dropdown( $default = 0, $parent = 0, $level = 0, $post = null ) {
   849 	global $wpdb;
   811 	global $wpdb;
   850 	$post = get_post();
   812 	$post = get_post( $post );
   851 	$items = $wpdb->get_results( $wpdb->prepare("SELECT ID, post_parent, post_title FROM $wpdb->posts WHERE post_parent = %d AND post_type = 'page' ORDER BY menu_order", $parent) );
   813 	$items = $wpdb->get_results( $wpdb->prepare("SELECT ID, post_parent, post_title FROM $wpdb->posts WHERE post_parent = %d AND post_type = 'page' ORDER BY menu_order", $parent) );
   852 
   814 
   853 	if ( $items ) {
   815 	if ( $items ) {
   854 		foreach ( $items as $item ) {
   816 		foreach ( $items as $item ) {
   855 			// A page cannot be its own parent.
   817 			// A page cannot be its own parent.
   873  * @since 2.1.0
   835  * @since 2.1.0
   874  *
   836  *
   875  * @param string $selected Slug for the role that should be already selected.
   837  * @param string $selected Slug for the role that should be already selected.
   876  */
   838  */
   877 function wp_dropdown_roles( $selected = '' ) {
   839 function wp_dropdown_roles( $selected = '' ) {
   878 	$p = '';
       
   879 	$r = '';
   840 	$r = '';
   880 
   841 
   881 	$editable_roles = array_reverse( get_editable_roles() );
   842 	$editable_roles = array_reverse( get_editable_roles() );
   882 
   843 
   883 	foreach ( $editable_roles as $role => $details ) {
   844 	foreach ( $editable_roles as $role => $details ) {
   884 		$name = translate_user_role($details['name'] );
   845 		$name = translate_user_role($details['name'] );
   885 		if ( $selected == $role ) // preselect specified role
   846 		// preselect specified role
   886 			$p = "\n\t<option selected='selected' value='" . esc_attr($role) . "'>$name</option>";
   847 		if ( $selected == $role ) {
   887 		else
   848 			$r .= "\n\t<option selected='selected' value='" . esc_attr( $role ) . "'>$name</option>";
   888 			$r .= "\n\t<option value='" . esc_attr($role) . "'>$name</option>";
   849 		} else {
   889 	}
   850 			$r .= "\n\t<option value='" . esc_attr( $role ) . "'>$name</option>";
   890 	echo $p . $r;
   851 		}
       
   852 	}
       
   853 
       
   854 	echo $r;
   891 }
   855 }
   892 
   856 
   893 /**
   857 /**
   894  * Outputs the form used by the importers to accept the data to be imported
   858  * Outputs the form used by the importers to accept the data to be imported
   895  *
   859  *
   898  * @param string $action The action attribute for the form.
   862  * @param string $action The action attribute for the form.
   899  */
   863  */
   900 function wp_import_upload_form( $action ) {
   864 function wp_import_upload_form( $action ) {
   901 
   865 
   902 	/**
   866 	/**
   903 	 * Filter the maximum allowed upload size for import files.
   867 	 * Filters the maximum allowed upload size for import files.
   904 	 *
   868 	 *
   905 	 * @since 2.3.0
   869 	 * @since 2.3.0
   906 	 *
   870 	 *
   907 	 * @see wp_max_upload_size()
   871 	 * @see wp_max_upload_size()
   908 	 *
   872 	 *
   921 <label for="upload"><?php _e( 'Choose a file from your computer:' ); ?></label> (<?php printf( __('Maximum size: %s' ), $size ); ?>)
   885 <label for="upload"><?php _e( 'Choose a file from your computer:' ); ?></label> (<?php printf( __('Maximum size: %s' ), $size ); ?>)
   922 <input type="file" id="upload" name="import" size="25" />
   886 <input type="file" id="upload" name="import" size="25" />
   923 <input type="hidden" name="action" value="save" />
   887 <input type="hidden" name="action" value="save" />
   924 <input type="hidden" name="max_file_size" value="<?php echo $bytes; ?>" />
   888 <input type="hidden" name="max_file_size" value="<?php echo $bytes; ?>" />
   925 </p>
   889 </p>
   926 <?php submit_button( __('Upload file and import'), 'button' ); ?>
   890 <?php submit_button( __('Upload file and import'), 'primary' ); ?>
   927 </form>
   891 </form>
   928 <?php
   892 <?php
   929 	endif;
   893 	endif;
   930 }
   894 }
   931 
   895 
   932 /**
   896 /**
   933  * Add a meta box to an edit form.
   897  * Adds a meta box to one or more screens.
   934  *
   898  *
   935  * @since 2.5.0
   899  * @since 2.5.0
   936  *
   900  * @since 4.4.0 The `$screen` parameter now accepts an array of screen IDs.
   937  * @param string           $id            String for use in the 'id' attribute of tags.
   901  *
   938  * @param string           $title         Title of the meta box.
   902  * @global array $wp_meta_boxes
   939  * @param callback         $callback      Function that fills the box with the desired content.
   903  *
   940  *                                        The function should echo its output.
   904  * @param string                 $id            Meta box ID (used in the 'id' attribute for the meta box).
   941  * @param string|WP_Screen $screen        Optional. The screen on which to show the box (like a post
   905  * @param string                 $title         Title of the meta box.
   942  *                                        type, 'link', or 'comment'). Default is the current screen.
   906  * @param callable               $callback      Function that fills the box with the desired content.
   943  * @param string           $context       Optional. The context within the screen where the boxes
   907  *                                              The function should echo its output.
   944  *                                        should display. Available contexts vary from screen to
   908  * @param string|array|WP_Screen $screen        Optional. The screen or screens on which to show the box
   945  *                                        screen. Post edit screen contexts include 'normal', 'side',
   909  *                                              (such as a post type, 'link', or 'comment'). Accepts a single
   946  *                                        and 'advanced'. Comments screen contexts include 'normal'
   910  *                                              screen ID, WP_Screen object, or array of screen IDs. Default
   947  *                                        and 'side'. Menus meta boxes (accordion sections) all use
   911  *                                              is the current screen.  If you have used add_menu_page() or
   948  *                                        the 'side' context. Global default is 'advanced'.
   912  *                                              add_submenu_page() to create a new screen (and hence screen_id),
   949  * @param string           $priority      Optional. The priority within the context where the boxes
   913  *                                              make sure your menu slug conforms to the limits of sanitize_key()
   950  *                                        should show ('high', 'low'). Default 'default'.
   914  *                                              otherwise the 'screen' menu may not correctly render on your page.
   951  * @param array            $callback_args Optional. Data that should be set as the $args property
   915  * @param string                 $context       Optional. The context within the screen where the boxes
   952  *                                        of the box array (which is the second parameter passed
   916  *                                              should display. Available contexts vary from screen to
   953  *                                        to your callback). Default null.
   917  *                                              screen. Post edit screen contexts include 'normal', 'side',
       
   918  *                                              and 'advanced'. Comments screen contexts include 'normal'
       
   919  *                                              and 'side'. Menus meta boxes (accordion sections) all use
       
   920  *                                              the 'side' context. Global default is 'advanced'.
       
   921  * @param string                 $priority      Optional. The priority within the context where the boxes
       
   922  *                                              should show ('high', 'low'). Default 'default'.
       
   923  * @param array                  $callback_args Optional. Data that should be set as the $args property
       
   924  *                                              of the box array (which is the second parameter passed
       
   925  *                                              to your callback). Default null.
   954  */
   926  */
   955 function add_meta_box( $id, $title, $callback, $screen = null, $context = 'advanced', $priority = 'default', $callback_args = null ) {
   927 function add_meta_box( $id, $title, $callback, $screen = null, $context = 'advanced', $priority = 'default', $callback_args = null ) {
   956 	global $wp_meta_boxes;
   928 	global $wp_meta_boxes;
   957 
   929 
   958 	if ( empty( $screen ) )
   930 	if ( empty( $screen ) ) {
   959 		$screen = get_current_screen();
   931 		$screen = get_current_screen();
   960 	elseif ( is_string( $screen ) )
   932 	} elseif ( is_string( $screen ) ) {
   961 		$screen = convert_to_screen( $screen );
   933 		$screen = convert_to_screen( $screen );
       
   934 	} elseif ( is_array( $screen ) ) {
       
   935 		foreach ( $screen as $single_screen ) {
       
   936 			add_meta_box( $id, $title, $callback, $single_screen, $context, $priority, $callback_args );
       
   937 		}
       
   938 	}
       
   939 
       
   940 	if ( ! isset( $screen->id ) ) {
       
   941 		return;
       
   942 	}
   962 
   943 
   963 	$page = $screen->id;
   944 	$page = $screen->id;
   964 
   945 
   965 	if ( !isset($wp_meta_boxes) )
   946 	if ( !isset($wp_meta_boxes) )
   966 		$wp_meta_boxes = array();
   947 		$wp_meta_boxes = array();
  1020 /**
  1001 /**
  1021  * Meta-Box template function
  1002  * Meta-Box template function
  1022  *
  1003  *
  1023  * @since 2.5.0
  1004  * @since 2.5.0
  1024  *
  1005  *
       
  1006  * @global array $wp_meta_boxes
       
  1007  *
  1025  * @staticvar bool $already_sorted
  1008  * @staticvar bool $already_sorted
  1026  * @param string|WP_Screen $screen Screen identifier
  1009  *
  1027  * @param string $context box context
  1010  * @param string|WP_Screen $screen  Screen identifier. If you have used add_menu_page() or
  1028  * @param mixed $object gets passed to the box callback function as first parameter
  1011  *                                  add_submenu_page() to create a new screen (and hence screen_id)
       
  1012  *                                  make sure your menu slug conforms to the limits of sanitize_key()
       
  1013  *                                  otherwise the 'screen' menu may not correctly render on your page.
       
  1014  * @param string           $context box context
       
  1015  * @param mixed            $object  gets passed to the box callback function as first parameter
  1029  * @return int number of meta_boxes
  1016  * @return int number of meta_boxes
  1030  */
  1017  */
  1031 function do_meta_boxes( $screen, $context, $object ) {
  1018 function do_meta_boxes( $screen, $context, $object ) {
  1032 	global $wp_meta_boxes;
  1019 	global $wp_meta_boxes;
  1033 	static $already_sorted = false;
  1020 	static $already_sorted = false;
  1039 
  1026 
  1040 	$page = $screen->id;
  1027 	$page = $screen->id;
  1041 
  1028 
  1042 	$hidden = get_hidden_meta_boxes( $screen );
  1029 	$hidden = get_hidden_meta_boxes( $screen );
  1043 
  1030 
  1044 	printf('<div id="%s-sortables" class="meta-box-sortables">', htmlspecialchars($context));
  1031 	printf( '<div id="%s-sortables" class="meta-box-sortables">', esc_attr( $context ) );
  1045 
  1032 
  1046 	// Grab the ones the user has manually sorted. Pull them out of their previous context/priority and into the one the user chose
  1033 	// Grab the ones the user has manually sorted. Pull them out of their previous context/priority and into the one the user chose
  1047 	if ( ! $already_sorted && $sorted = get_user_option( "meta-box-order_$page" ) ) {
  1034 	if ( ! $already_sorted && $sorted = get_user_option( "meta-box-order_$page" ) ) {
  1048 		foreach ( $sorted as $box_context => $ids ) {
  1035 		foreach ( $sorted as $box_context => $ids ) {
  1049 			foreach ( explode( ',', $ids ) as $id ) {
  1036 			foreach ( explode( ',', $ids ) as $id ) {
  1065 					if ( false == $box || ! $box['title'] )
  1052 					if ( false == $box || ! $box['title'] )
  1066 						continue;
  1053 						continue;
  1067 					$i++;
  1054 					$i++;
  1068 					$hidden_class = in_array($box['id'], $hidden) ? ' hide-if-js' : '';
  1055 					$hidden_class = in_array($box['id'], $hidden) ? ' hide-if-js' : '';
  1069 					echo '<div id="' . $box['id'] . '" class="postbox ' . postbox_classes($box['id'], $page) . $hidden_class . '" ' . '>' . "\n";
  1056 					echo '<div id="' . $box['id'] . '" class="postbox ' . postbox_classes($box['id'], $page) . $hidden_class . '" ' . '>' . "\n";
  1070 					if ( 'dashboard_browser_nag' != $box['id'] )
  1057 					if ( 'dashboard_browser_nag' != $box['id'] ) {
  1071 						echo '<div class="handlediv" title="' . esc_attr__('Click to toggle') . '"><br /></div>';
  1058 						$widget_title = $box[ 'title' ];
  1072 					echo "<h3 class='hndle'><span>{$box['title']}</span></h3>\n";
  1059 
       
  1060 						if ( is_array( $box[ 'args' ] ) && isset( $box[ 'args' ][ '__widget_basename' ] ) ) {
       
  1061 							$widget_title = $box[ 'args' ][ '__widget_basename' ];
       
  1062 							// Do not pass this parameter to the user callback function.
       
  1063 							unset( $box[ 'args' ][ '__widget_basename' ] );
       
  1064 						}
       
  1065 
       
  1066 						echo '<button type="button" class="handlediv" aria-expanded="true">';
       
  1067 						echo '<span class="screen-reader-text">' . sprintf( __( 'Toggle panel: %s' ), $widget_title ) . '</span>';
       
  1068 						echo '<span class="toggle-indicator" aria-hidden="true"></span>';
       
  1069 						echo '</button>';
       
  1070 					}
       
  1071 					echo "<h2 class='hndle'><span>{$box['title']}</span></h2>\n";
  1073 					echo '<div class="inside">' . "\n";
  1072 					echo '<div class="inside">' . "\n";
  1074 					call_user_func($box['callback'], $object, $box);
  1073 					call_user_func($box['callback'], $object, $box);
  1075 					echo "</div>\n";
  1074 					echo "</div>\n";
  1076 					echo "</div>\n";
  1075 					echo "</div>\n";
  1077 				}
  1076 				}
  1084 	return $i;
  1083 	return $i;
  1085 
  1084 
  1086 }
  1085 }
  1087 
  1086 
  1088 /**
  1087 /**
  1089  * Remove a meta box from an edit form.
  1088  * Removes a meta box from one or more screens.
  1090  *
  1089  *
  1091  * @since 2.6.0
  1090  * @since 2.6.0
  1092  *
  1091  * @since 4.4.0 The `$screen` parameter now accepts an array of screen IDs.
  1093  * @param string $id String for use in the 'id' attribute of tags.
  1092  *
  1094  * @param string|object $screen The screen on which to show the box (post, page, link).
  1093  * @global array $wp_meta_boxes
  1095  * @param string $context The context within the page where the boxes should show ('normal', 'advanced').
  1094  *
  1096  */
  1095  * @param string                 $id      Meta box ID (used in the 'id' attribute for the meta box).
  1097 function remove_meta_box($id, $screen, $context) {
  1096  * @param string|array|WP_Screen $screen  The screen or screens on which the meta box is shown (such as a
       
  1097  *                                        post type, 'link', or 'comment'). Accepts a single screen ID,
       
  1098  *                                        WP_Screen object, or array of screen IDs.
       
  1099  * @param string                 $context The context within the screen where the box is set to display.
       
  1100  *                                        Contexts vary from screen to screen. Post edit screen contexts
       
  1101  *                                        include 'normal', 'side', and 'advanced'. Comments screen contexts
       
  1102  *                                        include 'normal' and 'side'. Menus meta boxes (accordion sections)
       
  1103  *                                        all use the 'side' context.
       
  1104  */
       
  1105 function remove_meta_box( $id, $screen, $context ) {
  1098 	global $wp_meta_boxes;
  1106 	global $wp_meta_boxes;
  1099 
  1107 
  1100 	if ( empty( $screen ) )
  1108 	if ( empty( $screen ) ) {
  1101 		$screen = get_current_screen();
  1109 		$screen = get_current_screen();
  1102 	elseif ( is_string( $screen ) )
  1110 	} elseif ( is_string( $screen ) ) {
  1103 		$screen = convert_to_screen( $screen );
  1111 		$screen = convert_to_screen( $screen );
       
  1112 	} elseif ( is_array( $screen ) ) {
       
  1113 		foreach ( $screen as $single_screen ) {
       
  1114 			remove_meta_box( $id, $single_screen, $context );
       
  1115 		}
       
  1116 	}
       
  1117 
       
  1118 	if ( ! isset( $screen->id ) ) {
       
  1119 		return;
       
  1120 	}
  1104 
  1121 
  1105 	$page = $screen->id;
  1122 	$page = $screen->id;
  1106 
  1123 
  1107 	if ( !isset($wp_meta_boxes) )
  1124 	if ( !isset($wp_meta_boxes) )
  1108 		$wp_meta_boxes = array();
  1125 		$wp_meta_boxes = array();
  1116 }
  1133 }
  1117 
  1134 
  1118 /**
  1135 /**
  1119  * Meta Box Accordion Template Function
  1136  * Meta Box Accordion Template Function
  1120  *
  1137  *
  1121  * Largely made up of abstracted code from {@link do_meta_boxes()}, this
  1138  * Largely made up of abstracted code from do_meta_boxes(), this
  1122  * function serves to build meta boxes as list items for display as
  1139  * function serves to build meta boxes as list items for display as
  1123  * a collapsible accordion.
  1140  * a collapsible accordion.
  1124  *
  1141  *
  1125  * @since 3.6.0
  1142  * @since 3.6.0
  1126  *
  1143  *
  1127  * @uses global $wp_meta_boxes Used to retrieve registered meta boxes.
  1144  * @uses global $wp_meta_boxes Used to retrieve registered meta boxes.
  1128  *
  1145  *
  1129  * @param string|object $screen The screen identifier.
  1146  * @param string|object $screen  The screen identifier.
  1130  * @param string $context The meta box context.
  1147  * @param string        $context The meta box context.
  1131  * @param mixed $object gets passed to the section callback function as first parameter.
  1148  * @param mixed         $object  gets passed to the section callback function as first parameter.
  1132  * @return int number of meta boxes as accordion sections.
  1149  * @return int number of meta boxes as accordion sections.
  1133  */
  1150  */
  1134 function do_accordion_sections( $screen, $context, $object ) {
  1151 function do_accordion_sections( $screen, $context, $object ) {
  1135 	global $wp_meta_boxes;
  1152 	global $wp_meta_boxes;
  1136 
  1153 
  1167 					}
  1184 					}
  1168 					?>
  1185 					?>
  1169 					<li class="control-section accordion-section <?php echo $hidden_class; ?> <?php echo $open_class; ?> <?php echo esc_attr( $box['id'] ); ?>" id="<?php echo esc_attr( $box['id'] ); ?>">
  1186 					<li class="control-section accordion-section <?php echo $hidden_class; ?> <?php echo $open_class; ?> <?php echo esc_attr( $box['id'] ); ?>" id="<?php echo esc_attr( $box['id'] ); ?>">
  1170 						<h3 class="accordion-section-title hndle" tabindex="0">
  1187 						<h3 class="accordion-section-title hndle" tabindex="0">
  1171 							<?php echo esc_html( $box['title'] ); ?>
  1188 							<?php echo esc_html( $box['title'] ); ?>
  1172 							<span class="screen-reader-text"><?php _e( 'Press return or enter to expand' ); ?></span>
  1189 							<span class="screen-reader-text"><?php _e( 'Press return or enter to open this section' ); ?></span>
  1173 						</h3>
  1190 						</h3>
  1174 						<div class="accordion-section-content <?php postbox_classes( $box['id'], $page ); ?>">
  1191 						<div class="accordion-section-content <?php postbox_classes( $box['id'], $page ); ?>">
  1175 							<div class="inside">
  1192 							<div class="inside">
  1176 								<?php call_user_func( $box['callback'], $object, $box ); ?>
  1193 								<?php call_user_func( $box['callback'], $object, $box ); ?>
  1177 							</div><!-- .inside -->
  1194 							</div><!-- .inside -->
  1202  *
  1219  *
  1203  * @since 2.7.0
  1220  * @since 2.7.0
  1204  *
  1221  *
  1205  * @global $wp_settings_sections Storage array of all settings sections added to admin pages
  1222  * @global $wp_settings_sections Storage array of all settings sections added to admin pages
  1206  *
  1223  *
  1207  * @param string $id Slug-name to identify the section. Used in the 'id' attribute of tags.
  1224  * @param string   $id       Slug-name to identify the section. Used in the 'id' attribute of tags.
  1208  * @param string $title Formatted title of the section. Shown as the heading for the section.
  1225  * @param string   $title    Formatted title of the section. Shown as the heading for the section.
  1209  * @param string $callback Function that echos out any content at the top of the section (between heading and fields).
  1226  * @param callable $callback Function that echos out any content at the top of the section (between heading and fields).
  1210  * @param string $page The slug-name of the settings page on which to show the section. Built-in pages include 'general', 'reading', 'writing', 'discussion', 'media', etc. Create your own using add_options_page();
  1227  * @param string   $page     The slug-name of the settings page on which to show the section. Built-in pages include
       
  1228  *                           'general', 'reading', 'writing', 'discussion', 'media', etc. Create your own using
       
  1229  *                           add_options_page();
  1211  */
  1230  */
  1212 function add_settings_section($id, $title, $callback, $page) {
  1231 function add_settings_section($id, $title, $callback, $page) {
  1213 	global $wp_settings_sections;
  1232 	global $wp_settings_sections;
  1214 
  1233 
  1215 	if ( 'misc' == $page ) {
  1234 	if ( 'misc' == $page ) {
  1216 		_deprecated_argument( __FUNCTION__, '3.0', sprintf( __( 'The "%s" options group has been removed. Use another settings group.' ), 'misc' ) );
  1235 		_deprecated_argument( __FUNCTION__, '3.0.0',
       
  1236 			/* translators: %s: misc */
       
  1237 			sprintf( __( 'The "%s" options group has been removed. Use another settings group.' ),
       
  1238 				'misc'
       
  1239 			)
       
  1240 		);
  1217 		$page = 'general';
  1241 		$page = 'general';
  1218 	}
  1242 	}
  1219 
  1243 
  1220 	if ( 'privacy' == $page ) {
  1244 	if ( 'privacy' == $page ) {
  1221 		_deprecated_argument( __FUNCTION__, '3.5', sprintf( __( 'The "%s" options group has been removed. Use another settings group.' ), 'privacy' ) );
  1245 		_deprecated_argument( __FUNCTION__, '3.5.0',
       
  1246 			/* translators: %s: privacy */
       
  1247 			sprintf( __( 'The "%s" options group has been removed. Use another settings group.' ),
       
  1248 				'privacy'
       
  1249 			)
       
  1250 		);
  1222 		$page = 'reading';
  1251 		$page = 'reading';
  1223 	}
  1252 	}
  1224 
  1253 
  1225 	$wp_settings_sections[$page][$id] = array('id' => $id, 'title' => $title, 'callback' => $callback);
  1254 	$wp_settings_sections[$page][$id] = array('id' => $id, 'title' => $title, 'callback' => $callback);
  1226 }
  1255 }
  1239  * @since 2.7.0
  1268  * @since 2.7.0
  1240  * @since 4.2.0 The `$class` argument was added.
  1269  * @since 4.2.0 The `$class` argument was added.
  1241  *
  1270  *
  1242  * @global $wp_settings_fields Storage array of settings fields and info about their pages/sections
  1271  * @global $wp_settings_fields Storage array of settings fields and info about their pages/sections
  1243  *
  1272  *
  1244  * @param string $id       Slug-name to identify the field. Used in the 'id' attribute of tags.
  1273  * @param string   $id       Slug-name to identify the field. Used in the 'id' attribute of tags.
  1245  * @param string $title    Formatted title of the field. Shown as the label for the field
  1274  * @param string   $title    Formatted title of the field. Shown as the label for the field
  1246  *                         during output.
  1275  *                           during output.
  1247  * @param string $callback Function that fills the field with the desired form inputs. The
  1276  * @param callable $callback Function that fills the field with the desired form inputs. The
  1248  *                         function should echo its output.
  1277  *                           function should echo its output.
  1249  * @param string $page     The slug-name of the settings page on which to show the section
  1278  * @param string   $page     The slug-name of the settings page on which to show the section
  1250  *                         (general, reading, writing, ...).
  1279  *                           (general, reading, writing, ...).
  1251  * @param string $section  Optional. The slug-name of the section of the settings page
  1280  * @param string   $section  Optional. The slug-name of the section of the settings page
  1252  *                         in which to show the box. Default 'default'.
  1281  *                           in which to show the box. Default 'default'.
  1253  * @param array  $args {
  1282  * @param array    $args {
  1254  *     Optional. Extra arguments used when outputting the field.
  1283  *     Optional. Extra arguments used when outputting the field.
  1255  *
  1284  *
  1256  *     @type string $label_for When supplied, the setting title will be wrapped
  1285  *     @type string $label_for When supplied, the setting title will be wrapped
  1257  *                             in a `<label>` element, its `for` attribute populated
  1286  *                             in a `<label>` element, its `for` attribute populated
  1258  *                             with this value.
  1287  *                             with this value.
  1262  */
  1291  */
  1263 function add_settings_field($id, $title, $callback, $page, $section = 'default', $args = array()) {
  1292 function add_settings_field($id, $title, $callback, $page, $section = 'default', $args = array()) {
  1264 	global $wp_settings_fields;
  1293 	global $wp_settings_fields;
  1265 
  1294 
  1266 	if ( 'misc' == $page ) {
  1295 	if ( 'misc' == $page ) {
  1267 		_deprecated_argument( __FUNCTION__, '3.0', __( 'The miscellaneous options group has been removed. Use another settings group.' ) );
  1296 		_deprecated_argument( __FUNCTION__, '3.0.0',
       
  1297 			/* translators: %s: misc */
       
  1298 			sprintf( __( 'The "%s" options group has been removed. Use another settings group.' ),
       
  1299 				'misc'
       
  1300 			)
       
  1301 		);
  1268 		$page = 'general';
  1302 		$page = 'general';
  1269 	}
  1303 	}
  1270 
  1304 
  1271 	if ( 'privacy' == $page ) {
  1305 	if ( 'privacy' == $page ) {
  1272 		_deprecated_argument( __FUNCTION__, '3.5', __( 'The privacy options group has been removed. Use another settings group.' ) );
  1306 		_deprecated_argument( __FUNCTION__, '3.5.0',
       
  1307 			/* translators: %s: privacy */
       
  1308 			sprintf( __( 'The "%s" options group has been removed. Use another settings group.' ),
       
  1309 				'privacy'
       
  1310 			)
       
  1311 		);
  1273 		$page = 'reading';
  1312 		$page = 'reading';
  1274 	}
  1313 	}
  1275 
  1314 
  1276 	$wp_settings_fields[$page][$section][$id] = array('id' => $id, 'title' => $title, 'callback' => $callback, 'args' => $args);
  1315 	$wp_settings_fields[$page][$section][$id] = array('id' => $id, 'title' => $title, 'callback' => $callback, 'args' => $args);
  1277 }
  1316 }
  1285  *
  1324  *
  1286  * @global $wp_settings_sections Storage array of all settings sections added to admin pages
  1325  * @global $wp_settings_sections Storage array of all settings sections added to admin pages
  1287  * @global $wp_settings_fields Storage array of settings fields and info about their pages/sections
  1326  * @global $wp_settings_fields Storage array of settings fields and info about their pages/sections
  1288  * @since 2.7.0
  1327  * @since 2.7.0
  1289  *
  1328  *
  1290  * @param string $page The slug name of the page whos settings sections you want to output
  1329  * @param string $page The slug name of the page whose settings sections you want to output
  1291  */
  1330  */
  1292 function do_settings_sections( $page ) {
  1331 function do_settings_sections( $page ) {
  1293 	global $wp_settings_sections, $wp_settings_fields;
  1332 	global $wp_settings_sections, $wp_settings_fields;
  1294 
  1333 
  1295 	if ( ! isset( $wp_settings_sections[$page] ) )
  1334 	if ( ! isset( $wp_settings_sections[$page] ) )
  1296 		return;
  1335 		return;
  1297 
  1336 
  1298 	foreach ( (array) $wp_settings_sections[$page] as $section ) {
  1337 	foreach ( (array) $wp_settings_sections[$page] as $section ) {
  1299 		if ( $section['title'] )
  1338 		if ( $section['title'] )
  1300 			echo "<h3>{$section['title']}</h3>\n";
  1339 			echo "<h2>{$section['title']}</h2>\n";
  1301 
  1340 
  1302 		if ( $section['callback'] )
  1341 		if ( $section['callback'] )
  1303 			call_user_func( $section['callback'], $section );
  1342 			call_user_func( $section['callback'], $section );
  1304 
  1343 
  1305 		if ( ! isset( $wp_settings_fields ) || !isset( $wp_settings_fields[$page] ) || !isset( $wp_settings_fields[$page][$section['id']] ) )
  1344 		if ( ! isset( $wp_settings_fields ) || !isset( $wp_settings_fields[$page] ) || !isset( $wp_settings_fields[$page][$section['id']] ) )
  1397  * to the 'settings_errors' transient then those errors will be returned instead. This
  1436  * to the 'settings_errors' transient then those errors will be returned instead. This
  1398  * is used to pass errors back across pageloads.
  1437  * is used to pass errors back across pageloads.
  1399  *
  1438  *
  1400  * Use the $sanitize argument to manually re-sanitize the option before returning errors.
  1439  * Use the $sanitize argument to manually re-sanitize the option before returning errors.
  1401  * This is useful if you have errors or notices you want to show even when the user
  1440  * This is useful if you have errors or notices you want to show even when the user
  1402  * hasn't submitted data (i.e. when they first load an options page, or in admin_notices action hook)
  1441  * hasn't submitted data (i.e. when they first load an options page, or in the {@see 'admin_notices'}
       
  1442  * action hook).
  1403  *
  1443  *
  1404  * @since 3.0.0
  1444  * @since 3.0.0
  1405  *
  1445  *
  1406  * @global array $wp_settings_errors Storage array of errors registered during this pageload
  1446  * @global array $wp_settings_errors Storage array of errors registered during this pageload
  1407  *
  1447  *
  1425 		$wp_settings_errors = array_merge( (array) $wp_settings_errors, get_transient( 'settings_errors' ) );
  1465 		$wp_settings_errors = array_merge( (array) $wp_settings_errors, get_transient( 'settings_errors' ) );
  1426 		delete_transient( 'settings_errors' );
  1466 		delete_transient( 'settings_errors' );
  1427 	}
  1467 	}
  1428 
  1468 
  1429 	// Check global in case errors have been added on this pageload.
  1469 	// Check global in case errors have been added on this pageload.
  1430 	if ( ! count( $wp_settings_errors ) )
  1470 	if ( empty( $wp_settings_errors ) ) {
  1431 		return array();
  1471 		return array();
       
  1472 	}
  1432 
  1473 
  1433 	// Filter the results to those of a specific setting if one was set.
  1474 	// Filter the results to those of a specific setting if one was set.
  1434 	if ( $setting ) {
  1475 	if ( $setting ) {
  1435 		$setting_errors = array();
  1476 		$setting_errors = array();
  1436 		foreach ( (array) $wp_settings_errors as $key => $details ) {
  1477 		foreach ( (array) $wp_settings_errors as $key => $details ) {
  1442 
  1483 
  1443 	return $wp_settings_errors;
  1484 	return $wp_settings_errors;
  1444 }
  1485 }
  1445 
  1486 
  1446 /**
  1487 /**
  1447  * Display settings errors registered by {@see add_settings_error()}.
  1488  * Display settings errors registered by add_settings_error().
  1448  *
  1489  *
  1449  * Part of the Settings API. Outputs a div for each error retrieved by
  1490  * Part of the Settings API. Outputs a div for each error retrieved by
  1450  * {@see get_settings_errors()}.
  1491  * get_settings_errors().
  1451  *
  1492  *
  1452  * This is called automatically after a settings page based on the
  1493  * This is called automatically after a settings page based on the
  1453  * Settings API is submitted. Errors should be added during the validation
  1494  * Settings API is submitted. Errors should be added during the validation
  1454  * callback function for a setting defined in {@see register_setting()}
  1495  * callback function for a setting defined in register_setting().
  1455  *
  1496  *
  1456  * The $sanitize option is passed into {@see get_settings_errors()} and will
  1497  * The $sanitize option is passed into get_settings_errors() and will
  1457  * re-run the setting sanitization
  1498  * re-run the setting sanitization
  1458  * on its current value.
  1499  * on its current value.
  1459  *
  1500  *
  1460  * The $hide_on_update option will cause errors to only show when the settings
  1501  * The $hide_on_update option will cause errors to only show when the settings
  1461  * page is first loaded. if the user has already saved new values it will be
  1502  * page is first loaded. if the user has already saved new values it will be
  1463  * reporting after submission. This is useful to show general errors like
  1504  * reporting after submission. This is useful to show general errors like
  1464  * missing settings when the user arrives at the settings page.
  1505  * missing settings when the user arrives at the settings page.
  1465  *
  1506  *
  1466  * @since 3.0.0
  1507  * @since 3.0.0
  1467  *
  1508  *
  1468  * @param string $setting Optional slug title of a specific setting who's errors you want.
  1509  * @param string $setting        Optional slug title of a specific setting who's errors you want.
  1469  * @param boolean $sanitize Whether to re-sanitize the setting value before returning errors.
  1510  * @param bool   $sanitize       Whether to re-sanitize the setting value before returning errors.
  1470  * @param boolean $hide_on_update If set to true errors will not be shown if the settings page has already been submitted.
  1511  * @param bool   $hide_on_update If set to true errors will not be shown if the settings page has
       
  1512  *                               already been submitted.
  1471  */
  1513  */
  1472 function settings_errors( $setting = '', $sanitize = false, $hide_on_update = false ) {
  1514 function settings_errors( $setting = '', $sanitize = false, $hide_on_update = false ) {
  1473 
  1515 
  1474 	if ( $hide_on_update && ! empty( $_GET['settings-updated'] ) )
  1516 	if ( $hide_on_update && ! empty( $_GET['settings-updated'] ) )
  1475 		return;
  1517 		return;
  1489 	}
  1531 	}
  1490 	echo $output;
  1532 	echo $output;
  1491 }
  1533 }
  1492 
  1534 
  1493 /**
  1535 /**
  1494  * {@internal Missing Short Description}}
  1536  * Outputs the modal window used for attaching media to posts or pages in the media-listing screen.
  1495  *
  1537  *
  1496  * @since 2.7.0
  1538  * @since 2.7.0
  1497  *
  1539  *
  1498  * @param string $found_action
  1540  * @param string $found_action
  1499  */
  1541  */
  1500 function find_posts_div($found_action = '') {
  1542 function find_posts_div($found_action = '') {
  1501 ?>
  1543 ?>
  1502 	<div id="find-posts" class="find-box" style="display: none;">
  1544 	<div id="find-posts" class="find-box" style="display: none;">
  1503 		<div id="find-posts-head" class="find-box-head">
  1545 		<div id="find-posts-head" class="find-box-head">
  1504 			<?php _e( 'Find Posts or Pages' ); ?>
  1546 			<?php _e( 'Attach to existing content' ); ?>
  1505 			<div id="find-posts-close"></div>
  1547 			<button type="button" id="find-posts-close"><span class="screen-reader-text"><?php _e( 'Close media attachment panel' ); ?></span></button>
  1506 		</div>
  1548 		</div>
  1507 		<div class="find-box-inside">
  1549 		<div class="find-box-inside">
  1508 			<div class="find-box-search">
  1550 			<div class="find-box-search">
  1509 				<?php if ( $found_action ) { ?>
  1551 				<?php if ( $found_action ) { ?>
  1510 					<input type="hidden" name="found_action" value="<?php echo esc_attr($found_action); ?>" />
  1552 					<input type="hidden" name="found_action" value="<?php echo esc_attr($found_action); ?>" />
  1518 				<div class="clear"></div>
  1560 				<div class="clear"></div>
  1519 			</div>
  1561 			</div>
  1520 			<div id="find-posts-response"></div>
  1562 			<div id="find-posts-response"></div>
  1521 		</div>
  1563 		</div>
  1522 		<div class="find-box-buttons">
  1564 		<div class="find-box-buttons">
  1523 			<?php submit_button( __( 'Select' ), 'button-primary alignright', 'find-posts-submit', false ); ?>
  1565 			<?php submit_button( __( 'Select' ), 'primary alignright', 'find-posts-submit', false ); ?>
  1524 			<div class="clear"></div>
  1566 			<div class="clear"></div>
  1525 		</div>
  1567 		</div>
  1526 	</div>
  1568 	</div>
  1527 <?php
  1569 <?php
  1528 }
  1570 }
  1529 
  1571 
  1530 /**
  1572 /**
  1531  * Display the post password.
  1573  * Displays the post password.
  1532  *
  1574  *
  1533  * The password is passed through {@link esc_attr()} to ensure that it
  1575  * The password is passed through esc_attr() to ensure that it is safe for placing in an html attribute.
  1534  * is safe for placing in an html attribute.
       
  1535  *
  1576  *
  1536  * @since 2.7.0
  1577  * @since 2.7.0
  1537  */
  1578  */
  1538 function the_post_password() {
  1579 function the_post_password() {
  1539 	$post = get_post();
  1580 	$post = get_post();
  1558 		$title = __( '(no title)' );
  1599 		$title = __( '(no title)' );
  1559 	return esc_html( $title );
  1600 	return esc_html( $title );
  1560 }
  1601 }
  1561 
  1602 
  1562 /**
  1603 /**
  1563  * Display the search query.
  1604  * Displays the search query.
  1564  *
  1605  *
  1565  * A simple wrapper to display the "s" parameter in a GET URI. This function
  1606  * A simple wrapper to display the "s" parameter in a `GET` URI. This function
  1566  * should only be used when {@link the_search_query()} cannot.
  1607  * should only be used when the_search_query() cannot.
  1567  *
  1608  *
  1568  * @since 2.7.0
  1609  * @since 2.7.0
  1569  */
  1610  */
  1570 function _admin_search_query() {
  1611 function _admin_search_query() {
  1571 	echo isset($_REQUEST['s']) ? esc_attr( wp_unslash( $_REQUEST['s'] ) ) : '';
  1612 	echo isset($_REQUEST['s']) ? esc_attr( wp_unslash( $_REQUEST['s'] ) ) : '';
  1573 
  1614 
  1574 /**
  1615 /**
  1575  * Generic Iframe header for use with Thickbox
  1616  * Generic Iframe header for use with Thickbox
  1576  *
  1617  *
  1577  * @since 2.7.0
  1618  * @since 2.7.0
       
  1619  *
       
  1620  * @global string    $hook_suffix
       
  1621  * @global string    $admin_body_class
       
  1622  * @global WP_Locale $wp_locale
  1578  *
  1623  *
  1579  * @param string $title      Optional. Title of the Iframe page. Default empty.
  1624  * @param string $title      Optional. Title of the Iframe page. Default empty.
  1580  * @param bool   $deprecated Not used.
  1625  * @param bool   $deprecated Not used.
  1581  */
  1626  */
  1582 function iframe_header( $title = '', $deprecated = false ) {
  1627 function iframe_header( $title = '', $deprecated = false ) {
  1624 do_action( "admin_head-$hook_suffix" );
  1669 do_action( "admin_head-$hook_suffix" );
  1625 
  1670 
  1626 /** This action is documented in wp-admin/admin-header.php */
  1671 /** This action is documented in wp-admin/admin-header.php */
  1627 do_action( 'admin_head' );
  1672 do_action( 'admin_head' );
  1628 
  1673 
  1629 $admin_body_class .= ' locale-' . sanitize_html_class( strtolower( str_replace( '_', '-', get_locale() ) ) );
  1674 $admin_body_class .= ' locale-' . sanitize_html_class( strtolower( str_replace( '_', '-', get_user_locale() ) ) );
  1630 
  1675 
  1631 if ( is_rtl() )
  1676 if ( is_rtl() )
  1632 	$admin_body_class .= ' rtl';
  1677 	$admin_body_class .= ' rtl';
  1633 
  1678 
  1634 ?>
  1679 ?>
  1635 </head>
  1680 </head>
  1636 <?php
  1681 <?php
  1637 /** This filter is documented in wp-admin/admin-header.php */
  1682 /** This filter is documented in wp-admin/admin-header.php */
  1638 $admin_body_classes = apply_filters( 'admin_body_class', '' );
  1683 $admin_body_classes = apply_filters( 'admin_body_class', '' );
  1639 ?>
  1684 ?>
  1640 <body<?php if ( isset($GLOBALS['body_id']) ) echo ' id="' . $GLOBALS['body_id'] . '"'; ?> class="wp-admin wp-core-ui no-js iframe <?php echo $admin_body_classes . ' ' . $admin_body_class; ?>">
  1685 <body<?php
       
  1686 /**
       
  1687  * @global string $body_id
       
  1688  */
       
  1689 if ( isset($GLOBALS['body_id']) ) echo ' id="' . $GLOBALS['body_id'] . '"'; ?> class="wp-admin wp-core-ui no-js iframe <?php echo $admin_body_classes . ' ' . $admin_body_class; ?>">
  1641 <script type="text/javascript">
  1690 <script type="text/javascript">
  1642 (function(){
  1691 (function(){
  1643 var c = document.body.className;
  1692 var c = document.body.className;
  1644 c = c.replace(/no-js/, 'js');
  1693 c = c.replace(/no-js/, 'js');
  1645 document.body.className = c;
  1694 document.body.className = c;
  1657 	/*
  1706 	/*
  1658 	 * We're going to hide any footer output on iFrame pages,
  1707 	 * We're going to hide any footer output on iFrame pages,
  1659 	 * but run the hooks anyway since they output JavaScript
  1708 	 * but run the hooks anyway since they output JavaScript
  1660 	 * or other needed content.
  1709 	 * or other needed content.
  1661 	 */
  1710 	 */
  1662 	 ?>
  1711 
       
  1712 	/**
       
  1713 	 * @global string $hook_suffix
       
  1714 	 */
       
  1715 	global $hook_suffix;
       
  1716 	?>
  1663 	<div class="hidden">
  1717 	<div class="hidden">
  1664 <?php
  1718 <?php
  1665 	/** This action is documented in wp-admin/admin-footer.php */
  1719 	/** This action is documented in wp-admin/admin-footer.php */
  1666 	do_action( 'admin_footer', '' );
  1720 	do_action( 'admin_footer', $hook_suffix );
       
  1721 
       
  1722 	/** This action is documented in wp-admin/admin-footer.php */
       
  1723 	do_action( "admin_print_footer_scripts-$hook_suffix" );
  1667 
  1724 
  1668 	/** This action is documented in wp-admin/admin-footer.php */
  1725 	/** This action is documented in wp-admin/admin-footer.php */
  1669 	do_action( 'admin_print_footer_scripts' );
  1726 	do_action( 'admin_print_footer_scripts' );
  1670 ?>
  1727 ?>
  1671 	</div>
  1728 	</div>
  1673 </body>
  1730 </body>
  1674 </html>
  1731 </html>
  1675 <?php
  1732 <?php
  1676 }
  1733 }
  1677 
  1734 
       
  1735 /**
       
  1736  *
       
  1737  * @param WP_Post $post
       
  1738  */
  1678 function _post_states($post) {
  1739 function _post_states($post) {
  1679 	$post_states = array();
  1740 	$post_states = array();
  1680 	if ( isset( $_REQUEST['post_status'] ) )
  1741 	if ( isset( $_REQUEST['post_status'] ) )
  1681 		$post_status = $_REQUEST['post_status'];
  1742 		$post_status = $_REQUEST['post_status'];
  1682 	else
  1743 	else
  1684 
  1745 
  1685 	if ( !empty($post->post_password) )
  1746 	if ( !empty($post->post_password) )
  1686 		$post_states['protected'] = __('Password protected');
  1747 		$post_states['protected'] = __('Password protected');
  1687 	if ( 'private' == $post->post_status && 'private' != $post_status )
  1748 	if ( 'private' == $post->post_status && 'private' != $post_status )
  1688 		$post_states['private'] = __('Private');
  1749 		$post_states['private'] = __('Private');
  1689 	if ( 'draft' == $post->post_status && 'draft' != $post_status )
  1750 	if ( 'draft' === $post->post_status ) {
  1690 		$post_states['draft'] = __('Draft');
  1751 		if ( get_post_meta( $post->ID, '_customize_changeset_uuid', true ) ) {
       
  1752 			$post_states[] = __( 'Customization Draft' );
       
  1753 		} elseif ( 'draft' !== $post_status ) {
       
  1754 			$post_states['draft'] = __( 'Draft' );
       
  1755 		}
       
  1756 	} elseif ( 'trash' === $post->post_status && get_post_meta( $post->ID, '_customize_changeset_uuid', true ) ) {
       
  1757 		$post_states[] = __( 'Customization Draft' );
       
  1758 	}
  1691 	if ( 'pending' == $post->post_status && 'pending' != $post_status )
  1759 	if ( 'pending' == $post->post_status && 'pending' != $post_status )
  1692 		/* translators: post state */
  1760 		$post_states['pending'] = _x('Pending', 'post status');
  1693 		$post_states['pending'] = _x('Pending', 'post state');
       
  1694 	if ( is_sticky($post->ID) )
  1761 	if ( is_sticky($post->ID) )
  1695 		$post_states['sticky'] = __('Sticky');
  1762 		$post_states['sticky'] = __('Sticky');
  1696 
  1763 
  1697 	if ( get_option( 'page_on_front' ) == $post->ID ) {
  1764 	if ( 'future' === $post->post_status ) {
  1698 		$post_states['page_on_front'] = __( 'Front Page' );
  1765 		$post_states['scheduled'] = __( 'Scheduled' );
  1699 	}
  1766 	}
  1700 
  1767 
  1701 	if ( get_option( 'page_for_posts' ) == $post->ID ) {
  1768 	if ( 'page' === get_option( 'show_on_front' ) ) {
  1702 		$post_states['page_for_posts'] = __( 'Posts Page' );
  1769 		if ( intval( get_option( 'page_on_front' ) ) === $post->ID ) {
       
  1770 			$post_states['page_on_front'] = __( 'Front Page' );
       
  1771 		}
       
  1772 
       
  1773 		if ( intval( get_option( 'page_for_posts' ) ) === $post->ID ) {
       
  1774 			$post_states['page_for_posts'] = __( 'Posts Page' );
       
  1775 		}
       
  1776 	}
       
  1777 
       
  1778 	if ( intval( get_option( 'wp_page_for_privacy_policy' ) ) === $post->ID ) {
       
  1779 		$post_states['page_for_privacy_policy'] = __( 'Privacy Policy Page' );
  1703 	}
  1780 	}
  1704 
  1781 
  1705 	/**
  1782 	/**
  1706 	 * Filter the default post display states used in the posts list table.
  1783 	 * Filters the default post display states used in the posts list table.
  1707 	 *
  1784 	 *
  1708 	 * @since 2.8.0
  1785 	 * @since 2.8.0
       
  1786 	 * @since 3.6.0 Added the `$post` parameter.
  1709 	 *
  1787 	 *
  1710 	 * @param array $post_states An array of post display states.
  1788 	 * @param array   $post_states An array of post display states.
  1711 	 * @param int   $post        The post ID.
  1789 	 * @param WP_Post $post        The current post object.
  1712 	 */
  1790 	 */
  1713 	$post_states = apply_filters( 'display_post_states', $post_states, $post );
  1791 	$post_states = apply_filters( 'display_post_states', $post_states, $post );
  1714 
  1792 
  1715 	if ( ! empty($post_states) ) {
  1793 	if ( ! empty($post_states) ) {
  1716 		$state_count = count($post_states);
  1794 		$state_count = count($post_states);
  1717 		$i = 0;
  1795 		$i = 0;
  1718 		echo ' - ';
  1796 		echo ' &mdash; ';
  1719 		foreach ( $post_states as $state ) {
  1797 		foreach ( $post_states as $state ) {
  1720 			++$i;
  1798 			++$i;
  1721 			( $i == $state_count ) ? $sep = '' : $sep = ', ';
  1799 			( $i == $state_count ) ? $sep = '' : $sep = ', ';
  1722 			echo "<span class='post-state'>$state$sep</span>";
  1800 			echo "<span class='post-state'>$state$sep</span>";
  1723 		}
  1801 		}
  1724 	}
  1802 	}
  1725 
  1803 
  1726 }
  1804 }
  1727 
  1805 
       
  1806 /**
       
  1807  *
       
  1808  * @param WP_Post $post
       
  1809  */
  1728 function _media_states( $post ) {
  1810 function _media_states( $post ) {
  1729 	$media_states = array();
  1811 	$media_states = array();
  1730 	$stylesheet = get_option('stylesheet');
  1812 	$stylesheet = get_option('stylesheet');
  1731 
  1813 
  1732 	if ( current_theme_supports( 'custom-header') ) {
  1814 	if ( current_theme_supports( 'custom-header') ) {
  1733 		$meta_header = get_post_meta($post->ID, '_wp_attachment_is_custom_header', true );
  1815 		$meta_header = get_post_meta($post->ID, '_wp_attachment_is_custom_header', true );
  1734 		if ( ! empty( $meta_header ) && $meta_header == $stylesheet )
  1816 
  1735 			$media_states[] = __( 'Header Image' );
  1817 		if ( is_random_header_image() ) {
       
  1818 			$header_images = wp_list_pluck( get_uploaded_header_images(), 'attachment_id' );
       
  1819 
       
  1820 			if ( $meta_header == $stylesheet && in_array( $post->ID, $header_images ) ) {
       
  1821 				$media_states[] = __( 'Header Image' );
       
  1822 			}
       
  1823 		} else {
       
  1824 			$header_image = get_header_image();
       
  1825 
       
  1826 			// Display "Header Image" if the image was ever used as a header image
       
  1827 			if ( ! empty( $meta_header ) && $meta_header == $stylesheet && $header_image !== wp_get_attachment_url( $post->ID ) ) {
       
  1828 				$media_states[] = __( 'Header Image' );
       
  1829 			}
       
  1830 
       
  1831 			// Display "Current Header Image" if the image is currently the header image
       
  1832 			if ( $header_image && $header_image == wp_get_attachment_url( $post->ID ) ) {
       
  1833 				$media_states[] = __( 'Current Header Image' );
       
  1834 			}
       
  1835 		}
  1736 	}
  1836 	}
  1737 
  1837 
  1738 	if ( current_theme_supports( 'custom-background') ) {
  1838 	if ( current_theme_supports( 'custom-background') ) {
  1739 		$meta_background = get_post_meta($post->ID, '_wp_attachment_is_custom_background', true );
  1839 		$meta_background = get_post_meta($post->ID, '_wp_attachment_is_custom_background', true );
  1740 		if ( ! empty( $meta_background ) && $meta_background == $stylesheet )
  1840 
       
  1841 		if ( ! empty( $meta_background ) && $meta_background == $stylesheet ) {
  1741 			$media_states[] = __( 'Background Image' );
  1842 			$media_states[] = __( 'Background Image' );
       
  1843 
       
  1844 			$background_image = get_background_image();
       
  1845 			if ( $background_image && $background_image == wp_get_attachment_url( $post->ID ) ) {
       
  1846 				$media_states[] = __( 'Current Background Image' );
       
  1847 			}
       
  1848 		}
       
  1849 	}
       
  1850 
       
  1851 	if ( $post->ID == get_option( 'site_icon' ) ) {
       
  1852 		$media_states[] = __( 'Site Icon' );
       
  1853 	}
       
  1854 
       
  1855 	if ( $post->ID == get_theme_mod( 'custom_logo' ) ) {
       
  1856 		$media_states[] = __( 'Logo' );
  1742 	}
  1857 	}
  1743 
  1858 
  1744 	/**
  1859 	/**
  1745 	 * Filter the default media display states for items in the Media list table.
  1860 	 * Filters the default media display states for items in the Media list table.
  1746 	 *
  1861 	 *
  1747 	 * @since 3.2.0
  1862 	 * @since 3.2.0
       
  1863 	 * @since 4.8.0 Added the `$post` parameter.
  1748 	 *
  1864 	 *
  1749 	 * @param array $media_states An array of media states. Default 'Header Image',
  1865 	 * @param array   $media_states An array of media states. Default 'Header Image',
  1750 	 *                            'Background Image'.
  1866 	 *                              'Background Image', 'Site Icon', 'Logo'.
       
  1867 	 * @param WP_Post $post         The current attachment object.
  1751 	 */
  1868 	 */
  1752 	$media_states = apply_filters( 'display_media_states', $media_states );
  1869 	$media_states = apply_filters( 'display_media_states', $media_states, $post );
  1753 
  1870 
  1754 	if ( ! empty( $media_states ) ) {
  1871 	if ( ! empty( $media_states ) ) {
  1755 		$state_count = count( $media_states );
  1872 		$state_count = count( $media_states );
  1756 		$i = 0;
  1873 		$i = 0;
  1757 		echo ' - ';
  1874 		echo ' &mdash; ';
  1758 		foreach ( $media_states as $state ) {
  1875 		foreach ( $media_states as $state ) {
  1759 			++$i;
  1876 			++$i;
  1760 			( $i == $state_count ) ? $sep = '' : $sep = ', ';
  1877 			( $i == $state_count ) ? $sep = '' : $sep = ', ';
  1761 			echo "<span class='post-state'>$state$sep</span>";
  1878 			echo "<span class='post-state'>$state$sep</span>";
  1762 		}
  1879 		}
  1774  * @since 2.8.0
  1891  * @since 2.8.0
  1775  */
  1892  */
  1776 function compression_test() {
  1893 function compression_test() {
  1777 ?>
  1894 ?>
  1778 	<script type="text/javascript">
  1895 	<script type="text/javascript">
       
  1896 	var compressionNonce = <?php echo wp_json_encode( wp_create_nonce( 'update_can_compress_scripts' ) ); ?>;
  1779 	var testCompression = {
  1897 	var testCompression = {
  1780 		get : function(test) {
  1898 		get : function(test) {
  1781 			var x;
  1899 			var x;
  1782 			if ( window.XMLHttpRequest ) {
  1900 			if ( window.XMLHttpRequest ) {
  1783 				x = new XMLHttpRequest();
  1901 				x = new XMLHttpRequest();
  1793 						h = x.getResponseHeader('Content-Encoding');
  1911 						h = x.getResponseHeader('Content-Encoding');
  1794 						testCompression.check(r, h, test);
  1912 						testCompression.check(r, h, test);
  1795 					}
  1913 					}
  1796 				};
  1914 				};
  1797 
  1915 
  1798 				x.open('GET', ajaxurl + '?action=wp-compression-test&test='+test+'&'+(new Date()).getTime(), true);
  1916 				x.open('GET', ajaxurl + '?action=wp-compression-test&test='+test+'&_ajax_nonce='+compressionNonce+'&'+(new Date()).getTime(), true);
  1799 				x.send('');
  1917 				x.send('');
  1800 			}
  1918 			}
  1801 		},
  1919 		},
  1802 
  1920 
  1803 		check : function(r, h, test) {
  1921 		check : function(r, h, test) {
  1833  *
  1951  *
  1834  * @see get_submit_button()
  1952  * @see get_submit_button()
  1835  *
  1953  *
  1836  * @param string       $text             The text of the button (defaults to 'Save Changes')
  1954  * @param string       $text             The text of the button (defaults to 'Save Changes')
  1837  * @param string       $type             Optional. The type and CSS class(es) of the button. Core values
  1955  * @param string       $type             Optional. The type and CSS class(es) of the button. Core values
  1838  *                                       include 'primary', 'secondary', 'delete'. Default 'primary'
  1956  *                                       include 'primary', 'small', and 'large'. Default 'primary'.
  1839  * @param string       $name             The HTML name of the submit button. Defaults to "submit". If no
  1957  * @param string       $name             The HTML name of the submit button. Defaults to "submit". If no
  1840  *                                       id attribute is given in $other_attributes below, $name will be
  1958  *                                       id attribute is given in $other_attributes below, $name will be
  1841  *                                       used as the button's id.
  1959  *                                       used as the button's id.
  1842  * @param bool         $wrap             True if the output button should be wrapped in a paragraph tag,
  1960  * @param bool         $wrap             True if the output button should be wrapped in a paragraph tag,
  1843  *                                       false otherwise. Defaults to true
  1961  *                                       false otherwise. Defaults to true
  1856  * Returns a submit button, with provided text and appropriate class
  1974  * Returns a submit button, with provided text and appropriate class
  1857  *
  1975  *
  1858  * @since 3.1.0
  1976  * @since 3.1.0
  1859  *
  1977  *
  1860  * @param string       $text             Optional. The text of the button. Default 'Save Changes'.
  1978  * @param string       $text             Optional. The text of the button. Default 'Save Changes'.
  1861  * @param string       $type             Optional. The type of button. Accepts 'primary', 'secondary',
  1979  * @param string       $type             Optional. The type and CSS class(es) of the button. Core values
  1862  *                                       or 'delete'. Default 'primary large'.
  1980  *                                       include 'primary', 'small', and 'large'. Default 'primary large'.
  1863  * @param string       $name             Optional. The HTML name of the submit button. Defaults to "submit".
  1981  * @param string       $name             Optional. The HTML name of the submit button. Defaults to "submit".
  1864  *                                       If no id attribute is given in $other_attributes below, `$name` will
  1982  *                                       If no id attribute is given in $other_attributes below, `$name` will
  1865  *                                       be used as the button's id. Default 'submit'.
  1983  *                                       be used as the button's id. Default 'submit'.
  1866  * @param bool         $wrap             Optional. True if the output button should be wrapped in a paragraph
  1984  * @param bool         $wrap             Optional. True if the output button should be wrapped in a paragraph
  1867  *                                       tag, false otherwise. Default true.
  1985  *                                       tag, false otherwise. Default true.
  1882 	foreach ( $type as $t ) {
  2000 	foreach ( $type as $t ) {
  1883 		if ( 'secondary' === $t || 'button-secondary' === $t )
  2001 		if ( 'secondary' === $t || 'button-secondary' === $t )
  1884 			continue;
  2002 			continue;
  1885 		$classes[] = in_array( $t, $button_shorthand ) ? 'button-' . $t : $t;
  2003 		$classes[] = in_array( $t, $button_shorthand ) ? 'button-' . $t : $t;
  1886 	}
  2004 	}
  1887 	$class = implode( ' ', array_unique( $classes ) );
  2005 	// Remove empty items, remove duplicate items, and finally build a string.
  1888 
  2006 	$class = implode( ' ', array_unique( array_filter( $classes ) ) );
  1889 	if ( 'delete' === $type )
       
  1890 		$class = 'button-secondary delete';
       
  1891 
  2007 
  1892 	$text = $text ? $text : __( 'Save Changes' );
  2008 	$text = $text ? $text : __( 'Save Changes' );
  1893 
  2009 
  1894 	// Default the id attribute to $name unless an id was specifically provided in $other_attributes
  2010 	// Default the id attribute to $name unless an id was specifically provided in $other_attributes
  1895 	$id = $name;
  2011 	$id = $name;
  1919 	}
  2035 	}
  1920 
  2036 
  1921 	return $button;
  2037 	return $button;
  1922 }
  2038 }
  1923 
  2039 
       
  2040 /**
       
  2041  *
       
  2042  * @global bool $is_IE
       
  2043  */
  1924 function _wp_admin_html_begin() {
  2044 function _wp_admin_html_begin() {
  1925 	global $is_IE;
  2045 	global $is_IE;
  1926 
  2046 
  1927 	$admin_html_class = ( is_admin_bar_showing() ) ? 'wp-toolbar' : '';
  2047 	$admin_html_class = ( is_admin_bar_showing() ) ? 'wp-toolbar' : '';
  1928 
  2048 
  1950 <head>
  2070 <head>
  1951 <meta http-equiv="Content-Type" content="<?php bloginfo('html_type'); ?>; charset=<?php echo get_option('blog_charset'); ?>" />
  2071 <meta http-equiv="Content-Type" content="<?php bloginfo('html_type'); ?>; charset=<?php echo get_option('blog_charset'); ?>" />
  1952 <?php
  2072 <?php
  1953 }
  2073 }
  1954 
  2074 
  1955 final class WP_Internal_Pointers {
       
  1956 	/**
       
  1957 	 * Initializes the new feature pointers.
       
  1958 	 *
       
  1959 	 * @since 3.3.0
       
  1960 	 *
       
  1961 	 * All pointers can be disabled using the following:
       
  1962 	 *     remove_action( 'admin_enqueue_scripts', array( 'WP_Internal_Pointers', 'enqueue_scripts' ) );
       
  1963 	 *
       
  1964 	 * Individual pointers (e.g. wp390_widgets) can be disabled using the following:
       
  1965 	 *     remove_action( 'admin_print_footer_scripts', array( 'WP_Internal_Pointers', 'pointer_wp390_widgets' ) );
       
  1966 	 *
       
  1967 	 * @param string $hook_suffix The current admin page.
       
  1968 	 */
       
  1969 	public static function enqueue_scripts( $hook_suffix ) {
       
  1970 		/*
       
  1971 		 * Register feature pointers
       
  1972 		 * Format: array( hook_suffix => pointer_id )
       
  1973 		 */
       
  1974 
       
  1975 		$registered_pointers = array(
       
  1976 			'post-new.php' => 'wp410_dfw',
       
  1977 			'post.php'     => 'wp410_dfw',
       
  1978 			'edit.php'     => 'wp360_locks',
       
  1979 			'widgets.php'  => 'wp390_widgets',
       
  1980 			'themes.php'   => 'wp390_widgets',
       
  1981 		);
       
  1982 
       
  1983 		// Check if screen related pointer is registered
       
  1984 		if ( empty( $registered_pointers[ $hook_suffix ] ) )
       
  1985 			return;
       
  1986 
       
  1987 		$pointers = (array) $registered_pointers[ $hook_suffix ];
       
  1988 
       
  1989 		$caps_required = array(
       
  1990 			'wp390_widgets' => array( 'edit_theme_options' ),
       
  1991 		);
       
  1992 
       
  1993 		// Get dismissed pointers
       
  1994 		$dismissed = explode( ',', (string) get_user_meta( get_current_user_id(), 'dismissed_wp_pointers', true ) );
       
  1995 
       
  1996 		$got_pointers = false;
       
  1997 		foreach ( array_diff( $pointers, $dismissed ) as $pointer ) {
       
  1998 			if ( isset( $caps_required[ $pointer ] ) ) {
       
  1999 				foreach ( $caps_required[ $pointer ] as $cap ) {
       
  2000 					if ( ! current_user_can( $cap ) )
       
  2001 						continue 2;
       
  2002 				}
       
  2003 			}
       
  2004 
       
  2005 			// Bind pointer print function
       
  2006 			add_action( 'admin_print_footer_scripts', array( 'WP_Internal_Pointers', 'pointer_' . $pointer ) );
       
  2007 			$got_pointers = true;
       
  2008 		}
       
  2009 
       
  2010 		if ( ! $got_pointers )
       
  2011 			return;
       
  2012 
       
  2013 		// Add pointers script and style to queue
       
  2014 		wp_enqueue_style( 'wp-pointer' );
       
  2015 		wp_enqueue_script( 'wp-pointer' );
       
  2016 	}
       
  2017 
       
  2018 	/**
       
  2019 	 * Print the pointer JavaScript data.
       
  2020 	 *
       
  2021 	 * @since 3.3.0
       
  2022 	 *
       
  2023 	 * @param string $pointer_id The pointer ID.
       
  2024 	 * @param string $selector The HTML elements, on which the pointer should be attached.
       
  2025 	 * @param array  $args Arguments to be passed to the pointer JS (see wp-pointer.js).
       
  2026 	 */
       
  2027 	private static function print_js( $pointer_id, $selector, $args ) {
       
  2028 		if ( empty( $pointer_id ) || empty( $selector ) || empty( $args ) || empty( $args['content'] ) )
       
  2029 			return;
       
  2030 
       
  2031 		?>
       
  2032 		<script type="text/javascript">
       
  2033 		(function($){
       
  2034 			var options = <?php echo wp_json_encode( $args ); ?>, setup;
       
  2035 
       
  2036 			if ( ! options )
       
  2037 				return;
       
  2038 
       
  2039 			options = $.extend( options, {
       
  2040 				close: function() {
       
  2041 					$.post( ajaxurl, {
       
  2042 						pointer: '<?php echo $pointer_id; ?>',
       
  2043 						action: 'dismiss-wp-pointer'
       
  2044 					});
       
  2045 				}
       
  2046 			});
       
  2047 
       
  2048 			setup = function() {
       
  2049 				$('<?php echo $selector; ?>').first().pointer( options ).pointer('open');
       
  2050 			};
       
  2051 
       
  2052 			if ( options.position && options.position.defer_loading )
       
  2053 				$(window).bind( 'load.wp-pointers', setup );
       
  2054 			else
       
  2055 				$(document).ready( setup );
       
  2056 
       
  2057 		})( jQuery );
       
  2058 		</script>
       
  2059 		<?php
       
  2060 	}
       
  2061 
       
  2062 	public static function pointer_wp330_toolbar() {}
       
  2063 	public static function pointer_wp330_media_uploader() {}
       
  2064 	public static function pointer_wp330_saving_widgets() {}
       
  2065 	public static function pointer_wp340_customize_current_theme_link() {}
       
  2066 	public static function pointer_wp340_choose_image_from_library() {}
       
  2067 	public static function pointer_wp350_media() {}
       
  2068 	public static function pointer_wp360_revisions() {}
       
  2069 
       
  2070 	public static function pointer_wp360_locks() {
       
  2071 		if ( ! is_multi_author() ) {
       
  2072 			return;
       
  2073 		}
       
  2074 
       
  2075 		$content  = '<h3>' . __( 'Edit Lock' ) . '</h3>';
       
  2076 		$content .= '<p>' . __( 'Someone else is editing this. No need to refresh; the lock will disappear when they&#8217;re done.' ) . '</p>';
       
  2077 
       
  2078 		self::print_js( 'wp360_locks', 'tr.wp-locked .locked-indicator', array(
       
  2079 			'content' => $content,
       
  2080 			'position' => array( 'edge' => 'left', 'align' => 'left' ),
       
  2081 		) );
       
  2082 	}
       
  2083 
       
  2084 	public static function pointer_wp390_widgets() {
       
  2085 		if ( ! current_theme_supports( 'widgets' ) ) {
       
  2086 			return;
       
  2087 		}
       
  2088 
       
  2089 		$content  = '<h3>' . __( 'New Feature: Live Widget Previews' ) . '</h3>';
       
  2090 		$content .= '<p>' . __( 'Add, edit, and play around with your widgets from the Customizer.' ) . ' ' . __( 'Preview your changes in real-time and only save them when you&#8217;re ready.' ) . '</p>';
       
  2091 
       
  2092 		if ( 'themes' === get_current_screen()->id ) {
       
  2093 			$selector = '.theme.active .customize';
       
  2094 			$position = array( 'edge' => is_rtl() ? 'right' : 'left', 'align' => 'center' );
       
  2095 		} else {
       
  2096 			$selector = 'a[href^="customize.php"]';
       
  2097 			if ( is_rtl() ) {
       
  2098 				$position = array( 'edge' => 'right', 'align' => 'center', 'my' => 'right-5px' );
       
  2099 			} else {
       
  2100 				$position = array( 'edge' => 'left', 'align' => 'center', 'my' => 'left-5px' );
       
  2101 			}
       
  2102 		}
       
  2103 
       
  2104 		self::print_js( 'wp390_widgets', $selector, array(
       
  2105 			'content' => $content,
       
  2106 			'position' => $position,
       
  2107 		) );
       
  2108 	}
       
  2109 
       
  2110 	public static function pointer_wp410_dfw() {
       
  2111 		// Don't show when editor-scrolling is not used.
       
  2112 		if ( empty( $GLOBALS['_wp_editor_expand'] ) ) {
       
  2113 			return;
       
  2114 		}
       
  2115 
       
  2116 		$content  = '<h3>' . __( 'Distraction-Free Writing' ) . '</h3>';
       
  2117 		$content .= '<p>' . __( 'Enable distraction-free writing mode, and everything surrounding the editor will fade away when you start typing. Move your mouse out of the editor to reveal everything again.' ) . '</p>';
       
  2118 
       
  2119 		if ( is_rtl() ) {
       
  2120 			$position = array( 'edge' => 'left', 'align' => 'center', 'my' => 'left+40 top-11', 'at' => 'left top' );
       
  2121 		} else {
       
  2122 			$position = array( 'edge' => 'right', 'align' => 'center', 'my' => 'right-40 top-11', 'at' => 'right top' );
       
  2123 		}
       
  2124 
       
  2125 		self::print_js( 'wp410_dfw', '#wp-content-wrap', array(
       
  2126 			'content' => $content,
       
  2127 			'position' => $position,
       
  2128 		) );
       
  2129 	}
       
  2130 
       
  2131 	/**
       
  2132 	 * Prevents new users from seeing existing 'new feature' pointers.
       
  2133 	 *
       
  2134 	 * @since 3.3.0
       
  2135 	 *
       
  2136 	 * @param int $user_id User ID.
       
  2137 	 */
       
  2138 	public static function dismiss_pointers_for_new_users( $user_id ) {
       
  2139 		add_user_meta( $user_id, 'dismissed_wp_pointers', 'wp360_locks,wp390_widgets' );
       
  2140 	}
       
  2141 }
       
  2142 
       
  2143 add_action( 'admin_enqueue_scripts', array( 'WP_Internal_Pointers', 'enqueue_scripts'                ) );
       
  2144 add_action( 'user_register',         array( 'WP_Internal_Pointers', 'dismiss_pointers_for_new_users' ) );
       
  2145 
       
  2146 /**
  2075 /**
  2147  * Convert a screen string to a screen object
  2076  * Convert a screen string to a screen object
  2148  *
  2077  *
  2149  * @since 3.0.0
  2078  * @since 3.0.0
  2150  *
  2079  *
  2151  * @param string $hook_name The hook name (also known as the hook suffix) used to determine the screen.
  2080  * @param string $hook_name The hook name (also known as the hook suffix) used to determine the screen.
  2152  * @return WP_Screen Screen object.
  2081  * @return WP_Screen Screen object.
  2153  */
  2082  */
  2154 function convert_to_screen( $hook_name ) {
  2083 function convert_to_screen( $hook_name ) {
  2155 	if ( ! class_exists( 'WP_Screen' ) ) {
  2084 	if ( ! class_exists( 'WP_Screen' ) ) {
  2156 		_doing_it_wrong( 'convert_to_screen(), add_meta_box()', __( "Likely direct inclusion of wp-admin/includes/template.php in order to use add_meta_box(). This is very wrong. Hook the add_meta_box() call into the add_meta_boxes action instead." ), '3.3' );
  2085 		_doing_it_wrong(
       
  2086 			'convert_to_screen(), add_meta_box()',
       
  2087 			sprintf(
       
  2088 				/* translators: 1: wp-admin/includes/template.php 2: add_meta_box() 3: add_meta_boxes */
       
  2089 				__( 'Likely direct inclusion of %1$s in order to use %2$s. This is very wrong. Hook the %2$s call into the %3$s action instead.' ),
       
  2090 				'<code>wp-admin/includes/template.php</code>',
       
  2091 				'<code>add_meta_box()</code>',
       
  2092 				'<code>add_meta_boxes</code>'
       
  2093 			),
       
  2094 			'3.3.0'
       
  2095 		);
  2157 		return (object) array( 'id' => '_invalid', 'base' => '_are_belong_to_us' );
  2096 		return (object) array( 'id' => '_invalid', 'base' => '_are_belong_to_us' );
  2158 	}
  2097 	}
  2159 
  2098 
  2160 	return WP_Screen::get( $hook_name );
  2099 	return WP_Screen::get( $hook_name );
  2161 }
  2100 }
  2166  * @since 3.6.0
  2105  * @since 3.6.0
  2167  * @access private
  2106  * @access private
  2168  */
  2107  */
  2169 function _local_storage_notice() {
  2108 function _local_storage_notice() {
  2170 	?>
  2109 	?>
  2171 	<div id="local-storage-notice" class="hidden notice">
  2110 	<div id="local-storage-notice" class="hidden notice is-dismissible">
  2172 	<p class="local-restore">
  2111 	<p class="local-restore">
  2173 		<?php _e('The backup of this post in your browser is different from the version below.'); ?>
  2112 		<?php _e( 'The backup of this post in your browser is different from the version below.' ); ?>
  2174 		<a class="restore-backup" href="#"><?php _e('Restore the backup.'); ?></a>
  2113 		<button type="button" class="button restore-backup"><?php _e('Restore the backup'); ?></button>
  2175 	</p>
  2114 	</p>
  2176 	<p class="undo-restore hidden">
  2115 	<p class="help">
  2177 		<?php _e('Post restored successfully.'); ?>
  2116 		<?php _e( 'This will replace the current editor content with the last backup version. You can use undo and redo in the editor to get the old content back or to return to the restored version.' ); ?>
  2178 		<a class="undo-restore-backup" href="#"><?php _e('Undo.'); ?></a>
       
  2179 	</p>
  2117 	</p>
  2180 	</div>
  2118 	</div>
  2181 	<?php
  2119 	<?php
  2182 }
  2120 }
  2183 
  2121 
  2187  * Outputs a HTML element with the star rating exposed on a 0..5 scale in
  2125  * Outputs a HTML element with the star rating exposed on a 0..5 scale in
  2188  * half star increments (ie. 1, 1.5, 2 stars). Optionally, if specified, the
  2126  * half star increments (ie. 1, 1.5, 2 stars). Optionally, if specified, the
  2189  * number of ratings may also be displayed by passing the $number parameter.
  2127  * number of ratings may also be displayed by passing the $number parameter.
  2190  *
  2128  *
  2191  * @since 3.8.0
  2129  * @since 3.8.0
       
  2130  * @since 4.4.0 Introduced the `echo` parameter.
       
  2131  *
  2192  * @param array $args {
  2132  * @param array $args {
  2193  *     Optional. Array of star ratings arguments.
  2133  *     Optional. Array of star ratings arguments.
  2194  *
  2134  *
  2195  *     @type int    $rating The rating to display, expressed in either a 0.5 rating increment,
  2135  *     @type int|float $rating The rating to display, expressed in either a 0.5 rating increment,
  2196  *                          or percentage. Default 0.
  2136  *                             or percentage. Default 0.
  2197  *     @type string $type   Format that the $rating is in. Valid values are 'rating' (default),
  2137  *     @type string    $type   Format that the $rating is in. Valid values are 'rating' (default),
  2198  *                          or, 'percent'. Default 'rating'.
  2138  *                             or, 'percent'. Default 'rating'.
  2199  *     @type int    $number The number of ratings that makes up this rating. Default 0.
  2139  *     @type int       $number The number of ratings that makes up this rating. Default 0.
       
  2140  *     @type bool      $echo   Whether to echo the generated markup. False to return the markup instead
       
  2141  *                             of echoing it. Default true.
  2200  * }
  2142  * }
       
  2143  * @return string Star rating HTML.
  2201  */
  2144  */
  2202 function wp_star_rating( $args = array() ) {
  2145 function wp_star_rating( $args = array() ) {
  2203 	$defaults = array(
  2146 	$defaults = array(
  2204 		'rating' => 0,
  2147 		'rating' => 0,
  2205 		'type' => 'rating',
  2148 		'type'   => 'rating',
  2206 		'number' => 0,
  2149 		'number' => 0,
       
  2150 		'echo'   => true,
  2207 	);
  2151 	);
  2208 	$r = wp_parse_args( $args, $defaults );
  2152 	$r = wp_parse_args( $args, $defaults );
  2209 
  2153 
  2210 	// Non-english decimal places when the $rating is coming from a string
  2154 	// Non-English decimal places when the $rating is coming from a string
  2211 	$rating = str_replace( ',', '.', $r['rating'] );
  2155 	$rating = (float) str_replace( ',', '.', $r['rating'] );
  2212 
  2156 
  2213 	// Convert Percentage to star rating, 0..5 in .5 increments
  2157 	// Convert Percentage to star rating, 0..5 in .5 increments
  2214 	if ( 'percent' == $r['type'] ) {
  2158 	if ( 'percent' === $r['type'] ) {
  2215 		$rating = round( $rating / 10, 0 ) / 2;
  2159 		$rating = round( $rating / 10, 0 ) / 2;
  2216 	}
  2160 	}
  2217 
  2161 
  2218 	// Calculate the number of each type of star needed
  2162 	// Calculate the number of each type of star needed
  2219 	$full_stars = floor( $rating );
  2163 	$full_stars = floor( $rating );
  2227 	} else {
  2171 	} else {
  2228 		/* translators: 1: The rating */
  2172 		/* translators: 1: The rating */
  2229 		$title = sprintf( __( '%s rating' ), number_format_i18n( $rating, 1 ) );
  2173 		$title = sprintf( __( '%s rating' ), number_format_i18n( $rating, 1 ) );
  2230 	}
  2174 	}
  2231 
  2175 
  2232 	echo '<div class="star-rating" title="' . esc_attr( $title ) . '">';
  2176 	$output = '<div class="star-rating">';
  2233 	echo '<span class="screen-reader-text">' . $title . '</span>';
  2177 	$output .= '<span class="screen-reader-text">' . $title . '</span>';
  2234 	echo str_repeat( '<div class="star star-full"></div>', $full_stars );
  2178 	$output .= str_repeat( '<div class="star star-full" aria-hidden="true"></div>', $full_stars );
  2235 	echo str_repeat( '<div class="star star-half"></div>', $half_stars );
  2179 	$output .= str_repeat( '<div class="star star-half" aria-hidden="true"></div>', $half_stars );
  2236 	echo str_repeat( '<div class="star star-empty"></div>', $empty_stars);
  2180 	$output .= str_repeat( '<div class="star star-empty" aria-hidden="true"></div>', $empty_stars );
  2237 	echo '</div>';
  2181 	$output .= '</div>';
       
  2182 
       
  2183 	if ( $r['echo'] ) {
       
  2184 		echo $output;
       
  2185 	}
       
  2186 
       
  2187 	return $output;
  2238 }
  2188 }
  2239 
  2189 
  2240 /**
  2190 /**
  2241  * Output a notice when editing the page for posts (internal use only).
  2191  * Output a notice when editing the page for posts (internal use only).
  2242  *
  2192  *