PageRenderTime 302ms CodeModel.GetById 61ms app.highlight 166ms RepoModel.GetById 35ms app.codeStats 1ms

/wp-admin/includes/template.php

https://bitbucket.org/abnopanda/wordpress
PHP | 1878 lines | 1139 code | 225 blank | 514 comment | 219 complexity | b1490f3b6a829188c9f77e5868e30310 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1<?php
   2/**
   3 * Template WordPress Administration API.
   4 *
   5 * A Big Mess. Also some neat functions that are nicely written.
   6 *
   7 * @package WordPress
   8 * @subpackage Administration
   9 */
  10
  11//
  12// Category Checklists
  13//
  14
  15/**
  16 * Walker to output an unordered list of category checkbox <input> elements.
  17 *
  18 * @see Walker
  19 * @see wp_category_checklist()
  20 * @see wp_terms_checklist()
  21 * @since 2.5.1
  22 */
  23class Walker_Category_Checklist extends Walker {
  24	var $tree_type = 'category';
  25	var $db_fields = array ('parent' => 'parent', 'id' => 'term_id'); //TODO: decouple this
  26
  27	function start_lvl( &$output, $depth = 0, $args = array() ) {
  28		$indent = str_repeat("\t", $depth);
  29		$output .= "$indent<ul class='children'>\n";
  30	}
  31
  32	function end_lvl( &$output, $depth = 0, $args = array() ) {
  33		$indent = str_repeat("\t", $depth);
  34		$output .= "$indent</ul>\n";
  35	}
  36
  37	function start_el( &$output, $category, $depth, $args, $id = 0 ) {
  38		extract($args);
  39		if ( empty($taxonomy) )
  40			$taxonomy = 'category';
  41
  42		if ( $taxonomy == 'category' )
  43			$name = 'post_category';
  44		else
  45			$name = 'tax_input['.$taxonomy.']';
  46
  47		$class = in_array( $category->term_id, $popular_cats ) ? ' class="popular-category"' : '';
  48		$output .= "\n<li id='{$taxonomy}-{$category->term_id}'$class>" . '<label class="selectit"><input value="' . $category->term_id . '" type="checkbox" name="'.$name.'[]" id="in-'.$taxonomy.'-' . $category->term_id . '"' . checked( in_array( $category->term_id, $selected_cats ), true, false ) . disabled( empty( $args['disabled'] ), false, false ) . ' /> ' . esc_html( apply_filters('the_category', $category->name )) . '</label>';
  49	}
  50
  51	function end_el( &$output, $category, $depth = 0, $args = array() ) {
  52		$output .= "</li>\n";
  53	}
  54}
  55
  56/**
  57 * Output an unordered list of checkbox <input> elements labelled
  58 * with category names.
  59 *
  60 * @see wp_terms_checklist()
  61 * @since 2.5.1
  62 *
  63 * @param int $post_id Mark categories associated with this post as checked. $selected_cats must not be an array.
  64 * @param int $descendants_and_self ID of the category to output along with its descendents.
  65 * @param bool|array $selected_cats List of categories to mark as checked.
  66 * @param bool|array $popular_cats Override the list of categories that receive the "popular-category" class.
  67 * @param object $walker Walker object to use to build the output.
  68 * @param bool $checked_ontop Move checked items out of the hierarchy and to the top of the list.
  69 */
  70function wp_category_checklist( $post_id = 0, $descendants_and_self = 0, $selected_cats = false, $popular_cats = false, $walker = null, $checked_ontop = true ) {
  71	wp_terms_checklist( $post_id, array(
  72		'taxonomy' => 'category',
  73		'descendants_and_self' => $descendants_and_self,
  74		'selected_cats' => $selected_cats,
  75		'popular_cats' => $popular_cats,
  76		'walker' => $walker,
  77		'checked_ontop' => $checked_ontop
  78	) );
  79}
  80
  81/**
  82 * Output an unordered list of checkbox <input> elements labelled
  83 * with term names. Taxonomy independent version of wp_category_checklist().
  84 *
  85 * @since 3.0.0
  86 *
  87 * @param int $post_id
  88 * @param array $args
  89 */
  90function wp_terms_checklist($post_id = 0, $args = array()) {
  91 	$defaults = array(
  92		'descendants_and_self' => 0,
  93		'selected_cats' => false,
  94		'popular_cats' => false,
  95		'walker' => null,
  96		'taxonomy' => 'category',
  97		'checked_ontop' => true
  98	);
  99	$args = apply_filters( 'wp_terms_checklist_args', $args, $post_id );
 100
 101	extract( wp_parse_args($args, $defaults), EXTR_SKIP );
 102
 103	if ( empty($walker) || !is_a($walker, 'Walker') )
 104		$walker = new Walker_Category_Checklist;
 105
 106	$descendants_and_self = (int) $descendants_and_self;
 107
 108	$args = array('taxonomy' => $taxonomy);
 109
 110	$tax = get_taxonomy($taxonomy);
 111	$args['disabled'] = !current_user_can($tax->cap->assign_terms);
 112
 113	if ( is_array( $selected_cats ) )
 114		$args['selected_cats'] = $selected_cats;
 115	elseif ( $post_id )
 116		$args['selected_cats'] = wp_get_object_terms($post_id, $taxonomy, array_merge($args, array('fields' => 'ids')));
 117	else
 118		$args['selected_cats'] = array();
 119
 120	if ( is_array( $popular_cats ) )
 121		$args['popular_cats'] = $popular_cats;
 122	else
 123		$args['popular_cats'] = get_terms( $taxonomy, array( 'fields' => 'ids', 'orderby' => 'count', 'order' => 'DESC', 'number' => 10, 'hierarchical' => false ) );
 124
 125	if ( $descendants_and_self ) {
 126		$categories = (array) get_terms($taxonomy, array( 'child_of' => $descendants_and_self, 'hierarchical' => 0, 'hide_empty' => 0 ) );
 127		$self = get_term( $descendants_and_self, $taxonomy );
 128		array_unshift( $categories, $self );
 129	} else {
 130		$categories = (array) get_terms($taxonomy, array('get' => 'all'));
 131	}
 132
 133	if ( $checked_ontop ) {
 134		// 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)
 135		$checked_categories = array();
 136		$keys = array_keys( $categories );
 137
 138		foreach( $keys as $k ) {
 139			if ( in_array( $categories[$k]->term_id, $args['selected_cats'] ) ) {
 140				$checked_categories[] = $categories[$k];
 141				unset( $categories[$k] );
 142			}
 143		}
 144
 145		// Put checked cats on top
 146		echo call_user_func_array(array(&$walker, 'walk'), array($checked_categories, 0, $args));
 147	}
 148	// Then the rest of them
 149	echo call_user_func_array(array(&$walker, 'walk'), array($categories, 0, $args));
 150}
 151
 152/**
 153 * Retrieve a list of the most popular terms from the specified taxonomy.
 154 *
 155 * If the $echo argument is true then the elements for a list of checkbox
 156 * <input> elements labelled with the names of the selected terms is output.
 157 * If the $post_ID global isn't empty then the terms associated with that
 158 * post will be marked as checked.
 159 *
 160 * @since 2.5.0
 161 *
 162 * @param string $taxonomy Taxonomy to retrieve terms from.
 163 * @param int $default Unused.
 164 * @param int $number Number of terms to retrieve. Defaults to 10.
 165 * @param bool $echo Optionally output the list as well. Defaults to true.
 166 * @return array List of popular term IDs.
 167 */
 168function wp_popular_terms_checklist( $taxonomy, $default = 0, $number = 10, $echo = true ) {
 169	$post = get_post();
 170
 171	if ( $post && $post->ID )
 172		$checked_terms = wp_get_object_terms($post->ID, $taxonomy, array('fields'=>'ids'));
 173	else
 174		$checked_terms = array();
 175
 176	$terms = get_terms( $taxonomy, array( 'orderby' => 'count', 'order' => 'DESC', 'number' => $number, 'hierarchical' => false ) );
 177
 178	$tax = get_taxonomy($taxonomy);
 179	if ( ! current_user_can($tax->cap->assign_terms) )
 180		$disabled = 'disabled="disabled"';
 181	else
 182		$disabled = '';
 183
 184	$popular_ids = array();
 185	foreach ( (array) $terms as $term ) {
 186		$popular_ids[] = $term->term_id;
 187		if ( !$echo ) // hack for AJAX use
 188			continue;
 189		$id = "popular-$taxonomy-$term->term_id";
 190		$checked = in_array( $term->term_id, $checked_terms ) ? 'checked="checked"' : '';
 191		?>
 192
 193		<li id="<?php echo $id; ?>" class="popular-category">
 194			<label class="selectit">
 195			<input id="in-<?php echo $id; ?>" type="checkbox" <?php echo $checked; ?> value="<?php echo (int) $term->term_id; ?>" <?php echo $disabled ?>/>
 196				<?php echo esc_html( apply_filters( 'the_category', $term->name ) ); ?>
 197			</label>
 198		</li>
 199
 200		<?php
 201	}
 202	return $popular_ids;
 203}
 204
 205/**
 206 * {@internal Missing Short Description}}
 207 *
 208 * @since 2.5.1
 209 *
 210 * @param unknown_type $link_id
 211 */
 212function wp_link_category_checklist( $link_id = 0 ) {
 213	$default = 1;
 214
 215	if ( $link_id ) {
 216		$checked_categories = wp_get_link_cats( $link_id );
 217		// No selected categories, strange
 218		if ( ! count( $checked_categories ) )
 219			$checked_categories[] = $default;
 220	} else {
 221		$checked_categories[] = $default;
 222	}
 223
 224	$categories = get_terms( 'link_category', array( 'orderby' => 'name', 'hide_empty' => 0 ) );
 225
 226	if ( empty( $categories ) )
 227		return;
 228
 229	foreach ( $categories as $category ) {
 230		$cat_id = $category->term_id;
 231		$name = esc_html( apply_filters( 'the_category', $category->name ) );
 232		$checked = in_array( $cat_id, $checked_categories ) ? ' checked="checked"' : '';
 233		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>";
 234	}
 235}
 236
 237// adds hidden fields with the data for use in the inline editor for posts and pages
 238/**
 239 * {@internal Missing Short Description}}
 240 *
 241 * @since 2.7.0
 242 *
 243 * @param unknown_type $post
 244 */
 245function get_inline_data($post) {
 246	$post_type_object = get_post_type_object($post->post_type);
 247	if ( ! current_user_can($post_type_object->cap->edit_post, $post->ID) )
 248		return;
 249
 250	$title = esc_textarea( trim( $post->post_title ) );
 251
 252	echo '
 253<div class="hidden" id="inline_' . $post->ID . '">
 254	<div class="post_title">' . $title . '</div>
 255	<div class="post_name">' . apply_filters('editable_slug', $post->post_name) . '</div>
 256	<div class="post_author">' . $post->post_author . '</div>
 257	<div class="comment_status">' . esc_html( $post->comment_status ) . '</div>
 258	<div class="ping_status">' . esc_html( $post->ping_status ) . '</div>
 259	<div class="_status">' . esc_html( $post->post_status ) . '</div>
 260	<div class="jj">' . mysql2date( 'd', $post->post_date, false ) . '</div>
 261	<div class="mm">' . mysql2date( 'm', $post->post_date, false ) . '</div>
 262	<div class="aa">' . mysql2date( 'Y', $post->post_date, false ) . '</div>
 263	<div class="hh">' . mysql2date( 'H', $post->post_date, false ) . '</div>
 264	<div class="mn">' . mysql2date( 'i', $post->post_date, false ) . '</div>
 265	<div class="ss">' . mysql2date( 's', $post->post_date, false ) . '</div>
 266	<div class="post_password">' . esc_html( $post->post_password ) . '</div>';
 267
 268	if ( $post_type_object->hierarchical )
 269		echo '<div class="post_parent">' . $post->post_parent . '</div>';
 270
 271	if ( $post->post_type == 'page' )
 272		echo '<div class="page_template">' . esc_html( get_post_meta( $post->ID, '_wp_page_template', true ) ) . '</div>';
 273
 274	if ( post_type_supports( $post->post_type, 'page-attributes' ) )
 275		echo '<div class="menu_order">' . $post->menu_order . '</div>';
 276
 277	$taxonomy_names = get_object_taxonomies( $post->post_type );
 278	foreach ( $taxonomy_names as $taxonomy_name) {
 279		$taxonomy = get_taxonomy( $taxonomy_name );
 280
 281		if ( $taxonomy->hierarchical && $taxonomy->show_ui ) {
 282				echo '<div class="post_category" id="' . $taxonomy_name . '_' . $post->ID . '">'
 283					. implode( ',', wp_get_object_terms( $post->ID, $taxonomy_name, array( 'fields' => 'ids' ) ) ) . '</div>';
 284		} elseif ( $taxonomy->show_ui ) {
 285			echo '<div class="tags_input" id="'.$taxonomy_name.'_'.$post->ID.'">'
 286				. esc_html( str_replace( ',', ', ', get_terms_to_edit( $post->ID, $taxonomy_name ) ) ) . '</div>';
 287		}
 288	}
 289
 290	if ( !$post_type_object->hierarchical )
 291		echo '<div class="sticky">' . (is_sticky($post->ID) ? 'sticky' : '') . '</div>';
 292
 293	if ( post_type_supports( $post->post_type, 'post-formats' ) )
 294		echo '<div class="post_format">' . esc_html( get_post_format( $post->ID ) ) . '</div>';
 295
 296	echo '</div>';
 297}
 298
 299/**
 300 * {@internal Missing Short Description}}
 301 *
 302 * @since 2.7.0
 303 *
 304 * @param unknown_type $position
 305 * @param unknown_type $checkbox
 306 * @param unknown_type $mode
 307 */
 308function wp_comment_reply($position = '1', $checkbox = false, $mode = 'single', $table_row = true) {
 309	// allow plugin to replace the popup content
 310	$content = apply_filters( 'wp_comment_reply', '', array('position' => $position, 'checkbox' => $checkbox, 'mode' => $mode) );
 311
 312	if ( ! empty($content) ) {
 313		echo $content;
 314		return;
 315	}
 316
 317	if ( $mode == 'single' ) {
 318		$wp_list_table = _get_list_table('WP_Post_Comments_List_Table');
 319	} else {
 320		$wp_list_table = _get_list_table('WP_Comments_List_Table');
 321	}
 322
 323?>
 324<form method="get" action="">
 325<?php if ( $table_row ) : ?>
 326<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">
 327<?php else : ?>
 328<div id="com-reply" style="display:none;"><div id="replyrow" style="display:none;">
 329<?php endif; ?>
 330	<div id="replyhead" style="display:none;"><h5><?php _e( 'Reply to Comment' ); ?></h5></div>
 331	<div id="addhead" style="display:none;"><h5><?php _e('Add new Comment'); ?></h5></div>
 332	<div id="edithead" style="display:none;">
 333		<div class="inside">
 334		<label for="author"><?php _e('Name') ?></label>
 335		<input type="text" name="newcomment_author" size="50" value="" id="author" />
 336		</div>
 337
 338		<div class="inside">
 339		<label for="author-email"><?php _e('E-mail') ?></label>
 340		<input type="text" name="newcomment_author_email" size="50" value="" id="author-email" />
 341		</div>
 342
 343		<div class="inside">
 344		<label for="author-url"><?php _e('URL') ?></label>
 345		<input type="text" id="author-url" name="newcomment_author_url" size="103" value="" />
 346		</div>
 347		<div style="clear:both;"></div>
 348	</div>
 349
 350	<div id="replycontainer">
 351	<?php
 352	$quicktags_settings = array( 'buttons' => 'strong,em,link,block,del,ins,img,ul,ol,li,code,spell,close' );
 353	wp_editor( '', 'replycontent', array( 'media_buttons' => false, 'tinymce' => false, 'quicktags' => $quicktags_settings ) );
 354	?>
 355	</div>
 356
 357	<p id="replysubmit" class="submit">
 358	<a href="#comments-form" class="save button-primary alignright">
 359	<span id="addbtn" style="display:none;"><?php _e('Add Comment'); ?></span>
 360	<span id="savebtn" style="display:none;"><?php _e('Update Comment'); ?></span>
 361	<span id="replybtn" style="display:none;"><?php _e('Submit Reply'); ?></span></a>
 362	<a href="#comments-form" class="cancel button-secondary alignleft"><?php _e('Cancel'); ?></a>
 363	<span class="waiting spinner"></span>
 364	<span class="error" style="display:none;"></span>
 365	<br class="clear" />
 366	</p>
 367
 368	<input type="hidden" name="user_ID" id="user_ID" value="<?php echo get_current_user_id(); ?>" />
 369	<input type="hidden" name="action" id="action" value="" />
 370	<input type="hidden" name="comment_ID" id="comment_ID" value="" />
 371	<input type="hidden" name="comment_post_ID" id="comment_post_ID" value="" />
 372	<input type="hidden" name="status" id="status" value="" />
 373	<input type="hidden" name="position" id="position" value="<?php echo $position; ?>" />
 374	<input type="hidden" name="checkbox" id="checkbox" value="<?php echo $checkbox ? 1 : 0; ?>" />
 375	<input type="hidden" name="mode" id="mode" value="<?php echo esc_attr($mode); ?>" />
 376	<?php
 377		wp_nonce_field( 'replyto-comment', '_ajax_nonce-replyto-comment', false );
 378		if ( current_user_can( 'unfiltered_html' ) )
 379			wp_nonce_field( 'unfiltered-html-comment', '_wp_unfiltered_html_comment', false );
 380	?>
 381<?php if ( $table_row ) : ?>
 382</td></tr></tbody></table>
 383<?php else : ?>
 384</div></div>
 385<?php endif; ?>
 386</form>
 387<?php
 388}
 389
 390/**
 391 * Output 'undo move to trash' text for comments
 392 *
 393 * @since 2.9.0
 394 */
 395function wp_comment_trashnotice() {
 396?>
 397<div class="hidden" id="trash-undo-holder">
 398	<div class="trash-undo-inside"><?php printf(__('Comment by %s moved to the trash.'), '<strong></strong>'); ?> <span class="undo untrash"><a href="#"><?php _e('Undo'); ?></a></span></div>
 399</div>
 400<div class="hidden" id="spam-undo-holder">
 401	<div class="spam-undo-inside"><?php printf(__('Comment by %s marked as spam.'), '<strong></strong>'); ?> <span class="undo unspam"><a href="#"><?php _e('Undo'); ?></a></span></div>
 402</div>
 403<?php
 404}
 405
 406/**
 407 * {@internal Missing Short Description}}
 408 *
 409 * @since 1.2.0
 410 *
 411 * @param unknown_type $meta
 412 */
 413function list_meta( $meta ) {
 414	// Exit if no meta
 415	if ( ! $meta ) {
 416		echo '
 417<table id="list-table" style="display: none;">
 418	<thead>
 419	<tr>
 420		<th class="left">' . _x( 'Name', 'meta name' ) . '</th>
 421		<th>' . __( 'Value' ) . '</th>
 422	</tr>
 423	</thead>
 424	<tbody id="the-list" data-wp-lists="list:meta">
 425	<tr><td></td></tr>
 426	</tbody>
 427</table>'; //TBODY needed for list-manipulation JS
 428		return;
 429	}
 430	$count = 0;
 431?>
 432<table id="list-table">
 433	<thead>
 434	<tr>
 435		<th class="left"><?php _ex( 'Name', 'meta name' ) ?></th>
 436		<th><?php _e( 'Value' ) ?></th>
 437	</tr>
 438	</thead>
 439	<tbody id='the-list' data-wp-lists='list:meta'>
 440<?php
 441	foreach ( $meta as $entry )
 442		echo _list_meta_row( $entry, $count );
 443?>
 444	</tbody>
 445</table>
 446<?php
 447}
 448
 449/**
 450 * {@internal Missing Short Description}}
 451 *
 452 * @since 2.5.0
 453 *
 454 * @param unknown_type $entry
 455 * @param unknown_type $count
 456 * @return unknown
 457 */
 458function _list_meta_row( $entry, &$count ) {
 459	static $update_nonce = false;
 460
 461	if ( is_protected_meta( $entry['meta_key'], 'post' ) )
 462		return;
 463
 464	if ( !$update_nonce )
 465		$update_nonce = wp_create_nonce( 'add-meta' );
 466
 467	$r = '';
 468	++ $count;
 469	if ( $count % 2 )
 470		$style = 'alternate';
 471	else
 472		$style = '';
 473
 474	if ( is_serialized( $entry['meta_value'] ) ) {
 475		if ( is_serialized_string( $entry['meta_value'] ) ) {
 476			// this is a serialized string, so we should display it
 477			$entry['meta_value'] = maybe_unserialize( $entry['meta_value'] );
 478		} else {
 479			// this is a serialized array/object so we should NOT display it
 480			--$count;
 481			return;
 482		}
 483	}
 484
 485	$entry['meta_key'] = esc_attr($entry['meta_key']);
 486	$entry['meta_value'] = esc_textarea( $entry['meta_value'] ); // using a <textarea />
 487	$entry['meta_id'] = (int) $entry['meta_id'];
 488
 489	$delete_nonce = wp_create_nonce( 'delete-meta_' . $entry['meta_id'] );
 490
 491	$r .= "\n\t<tr id='meta-{$entry['meta_id']}' class='$style'>";
 492	$r .= "\n\t\t<td class='left'><label class='screen-reader-text' for='meta[{$entry['meta_id']}][key]'>" . __( 'Key' ) . "</label><input name='meta[{$entry['meta_id']}][key]' id='meta[{$entry['meta_id']}][key]' type='text' size='20' value='{$entry['meta_key']}' />";
 493
 494	$r .= "\n\t\t<div class='submit'>";
 495	$r .= get_submit_button( __( 'Delete' ), 'deletemeta small', "deletemeta[{$entry['meta_id']}]", false, array( 'data-wp-lists' => "delete:the-list:meta-{$entry['meta_id']}::_ajax_nonce=$delete_nonce" ) );
 496	$r .= "\n\t\t";
 497	$r .= get_submit_button( __( 'Update' ), 'updatemeta small', "meta-{$entry['meta_id']}-submit", false, array( 'data-wp-lists' => "add:the-list:meta-{$entry['meta_id']}::_ajax_nonce-add-meta=$update_nonce" ) );
 498	$r .= "</div>";
 499	$r .= wp_nonce_field( 'change-meta', '_ajax_nonce', false, false );
 500	$r .= "</td>";
 501
 502	$r .= "\n\t\t<td><label class='screen-reader-text' for='meta[{$entry['meta_id']}][value]'>" . __( 'Value' ) . "</label><textarea name='meta[{$entry['meta_id']}][value]' id='meta[{$entry['meta_id']}][value]' rows='2' cols='30'>{$entry['meta_value']}</textarea></td>\n\t</tr>";
 503	return $r;
 504}
 505
 506/**
 507 * {@internal Missing Short Description}}
 508 *
 509 * @since 1.2.0
 510 */
 511function meta_form() {
 512	global $wpdb;
 513	$limit = (int) apply_filters( 'postmeta_form_limit', 30 );
 514	$keys = $wpdb->get_col( "
 515		SELECT meta_key
 516		FROM $wpdb->postmeta
 517		GROUP BY meta_key
 518		HAVING meta_key NOT LIKE '\_%'
 519		ORDER BY meta_key
 520		LIMIT $limit" );
 521	if ( $keys )
 522		natcasesort($keys);
 523?>
 524<p><strong><?php _e( 'Add New Custom Field:' ) ?></strong></p>
 525<table id="newmeta">
 526<thead>
 527<tr>
 528<th class="left"><label for="metakeyselect"><?php _ex( 'Name', 'meta name' ) ?></label></th>
 529<th><label for="metavalue"><?php _e( 'Value' ) ?></label></th>
 530</tr>
 531</thead>
 532
 533<tbody>
 534<tr>
 535<td id="newmetaleft" class="left">
 536<?php if ( $keys ) { ?>
 537<select id="metakeyselect" name="metakeyselect">
 538<option value="#NONE#"><?php _e( '&mdash; Select &mdash;' ); ?></option>
 539<?php
 540
 541	foreach ( $keys as $key ) {
 542		echo "\n<option value='" . esc_attr($key) . "'>" . esc_html($key) . "</option>";
 543	}
 544?>
 545</select>
 546<input class="hide-if-js" type="text" id="metakeyinput" name="metakeyinput" value="" />
 547<a href="#postcustomstuff" class="hide-if-no-js" onclick="jQuery('#metakeyinput, #metakeyselect, #enternew, #cancelnew').toggle();return false;">
 548<span id="enternew"><?php _e('Enter new'); ?></span>
 549<span id="cancelnew" class="hidden"><?php _e('Cancel'); ?></span></a>
 550<?php } else { ?>
 551<input type="text" id="metakeyinput" name="metakeyinput" value="" />
 552<?php } ?>
 553</td>
 554<td><textarea id="metavalue" name="metavalue" rows="2" cols="25"></textarea></td>
 555</tr>
 556
 557<tr><td colspan="2">
 558<div class="submit">
 559<?php submit_button( __( 'Add Custom Field' ), 'secondary', 'addmeta', false, array( 'id' => 'newmeta-submit', 'data-wp-lists' => 'add:the-list:newmeta' ) ); ?>
 560</div>
 561<?php wp_nonce_field( 'add-meta', '_ajax_nonce-add-meta', false ); ?>
 562</td></tr>
 563</tbody>
 564</table>
 565<?php
 566
 567}
 568
 569/**
 570 * {@internal Missing Short Description}}
 571 *
 572 * @since 0.71
 573 *
 574 * @param unknown_type $edit
 575 * @param unknown_type $for_post
 576 * @param unknown_type $tab_index
 577 * @param unknown_type $multi
 578 */
 579function touch_time( $edit = 1, $for_post = 1, $tab_index = 0, $multi = 0 ) {
 580	global $wp_locale, $comment;
 581	$post = get_post();
 582
 583	if ( $for_post )
 584		$edit = ! ( in_array($post->post_status, array('draft', 'pending') ) && (!$post->post_date_gmt || '0000-00-00 00:00:00' == $post->post_date_gmt ) );
 585
 586	$tab_index_attribute = '';
 587	if ( (int) $tab_index > 0 )
 588		$tab_index_attribute = " tabindex=\"$tab_index\"";
 589
 590	// 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 />';
 591
 592	$time_adj = current_time('timestamp');
 593	$post_date = ($for_post) ? $post->post_date : $comment->comment_date;
 594	$jj = ($edit) ? mysql2date( 'd', $post_date, false ) : gmdate( 'd', $time_adj );
 595	$mm = ($edit) ? mysql2date( 'm', $post_date, false ) : gmdate( 'm', $time_adj );
 596	$aa = ($edit) ? mysql2date( 'Y', $post_date, false ) : gmdate( 'Y', $time_adj );
 597	$hh = ($edit) ? mysql2date( 'H', $post_date, false ) : gmdate( 'H', $time_adj );
 598	$mn = ($edit) ? mysql2date( 'i', $post_date, false ) : gmdate( 'i', $time_adj );
 599	$ss = ($edit) ? mysql2date( 's', $post_date, false ) : gmdate( 's', $time_adj );
 600
 601	$cur_jj = gmdate( 'd', $time_adj );
 602	$cur_mm = gmdate( 'm', $time_adj );
 603	$cur_aa = gmdate( 'Y', $time_adj );
 604	$cur_hh = gmdate( 'H', $time_adj );
 605	$cur_mn = gmdate( 'i', $time_adj );
 606
 607	$month = "<select " . ( $multi ? '' : 'id="mm" ' ) . "name=\"mm\"$tab_index_attribute>\n";
 608	for ( $i = 1; $i < 13; $i = $i +1 ) {
 609		$monthnum = zeroise($i, 2);
 610		$month .= "\t\t\t" . '<option value="' . $monthnum . '"';
 611		if ( $i == $mm )
 612			$month .= ' selected="selected"';
 613		/* translators: 1: month number (01, 02, etc.), 2: month abbreviation */
 614		$month .= '>' . sprintf( __( '%1$s-%2$s' ), $monthnum, $wp_locale->get_month_abbrev( $wp_locale->get_month( $i ) ) ) . "</option>\n";
 615	}
 616	$month .= '</select>';
 617
 618	$day = '<input type="text" ' . ( $multi ? '' : 'id="jj" ' ) . 'name="jj" value="' . $jj . '" size="2" maxlength="2"' . $tab_index_attribute . ' autocomplete="off" />';
 619	$year = '<input type="text" ' . ( $multi ? '' : 'id="aa" ' ) . 'name="aa" value="' . $aa . '" size="4" maxlength="4"' . $tab_index_attribute . ' autocomplete="off" />';
 620	$hour = '<input type="text" ' . ( $multi ? '' : 'id="hh" ' ) . 'name="hh" value="' . $hh . '" size="2" maxlength="2"' . $tab_index_attribute . ' autocomplete="off" />';
 621	$minute = '<input type="text" ' . ( $multi ? '' : 'id="mn" ' ) . 'name="mn" value="' . $mn . '" size="2" maxlength="2"' . $tab_index_attribute . ' autocomplete="off" />';
 622
 623	echo '<div class="timestamp-wrap">';
 624	/* translators: 1: month input, 2: day input, 3: year input, 4: hour input, 5: minute input */
 625	printf(__('%1$s%2$s, %3$s @ %4$s : %5$s'), $month, $day, $year, $hour, $minute);
 626
 627	echo '</div><input type="hidden" id="ss" name="ss" value="' . $ss . '" />';
 628
 629	if ( $multi ) return;
 630
 631	echo "\n\n";
 632	foreach ( array('mm', 'jj', 'aa', 'hh', 'mn') as $timeunit ) {
 633		echo '<input type="hidden" id="hidden_' . $timeunit . '" name="hidden_' . $timeunit . '" value="' . $$timeunit . '" />' . "\n";
 634		$cur_timeunit = 'cur_' . $timeunit;
 635		echo '<input type="hidden" id="'. $cur_timeunit . '" name="'. $cur_timeunit . '" value="' . $$cur_timeunit . '" />' . "\n";
 636	}
 637?>
 638
 639<p>
 640<a href="#edit_timestamp" class="save-timestamp hide-if-no-js button"><?php _e('OK'); ?></a>
 641<a href="#edit_timestamp" class="cancel-timestamp hide-if-no-js"><?php _e('Cancel'); ?></a>
 642</p>
 643<?php
 644}
 645
 646/**
 647 * {@internal Missing Short Description}}
 648 *
 649 * @since 1.5.0
 650 *
 651 * @param unknown_type $default
 652 */
 653function page_template_dropdown( $default = '' ) {
 654	$templates = get_page_templates();
 655	ksort( $templates );
 656	foreach (array_keys( $templates ) as $template )
 657		: if ( $default == $templates[$template] )
 658			$selected = " selected='selected'";
 659		else
 660			$selected = '';
 661	echo "\n\t<option value='".$templates[$template]."' $selected>$template</option>";
 662	endforeach;
 663}
 664
 665/**
 666 * {@internal Missing Short Description}}
 667 *
 668 * @since 1.5.0
 669 *
 670 * @param unknown_type $default
 671 * @param unknown_type $parent
 672 * @param unknown_type $level
 673 * @return unknown
 674 */
 675function parent_dropdown( $default = 0, $parent = 0, $level = 0 ) {
 676	global $wpdb;
 677	$post = get_post();
 678	$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) );
 679
 680	if ( $items ) {
 681		foreach ( $items as $item ) {
 682			// A page cannot be its own parent.
 683			if ( $post->ID && $item->ID == $post->ID )
 684				continue;
 685
 686			$pad = str_repeat( '&nbsp;', $level * 3 );
 687			if ( $item->ID == $default)
 688				$current = ' selected="selected"';
 689			else
 690				$current = '';
 691
 692			echo "\n\t<option class='level-$level' value='$item->ID'$current>$pad " . esc_html($item->post_title) . "</option>";
 693			parent_dropdown( $default, $item->ID, $level +1 );
 694		}
 695	} else {
 696		return false;
 697	}
 698}
 699
 700/**
 701 * {@internal Missing Short Description}}
 702 *
 703 * @since 2.0.0
 704 *
 705 * @param unknown_type $id
 706 * @return unknown
 707 */
 708function the_attachment_links( $id = false ) {
 709	$id = (int) $id;
 710	$post = get_post( $id );
 711
 712	if ( $post->post_type != 'attachment' )
 713		return false;
 714
 715	$icon = wp_get_attachment_image( $post->ID, 'thumbnail', true );
 716	$attachment_data = wp_get_attachment_metadata( $id );
 717	$thumb = isset( $attachment_data['thumb'] );
 718?>
 719<form id="the-attachment-links">
 720<table>
 721	<col />
 722	<col class="widefat" />
 723	<tr>
 724		<th scope="row"><?php _e( 'URL' ) ?></th>
 725		<td><textarea rows="1" cols="40" type="text" class="attachmentlinks" readonly="readonly"><?php echo esc_textarea( wp_get_attachment_url() ); ?></textarea></td>
 726	</tr>
 727<?php if ( $icon ) : ?>
 728	<tr>
 729		<th scope="row"><?php $thumb ? _e( 'Thumbnail linked to file' ) : _e( 'Image linked to file' ); ?></th>
 730		<td><textarea rows="1" cols="40" type="text" class="attachmentlinks" readonly="readonly"><a href="<?php echo wp_get_attachment_url(); ?>"><?php echo $icon ?></a></textarea></td>
 731	</tr>
 732	<tr>
 733		<th scope="row"><?php $thumb ? _e( 'Thumbnail linked to page' ) : _e( 'Image linked to page' ); ?></th>
 734		<td><textarea rows="1" cols="40" type="text" class="attachmentlinks" readonly="readonly"><a href="<?php echo get_attachment_link( $post->ID ) ?>" rel="attachment wp-att-<?php echo $post->ID; ?>"><?php echo $icon ?></a></textarea></td>
 735	</tr>
 736<?php else : ?>
 737	<tr>
 738		<th scope="row"><?php _e( 'Link to file' ) ?></th>
 739		<td><textarea rows="1" cols="40" type="text" class="attachmentlinks" readonly="readonly"><a href="<?php echo wp_get_attachment_url(); ?>" class="attachmentlink"><?php echo basename( wp_get_attachment_url() ); ?></a></textarea></td>
 740	</tr>
 741	<tr>
 742		<th scope="row"><?php _e( 'Link to page' ) ?></th>
 743		<td><textarea rows="1" cols="40" type="text" class="attachmentlinks" readonly="readonly"><a href="<?php echo get_attachment_link( $post->ID ) ?>" rel="attachment wp-att-<?php echo $post->ID ?>"><?php the_title(); ?></a></textarea></td>
 744	</tr>
 745<?php endif; ?>
 746</table>
 747</form>
 748<?php
 749}
 750
 751/**
 752 * Print out <option> html elements for role selectors
 753 *
 754 * @since 2.1.0
 755 *
 756 * @param string $selected slug for the role that should be already selected
 757 */
 758function wp_dropdown_roles( $selected = false ) {
 759	$p = '';
 760	$r = '';
 761
 762	$editable_roles = get_editable_roles();
 763
 764	foreach ( $editable_roles as $role => $details ) {
 765		$name = translate_user_role($details['name'] );
 766		if ( $selected == $role ) // preselect specified role
 767			$p = "\n\t<option selected='selected' value='" . esc_attr($role) . "'>$name</option>";
 768		else
 769			$r .= "\n\t<option value='" . esc_attr($role) . "'>$name</option>";
 770	}
 771	echo $p . $r;
 772}
 773
 774/**
 775 * Outputs the form used by the importers to accept the data to be imported
 776 *
 777 * @since 2.0.0
 778 *
 779 * @param string $action The action attribute for the form.
 780 */
 781function wp_import_upload_form( $action ) {
 782	$bytes = apply_filters( 'import_upload_size_limit', wp_max_upload_size() );
 783	$size = wp_convert_bytes_to_hr( $bytes );
 784	$upload_dir = wp_upload_dir();
 785	if ( ! empty( $upload_dir['error'] ) ) :
 786		?><div class="error"><p><?php _e('Before you can upload your import file, you will need to fix the following error:'); ?></p>
 787		<p><strong><?php echo $upload_dir['error']; ?></strong></p></div><?php
 788	else :
 789?>
 790<form enctype="multipart/form-data" id="import-upload-form" method="post" class="wp-upload-form" action="<?php echo esc_attr(wp_nonce_url($action, 'import-upload')); ?>">
 791<p>
 792<label for="upload"><?php _e( 'Choose a file from your computer:' ); ?></label> (<?php printf( __('Maximum size: %s' ), $size ); ?>)
 793<input type="file" id="upload" name="import" size="25" />
 794<input type="hidden" name="action" value="save" />
 795<input type="hidden" name="max_file_size" value="<?php echo $bytes; ?>" />
 796</p>
 797<?php submit_button( __('Upload file and import'), 'button' ); ?>
 798</form>
 799<?php
 800	endif;
 801}
 802
 803/**
 804 * Add a meta box to an edit form.
 805 *
 806 * @since 2.5.0
 807 *
 808 * @param string $id String for use in the 'id' attribute of tags.
 809 * @param string $title Title of the meta box.
 810 * @param string $callback Function that fills the box with the desired content. The function should echo its output.
 811 * @param string|object $screen Optional. The screen on which to show the box (post, page, link). Defaults to current screen.
 812 * @param string $context Optional. The context within the page where the boxes should show ('normal', 'advanced').
 813 * @param string $priority Optional. The priority within the context where the boxes should show ('high', 'low').
 814 */
 815function add_meta_box( $id, $title, $callback, $screen = null, $context = 'advanced', $priority = 'default', $callback_args = null ) {
 816	global $wp_meta_boxes;
 817
 818	if ( empty( $screen ) )
 819		$screen = get_current_screen();
 820	elseif ( is_string( $screen ) )
 821		$screen = convert_to_screen( $screen );
 822
 823	$page = $screen->id;
 824
 825	if ( !isset($wp_meta_boxes) )
 826		$wp_meta_boxes = array();
 827	if ( !isset($wp_meta_boxes[$page]) )
 828		$wp_meta_boxes[$page] = array();
 829	if ( !isset($wp_meta_boxes[$page][$context]) )
 830		$wp_meta_boxes[$page][$context] = array();
 831
 832	foreach ( array_keys($wp_meta_boxes[$page]) as $a_context ) {
 833		foreach ( array('high', 'core', 'default', 'low') as $a_priority ) {
 834			if ( !isset($wp_meta_boxes[$page][$a_context][$a_priority][$id]) )
 835				continue;
 836
 837			// If a core box was previously added or removed by a plugin, don't add.
 838			if ( 'core' == $priority ) {
 839				// If core box previously deleted, don't add
 840				if ( false === $wp_meta_boxes[$page][$a_context][$a_priority][$id] )
 841					return;
 842				// If box was added with default priority, give it core priority to maintain sort order
 843				if ( 'default' == $a_priority ) {
 844					$wp_meta_boxes[$page][$a_context]['core'][$id] = $wp_meta_boxes[$page][$a_context]['default'][$id];
 845					unset($wp_meta_boxes[$page][$a_context]['default'][$id]);
 846				}
 847				return;
 848			}
 849			// If no priority given and id already present, use existing priority
 850			if ( empty($priority) ) {
 851				$priority = $a_priority;
 852			// else if we're adding to the sorted priority, we don't know the title or callback. Grab them from the previously added context/priority.
 853			} elseif ( 'sorted' == $priority ) {
 854				$title = $wp_meta_boxes[$page][$a_context][$a_priority][$id]['title'];
 855				$callback = $wp_meta_boxes[$page][$a_context][$a_priority][$id]['callback'];
 856				$callback_args = $wp_meta_boxes[$page][$a_context][$a_priority][$id]['args'];
 857			}
 858			// An id can be in only one priority and one context
 859			if ( $priority != $a_priority || $context != $a_context )
 860				unset($wp_meta_boxes[$page][$a_context][$a_priority][$id]);
 861		}
 862	}
 863
 864	if ( empty($priority) )
 865		$priority = 'low';
 866
 867	if ( !isset($wp_meta_boxes[$page][$context][$priority]) )
 868		$wp_meta_boxes[$page][$context][$priority] = array();
 869
 870	$wp_meta_boxes[$page][$context][$priority][$id] = array('id' => $id, 'title' => $title, 'callback' => $callback, 'args' => $callback_args);
 871}
 872
 873/**
 874 * Meta-Box template function
 875 *
 876 * @since 2.5.0
 877 *
 878 * @param string|object $screen Screen identifier
 879 * @param string $context box context
 880 * @param mixed $object gets passed to the box callback function as first parameter
 881 * @return int number of meta_boxes
 882 */
 883function do_meta_boxes( $screen, $context, $object ) {
 884	global $wp_meta_boxes;
 885	static $already_sorted = false;
 886
 887	if ( empty( $screen ) )
 888		$screen = get_current_screen();
 889	elseif ( is_string( $screen ) )
 890		$screen = convert_to_screen( $screen );
 891
 892	$page = $screen->id;
 893
 894	$hidden = get_hidden_meta_boxes( $screen );
 895
 896	printf('<div id="%s-sortables" class="meta-box-sortables">', htmlspecialchars($context));
 897
 898	$i = 0;
 899	do {
 900		// Grab the ones the user has manually sorted. Pull them out of their previous context/priority and into the one the user chose
 901		if ( !$already_sorted && $sorted = get_user_option( "meta-box-order_$page" ) ) {
 902			foreach ( $sorted as $box_context => $ids ) {
 903				foreach ( explode(',', $ids ) as $id ) {
 904					if ( $id && 'dashboard_browser_nag' !== $id )
 905						add_meta_box( $id, null, null, $screen, $box_context, 'sorted' );
 906				}
 907			}
 908		}
 909		$already_sorted = true;
 910
 911		if ( !isset($wp_meta_boxes) || !isset($wp_meta_boxes[$page]) || !isset($wp_meta_boxes[$page][$context]) )
 912			break;
 913
 914		foreach ( array('high', 'sorted', 'core', 'default', 'low') as $priority ) {
 915			if ( isset($wp_meta_boxes[$page][$context][$priority]) ) {
 916				foreach ( (array) $wp_meta_boxes[$page][$context][$priority] as $box ) {
 917					if ( false == $box || ! $box['title'] )
 918						continue;
 919					$i++;
 920					$style = '';
 921					$hidden_class = in_array($box['id'], $hidden) ? ' hide-if-js' : '';
 922					echo '<div id="' . $box['id'] . '" class="postbox ' . postbox_classes($box['id'], $page) . $hidden_class . '" ' . '>' . "\n";
 923					if ( 'dashboard_browser_nag' != $box['id'] )
 924						echo '<div class="handlediv" title="' . esc_attr__('Click to toggle') . '"><br /></div>';
 925					echo "<h3 class='hndle'><span>{$box['title']}</span></h3>\n";
 926					echo '<div class="inside">' . "\n";
 927					call_user_func($box['callback'], $object, $box);
 928					echo "</div>\n";
 929					echo "</div>\n";
 930				}
 931			}
 932		}
 933	} while(0);
 934
 935	echo "</div>";
 936
 937	return $i;
 938
 939}
 940
 941/**
 942 * Remove a meta box from an edit form.
 943 *
 944 * @since 2.6.0
 945 *
 946 * @param string $id String for use in the 'id' attribute of tags.
 947 * @param string|object $screen The screen on which to show the box (post, page, link).
 948 * @param string $context The context within the page where the boxes should show ('normal', 'advanced').
 949 */
 950function remove_meta_box($id, $screen, $context) {
 951	global $wp_meta_boxes;
 952
 953	if ( empty( $screen ) )
 954		$screen = get_current_screen();
 955	elseif ( is_string( $screen ) )
 956		$screen = convert_to_screen( $screen );
 957
 958	$page = $screen->id;
 959
 960	if ( !isset($wp_meta_boxes) )
 961		$wp_meta_boxes = array();
 962	if ( !isset($wp_meta_boxes[$page]) )
 963		$wp_meta_boxes[$page] = array();
 964	if ( !isset($wp_meta_boxes[$page][$context]) )
 965		$wp_meta_boxes[$page][$context] = array();
 966
 967	foreach ( array('high', 'core', 'default', 'low') as $priority )
 968		$wp_meta_boxes[$page][$context][$priority][$id] = false;
 969}
 970
 971/**
 972 * Add a new section to a settings page.
 973 *
 974 * Part of the Settings API. Use this to define new settings sections for an admin page.
 975 * Show settings sections in your admin page callback function with do_settings_sections().
 976 * Add settings fields to your section with add_settings_field()
 977 *
 978 * The $callback argument should be the name of a function that echoes out any
 979 * content you want to show at the top of the settings section before the actual
 980 * fields. It can output nothing if you want.
 981 *
 982 * @since 2.7.0
 983 *
 984 * @global $wp_settings_sections Storage array of all settings sections added to admin pages
 985 *
 986 * @param string $id Slug-name to identify the section. Used in the 'id' attribute of tags.
 987 * @param string $title Formatted title of the section. Shown as the heading for the section.
 988 * @param string $callback Function that echos out any content at the top of the section (between heading and fields).
 989 * @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();
 990 */
 991function add_settings_section($id, $title, $callback, $page) {
 992	global $wp_settings_sections;
 993
 994	if ( 'misc' == $page ) {
 995		_deprecated_argument( __FUNCTION__, '3.0', sprintf( __( 'The "%s" options group has been removed. Use another settings group.' ), 'misc' ) );
 996		$page = 'general';
 997	}
 998
 999	if ( 'privacy' == $page ) {
1000		_deprecated_argument( __FUNCTION__, '3.5', sprintf( __( 'The "%s" options group has been removed. Use another settings group.' ), 'privacy' ) );
1001		$page = 'reading';
1002	}
1003
1004	if ( !isset($wp_settings_sections) )
1005		$wp_settings_sections = array();
1006	if ( !isset($wp_settings_sections[$page]) )
1007		$wp_settings_sections[$page] = array();
1008	if ( !isset($wp_settings_sections[$page][$id]) )
1009		$wp_settings_sections[$page][$id] = array();
1010
1011	$wp_settings_sections[$page][$id] = array('id' => $id, 'title' => $title, 'callback' => $callback);
1012}
1013
1014/**
1015 * Add a new field to a section of a settings page
1016 *
1017 * Part of the Settings API. Use this to define a settings field that will show
1018 * as part of a settings section inside a settings page. The fields are shown using
1019 * do_settings_fields() in do_settings-sections()
1020 *
1021 * The $callback argument should be the name of a function that echoes out the
1022 * html input tags for this setting field. Use get_option() to retrieve existing
1023 * values to show.
1024 *
1025 * @since 2.7.0
1026 *
1027 * @global $wp_settings_fields Storage array of settings fields and info about their pages/sections
1028 *
1029 * @param string $id Slug-name to identify the field. Used in the 'id' attribute of tags.
1030 * @param string $title Formatted title of the field. Shown as the label for the field during output.
1031 * @param string $callback Function that fills the field with the desired form inputs. The function should echo its output.
1032 * @param string $page The slug-name of the settings page on which to show the section (general, reading, writing, ...).
1033 * @param string $section The slug-name of the section of the settings page in which to show the box (default, ...).
1034 * @param array $args Additional arguments
1035 */
1036function add_settings_field($id, $title, $callback, $page, $section = 'default', $args = array()) {
1037	global $wp_settings_fields;
1038
1039	if ( 'misc' == $page ) {
1040		_deprecated_argument( __FUNCTION__, '3.0', __( 'The miscellaneous options group has been removed. Use another settings group.' ) );
1041		$page = 'general';
1042	}
1043
1044	if ( 'privacy' == $page ) {
1045		_deprecated_argument( __FUNCTION__, '3.5', __( 'The privacy options group has been removed. Use another settings group.' ) );
1046		$page = 'reading';
1047	}
1048
1049	if ( !isset($wp_settings_fields) )
1050		$wp_settings_fields = array();
1051	if ( !isset($wp_settings_fields[$page]) )
1052		$wp_settings_fields[$page] = array();
1053	if ( !isset($wp_settings_fields[$page][$section]) )
1054		$wp_settings_fields[$page][$section] = array();
1055
1056	$wp_settings_fields[$page][$section][$id] = array('id' => $id, 'title' => $title, 'callback' => $callback, 'args' => $args);
1057}
1058
1059/**
1060 * Prints out all settings sections added to a particular settings page
1061 *
1062 * Part of the Settings API. Use this in a settings page callback function
1063 * to output all the sections and fields that were added to that $page with
1064 * add_settings_section() and add_settings_field()
1065 *
1066 * @global $wp_settings_sections Storage array of all settings sections added to admin pages
1067 * @global $wp_settings_fields Storage array of settings fields and info about their pages/sections
1068 * @since 2.7.0
1069 *
1070 * @param string $page The slug name of the page whos settings sections you want to output
1071 */
1072function do_settings_sections( $page ) {
1073	global $wp_settings_sections, $wp_settings_fields;
1074
1075	if ( ! isset( $wp_settings_sections ) || !isset( $wp_settings_sections[$page] ) )
1076		return;
1077
1078	foreach ( (array) $wp_settings_sections[$page] as $section ) {
1079		if ( $section['title'] )
1080			echo "<h3>{$section['title']}</h3>\n";
1081
1082		if ( $section['callback'] )
1083			call_user_func( $section['callback'], $section );
1084
1085		if ( ! isset( $wp_settings_fields ) || !isset( $wp_settings_fields[$page] ) || !isset( $wp_settings_fields[$page][$section['id']] ) )
1086			continue;
1087		echo '<table class="form-table">';
1088		do_settings_fields( $page, $section['id'] );
1089		echo '</table>';
1090	}
1091}
1092
1093/**
1094 * Print out the settings fields for a particular settings section
1095 *
1096 * Part of the Settings API. Use this in a settings page to output
1097 * a specific section. Should normally be called by do_settings_sections()
1098 * rather than directly.
1099 *
1100 * @global $wp_settings_fields Storage array of settings fields and their pages/sections
1101 *
1102 * @since 2.7.0
1103 *
1104 * @param string $page Slug title of the admin page who's settings fields you want to show.
1105 * @param section $section Slug title of the settings section who's fields you want to show.
1106 */
1107function do_settings_fields($page, $section) {
1108	global $wp_settings_fields;
1109
1110	if ( !isset($wp_settings_fields) || !isset($wp_settings_fields[$page]) || !isset($wp_settings_fields[$page][$section]) )
1111		return;
1112
1113	foreach ( (array) $wp_settings_fields[$page][$section] as $field ) {
1114		echo '<tr valign="top">';
1115		if ( !empty($field['args']['label_for']) )
1116			echo '<th scope="row"><label for="' . esc_attr( $field['args']['label_for'] ) . '">' . $field['title'] . '</label></th>';
1117		else
1118			echo '<th scope="row">' . $field['title'] . '</th>';
1119		echo '<td>';
1120		call_user_func($field['callback'], $field['args']);
1121		echo '</td>';
1122		echo '</tr>';
1123	}
1124}
1125
1126/**
1127 * Register a settings error to be displayed to the user
1128 *
1129 * Part of the Settings API. Use this to show messages to users about settings validation
1130 * problems, missing settings or anything else.
1131 *
1132 * Settings errors should be added inside the $sanitize_callback function defined in
1133 * register_setting() for a given setting to give feedback about the submission.
1134 *
1135 * By default messages will show immediately after the submission that generated the error.
1136 * Additional calls to settings_errors() can be used to show errors even when the settings
1137 * page is first accessed.
1138 *
1139 * @since 3.0.0
1140 *
1141 * @global array $wp_settings_errors Storage array of errors registered during this pageload
1142 *
1143 * @param string $setting Slug title of the setting to which this error applies
1144 * @param string $code Slug-name to identify the error. Used as part of 'id' attribute in HTML output.
1145 * @param string $message The formatted message text to display to the user (will be shown inside styled <div> and <p>)
1146 * @param string $type The type of message it is, controls HTML class. Use 'error' or 'updated'.
1147 */
1148function add_settings_error( $setting, $code, $message, $type = 'error' ) {
1149	global $wp_settings_errors;
1150
1151	if ( !isset($wp_settings_errors) )
1152		$wp_settings_errors = array();
1153
1154	$new_error = array(
1155		'setting' => $setting,
1156		'code' => $code,
1157		'message' => $message,
1158		'type' => $type
1159	);
1160	$wp_settings_errors[] = $new_error;
1161}
1162
1163/**
1164 * Fetch settings errors registered by add_settings_error()
1165 *
1166 * Checks the $wp_settings_errors array for any errors declared during the current
1167 * pageload and returns them.
1168 *
1169 * If changes were just submitted ($_GET['settings-updated']) and settings errors were saved
1170 * to the 'settings_errors' transient then those errors will be returned instead. This
1171 * is used to pass errors back across pageloads.
1172 *
1173 * Use the $sanitize argument to manually re-sanitize the option before returning errors.
1174 * This is useful if you have errors or notices you want to show even when the user
1175 * hasn't submitted data (i.e. when they first load an options page, or in admin_notices action hook)
1176 *
1177 * @since 3.0.0
1178 *
1179 * @global array $wp_settings_errors Storage array of errors registered during this pageload
1180 *
1181 * @param string $setting Optional slug title of a specific setting who's errors you want.
1182 * @param boolean $sanitize Whether to re-sanitize the setting value before returning errors.
1183 * @return array Array of settings errors
1184 */
1185function get_settings_errors( $setting = '', $sanitize = false ) {
1186	global $wp_settings_errors;
1187
1188	// If $sanitize is true, manually re-run the sanitizisation for this option
1189	// This allows the $sanitize_callback from register_setting() to run, adding
1190	// any settings errors you want to show by default.
1191	if ( $sanitize )
1192		sanitize_option( $setting, get_option( $setting ) );
1193
1194	// If settings were passed back from options.php then use them
1195	if ( isset( $_GET['settings-updated'] ) && $_GET['settings-updated'] && get_transient( 'settings_errors' ) ) {
1196		$wp_settings_errors = array_merge( (array) $wp_settings_errors, get_transient( 'settings_errors' ) );
1197		delete_transient( 'settings_errors' );
1198	}
1199
1200	// Check global in case errors have been added on this pageload
1201	if ( ! count( $wp_settings_errors ) )
1202		return array();
1203
1204	// Filter the results to those of a specific setting if one was set
1205	if ( $setting ) {
1206		$setting_errors = array();
1207		foreach ( (array) $wp_settings_errors as $key => $details ) {
1208			if ( $setting == $details['setting'] )
1209				$setting_errors[] = $wp_settings_errors[$key];
1210		}
1211		return $setting_errors;
1212	}
1213
1214	return $wp_settings_errors;
1215}
1216
1217/**
1218 * Display settings errors registered by add_settings_error()
1219 *
1220 * Part of the Settings API. Outputs a <div> for each error retrieved by get_settings_errors().
1221 *
1222 * This is called automatically after a settings page based on the Settings API is submitted.
1223 * Errors should be added during the validation callback function for a setting defined in register_setting()
1224 *
1225 * The $sanitize option is passed into get_settings_errors() and will re-run the setting sanitization
1226 * on its current value.
1227 *
1228 * The $hide_on_update option will cause errors to only show when the settings page is first loaded.
1229 * if the user has already saved new values it will be hidden to avoid repeating messages already
1230 * shown in the default error reporting after submission. This is useful to show general errors like missing
1231 * settings when the user arrives at the settings page.
1232 *
1233 * @since 3.0.0
1234 *
1235 * @param string $setting Optional slug title of a specific setting who's errors you want.
1236 * @param boolean $sanitize Whether to re-sanitize the setting value before returning errors.
1237 * @param boolean $hide_on_update If set to true errors will not be shown if the settings page has already been submitted.
1238 */
1239function settings_errors( $setting = '', $sanitize = false, $hide_on_update = false ) {
1240
1241	if ( $hide_on_update && ! empty( $_GET['settings-updated'] ) )
1242		return;
1243
1244	$settings_errors = get_settings_errors( $setting, $sanitize );
1245
1246	if ( empty( $settings_errors ) )
1247		return;
1248
1249	$output = '';
1250	foreach ( $settings_errors as $key => $details ) {
1251		$css_id = 'setting-error-' . $details['code'];
1252		$css_class = $details['type'] . ' settings-error';
1253		$output .= "<div id='$css_id' class='$css_class'> \n";
1254		$output .= "<p><strong>{$details['message']}</strong></p>";
1255		$output .= "</div> \n";
1256	}
1257	echo $output;
1258}
1259
1260/**
1261 * {@internal Missing Short Description}}
1262 *
1263 * @since 2.7.0
1264 *
1265 * @param unknown_type $found_action
1266 */
1267function find_posts_div($found_action = '') {
1268?>
1269	<div id="find-posts" class="find-box" style="display:none;">
1270		<div id="find-posts-head" class="find-box-head"><?php _e('Find Posts or Pages'); ?></div>
1271		<div class="find-box-inside">
1272			<div class="find-box-search">
1273				<?php if ( $found_action ) { ?>
1274					<input type="hidden" name="found_action" value="<?php echo esc_attr($found_action); ?>" />
1275				<?php } ?>
1276
1277				<input type="hidden" name="affected" id="affected" value="" />
1278				<?php wp_nonce_field( 'find-posts', '_ajax_nonce', false ); ?>
1279				<label class="screen-reader-text" for="find-posts-input"><?php _e( 'Search' ); ?></label>
1280				<input type="text" id="find-posts-input" name="ps" value="" />
1281				<span class="spinner"></span>
1282				<input type="button" id="find-posts-search" value="<?php esc_attr_e( 'Search' ); ?>" class="button" />
1283			</div>
1284			<div id="find-posts-response"></div>
1285		</div>
1286		<div class="find-box-buttons">
1287			<input id="find-posts-close" type="button" class="button alignleft" value="<?php esc_attr_e('Close'); ?>" />
1288			<?php submit_button( __( 'Select' ), 'button-primary alignright', 'find-posts-submit', false ); ?>
1289		</div>
1290	</div>
1291<?php
1292}
1293
1294/**
1295 * Display the post password.
1296 *
1297 * The password is passed through {@link esc_attr()} to ensure that it
1298 * is safe for placing in an html attribute.
1299 *
1300 * @uses attr
1301 * @since 2.7.0
1302 */
1303function the_post_password() {
1304	$post = get_post();
1305	if ( isset( $post->post_password ) )
1306		echo esc_attr( $post->post_password );
1307}
1308
1309/**
1310 * Get the post title.
1311 *
1312 * The post title is fetched and if it is blank then a default string is
1313 * returned.
1314 *
1315 * @since 2.7.0
1316 * @param mixed $post Post id or object. If not supplied the global $post is used.
1317 * @return string The post title if set
1318 */
1319function _draft_or_post_title( $post = 0 ) {
1320	$title = get_the_title( $post );
1321	if ( empty( $title ) )
1322		$title = __( '(no title)' );
1323	return $title;
1324}
1325
1326/**
1327 * Display the search query.
1328 *
1329 * A simple wrapper to display the "s" parameter in a GET URI. This function
1330 * should only be used when {@link the_search_query()} cannot.
1331 *
1332 * @uses attr
1333 * @since 2.7.0
1334 *
1335 */
1336function _admin_search_query() {
1337	echo isset($_REQUEST['s']) ? esc_attr( stripslashes( $_REQUEST['s'] ) ) : '';
1338}
1339
1340/**
1341 * Generic Iframe header for use with Thickbox
1342 *
1343 * @since 2.7.0
1344 * @param string $title Title of the Iframe page.
1345 * @param bool $limit_styles Limit styles to colour-related styles only (unless others are enqueued).
1346 *
1347 */
1348function iframe_header( $title = '', $limit_styles = false ) {
1349	show_admin_bar( false );
1350	global $hook_suffix, $current_user, $admin_body_class, $wp_locale;
1351	$admin_body_class = preg_replace('/[^a-z0-9_-]+/i', '-', $hook_suffix);
1352
1353	$current_screen = get_current_screen();
1354
1355	@header( 'Cont…

Large files files are truncated, but you can click here to view the full file