[ Index ] |
WordPress Cross Reference |
[Summary view] [Print] [Text view]
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 */ 23 class 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 /** 28 * Starts the list before the elements are added. 29 * 30 * @see Walker:start_lvl() 31 * 32 * @since 2.5.1 33 * 34 * @param string $output Passed by reference. Used to append additional content. 35 * @param int $depth Depth of category. Used for tab indentation. 36 * @param array $args An array of arguments. @see wp_terms_checklist() 37 */ 38 function start_lvl( &$output, $depth = 0, $args = array() ) { 39 $indent = str_repeat("\t", $depth); 40 $output .= "$indent<ul class='children'>\n"; 41 } 42 43 /** 44 * Ends the list of after the elements are added. 45 * 46 * @see Walker::end_lvl() 47 * 48 * @since 2.5.1 49 * 50 * @param string $output Passed by reference. Used to append additional content. 51 * @param int $depth Depth of category. Used for tab indentation. 52 * @param array $args An array of arguments. @see wp_terms_checklist() 53 */ 54 function end_lvl( &$output, $depth = 0, $args = array() ) { 55 $indent = str_repeat("\t", $depth); 56 $output .= "$indent</ul>\n"; 57 } 58 59 /** 60 * Start the element output. 61 * 62 * @see Walker::start_el() 63 * 64 * @since 2.5.1 65 * 66 * @param string $output Passed by reference. Used to append additional content. 67 * @param object $category The current term object. 68 * @param int $depth Depth of the term in reference to parents. Default 0. 69 * @param array $args An array of arguments. @see wp_terms_checklist() 70 * @param int $id ID of the current term. 71 */ 72 function start_el( &$output, $category, $depth = 0, $args = array(), $id = 0 ) { 73 extract($args); 74 if ( empty($taxonomy) ) 75 $taxonomy = 'category'; 76 77 if ( $taxonomy == 'category' ) 78 $name = 'post_category'; 79 else 80 $name = 'tax_input['.$taxonomy.']'; 81 82 $class = in_array( $category->term_id, $popular_cats ) ? ' class="popular-category"' : ''; 83 $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>'; 84 } 85 86 /** 87 * Ends the element output, if needed. 88 * 89 * @see Walker::end_el() 90 * 91 * @since 2.5.1 92 * 93 * @param string $output Passed by reference. Used to append additional content. 94 * @param object $category The current term object. 95 * @param int $depth Depth of the term in reference to parents. Default 0. 96 * @param array $args An array of arguments. @see wp_terms_checklist() 97 */ 98 function end_el( &$output, $category, $depth = 0, $args = array() ) { 99 $output .= "</li>\n"; 100 } 101 } 102 103 /** 104 * Output an unordered list of checkbox <input> elements labelled 105 * with category names. 106 * 107 * @see wp_terms_checklist() 108 * @since 2.5.1 109 * 110 * @param int $post_id Mark categories associated with this post as checked. $selected_cats must not be an array. 111 * @param int $descendants_and_self ID of the category to output along with its descendents. 112 * @param bool|array $selected_cats List of categories to mark as checked. 113 * @param bool|array $popular_cats Override the list of categories that receive the "popular-category" class. 114 * @param object $walker Walker object to use to build the output. 115 * @param bool $checked_ontop Move checked items out of the hierarchy and to the top of the list. 116 */ 117 function wp_category_checklist( $post_id = 0, $descendants_and_self = 0, $selected_cats = false, $popular_cats = false, $walker = null, $checked_ontop = true ) { 118 wp_terms_checklist( $post_id, array( 119 'taxonomy' => 'category', 120 'descendants_and_self' => $descendants_and_self, 121 'selected_cats' => $selected_cats, 122 'popular_cats' => $popular_cats, 123 'walker' => $walker, 124 'checked_ontop' => $checked_ontop 125 ) ); 126 } 127 128 /** 129 * Output an unordered list of checkbox <input> elements labelled 130 * with term names. Taxonomy independent version of wp_category_checklist(). 131 * 132 * @since 3.0.0 133 * 134 * @param int $post_id 135 * @param array $args 136 */ 137 function wp_terms_checklist($post_id = 0, $args = array()) { 138 $defaults = array( 139 'descendants_and_self' => 0, 140 'selected_cats' => false, 141 'popular_cats' => false, 142 'walker' => null, 143 'taxonomy' => 'category', 144 'checked_ontop' => true 145 ); 146 $args = apply_filters( 'wp_terms_checklist_args', $args, $post_id ); 147 148 extract( wp_parse_args($args, $defaults), EXTR_SKIP ); 149 150 if ( empty($walker) || !is_a($walker, 'Walker') ) 151 $walker = new Walker_Category_Checklist; 152 153 $descendants_and_self = (int) $descendants_and_self; 154 155 $args = array('taxonomy' => $taxonomy); 156 157 $tax = get_taxonomy($taxonomy); 158 $args['disabled'] = !current_user_can($tax->cap->assign_terms); 159 160 if ( is_array( $selected_cats ) ) 161 $args['selected_cats'] = $selected_cats; 162 elseif ( $post_id ) 163 $args['selected_cats'] = wp_get_object_terms($post_id, $taxonomy, array_merge($args, array('fields' => 'ids'))); 164 else 165 $args['selected_cats'] = array(); 166 167 if ( is_array( $popular_cats ) ) 168 $args['popular_cats'] = $popular_cats; 169 else 170 $args['popular_cats'] = get_terms( $taxonomy, array( 'fields' => 'ids', 'orderby' => 'count', 'order' => 'DESC', 'number' => 10, 'hierarchical' => false ) ); 171 172 if ( $descendants_and_self ) { 173 $categories = (array) get_terms($taxonomy, array( 'child_of' => $descendants_and_self, 'hierarchical' => 0, 'hide_empty' => 0 ) ); 174 $self = get_term( $descendants_and_self, $taxonomy ); 175 array_unshift( $categories, $self ); 176 } else { 177 $categories = (array) get_terms($taxonomy, array('get' => 'all')); 178 } 179 180 if ( $checked_ontop ) { 181 // 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) 182 $checked_categories = array(); 183 $keys = array_keys( $categories ); 184 185 foreach( $keys as $k ) { 186 if ( in_array( $categories[$k]->term_id, $args['selected_cats'] ) ) { 187 $checked_categories[] = $categories[$k]; 188 unset( $categories[$k] ); 189 } 190 } 191 192 // Put checked cats on top 193 echo call_user_func_array(array(&$walker, 'walk'), array($checked_categories, 0, $args)); 194 } 195 // Then the rest of them 196 echo call_user_func_array(array(&$walker, 'walk'), array($categories, 0, $args)); 197 } 198 199 /** 200 * Retrieve a list of the most popular terms from the specified taxonomy. 201 * 202 * If the $echo argument is true then the elements for a list of checkbox 203 * <input> elements labelled with the names of the selected terms is output. 204 * If the $post_ID global isn't empty then the terms associated with that 205 * post will be marked as checked. 206 * 207 * @since 2.5.0 208 * 209 * @param string $taxonomy Taxonomy to retrieve terms from. 210 * @param int $default Unused. 211 * @param int $number Number of terms to retrieve. Defaults to 10. 212 * @param bool $echo Optionally output the list as well. Defaults to true. 213 * @return array List of popular term IDs. 214 */ 215 function wp_popular_terms_checklist( $taxonomy, $default = 0, $number = 10, $echo = true ) { 216 $post = get_post(); 217 218 if ( $post && $post->ID ) 219 $checked_terms = wp_get_object_terms($post->ID, $taxonomy, array('fields'=>'ids')); 220 else 221 $checked_terms = array(); 222 223 $terms = get_terms( $taxonomy, array( 'orderby' => 'count', 'order' => 'DESC', 'number' => $number, 'hierarchical' => false ) ); 224 225 $tax = get_taxonomy($taxonomy); 226 227 $popular_ids = array(); 228 foreach ( (array) $terms as $term ) { 229 $popular_ids[] = $term->term_id; 230 if ( !$echo ) // hack for AJAX use 231 continue; 232 $id = "popular-$taxonomy-$term->term_id"; 233 $checked = in_array( $term->term_id, $checked_terms ) ? 'checked="checked"' : ''; 234 ?> 235 236 <li id="<?php echo $id; ?>" class="popular-category"> 237 <label class="selectit"> 238 <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 ) ); ?> /> 239 <?php echo esc_html( apply_filters( 'the_category', $term->name ) ); ?> 240 </label> 241 </li> 242 243 <?php 244 } 245 return $popular_ids; 246 } 247 248 /** 249 * {@internal Missing Short Description}} 250 * 251 * @since 2.5.1 252 * 253 * @param unknown_type $link_id 254 */ 255 function wp_link_category_checklist( $link_id = 0 ) { 256 $default = 1; 257 258 if ( $link_id ) { 259 $checked_categories = wp_get_link_cats( $link_id ); 260 // No selected categories, strange 261 if ( ! count( $checked_categories ) ) 262 $checked_categories[] = $default; 263 } else { 264 $checked_categories[] = $default; 265 } 266 267 $categories = get_terms( 'link_category', array( 'orderby' => 'name', 'hide_empty' => 0 ) ); 268 269 if ( empty( $categories ) ) 270 return; 271 272 foreach ( $categories as $category ) { 273 $cat_id = $category->term_id; 274 $name = esc_html( apply_filters( 'the_category', $category->name ) ); 275 $checked = in_array( $cat_id, $checked_categories ) ? ' checked="checked"' : ''; 276 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>"; 277 } 278 } 279 280 // adds hidden fields with the data for use in the inline editor for posts and pages 281 /** 282 * {@internal Missing Short Description}} 283 * 284 * @since 2.7.0 285 * 286 * @param unknown_type $post 287 */ 288 function get_inline_data($post) { 289 $post_type_object = get_post_type_object($post->post_type); 290 if ( ! current_user_can( 'edit_post', $post->ID ) ) 291 return; 292 293 $title = esc_textarea( trim( $post->post_title ) ); 294 295 echo ' 296 <div class="hidden" id="inline_' . $post->ID . '"> 297 <div class="post_title">' . $title . '</div> 298 <div class="post_name">' . apply_filters('editable_slug', $post->post_name) . '</div> 299 <div class="post_author">' . $post->post_author . '</div> 300 <div class="comment_status">' . esc_html( $post->comment_status ) . '</div> 301 <div class="ping_status">' . esc_html( $post->ping_status ) . '</div> 302 <div class="_status">' . esc_html( $post->post_status ) . '</div> 303 <div class="jj">' . mysql2date( 'd', $post->post_date, false ) . '</div> 304 <div class="mm">' . mysql2date( 'm', $post->post_date, false ) . '</div> 305 <div class="aa">' . mysql2date( 'Y', $post->post_date, false ) . '</div> 306 <div class="hh">' . mysql2date( 'H', $post->post_date, false ) . '</div> 307 <div class="mn">' . mysql2date( 'i', $post->post_date, false ) . '</div> 308 <div class="ss">' . mysql2date( 's', $post->post_date, false ) . '</div> 309 <div class="post_password">' . esc_html( $post->post_password ) . '</div>'; 310 311 if ( $post_type_object->hierarchical ) 312 echo '<div class="post_parent">' . $post->post_parent . '</div>'; 313 314 if ( $post->post_type == 'page' ) 315 echo '<div class="page_template">' . esc_html( get_post_meta( $post->ID, '_wp_page_template', true ) ) . '</div>'; 316 317 if ( post_type_supports( $post->post_type, 'page-attributes' ) ) 318 echo '<div class="menu_order">' . $post->menu_order . '</div>'; 319 320 $taxonomy_names = get_object_taxonomies( $post->post_type ); 321 foreach ( $taxonomy_names as $taxonomy_name) { 322 $taxonomy = get_taxonomy( $taxonomy_name ); 323 324 if ( $taxonomy->hierarchical && $taxonomy->show_ui ) { 325 echo '<div class="post_category" id="' . $taxonomy_name . '_' . $post->ID . '">' 326 . implode( ',', wp_get_object_terms( $post->ID, $taxonomy_name, array( 'fields' => 'ids' ) ) ) . '</div>'; 327 } elseif ( $taxonomy->show_ui ) { 328 echo '<div class="tags_input" id="'.$taxonomy_name.'_'.$post->ID.'">' 329 . esc_html( str_replace( ',', ', ', get_terms_to_edit( $post->ID, $taxonomy_name ) ) ) . '</div>'; 330 } 331 } 332 333 if ( !$post_type_object->hierarchical ) 334 echo '<div class="sticky">' . (is_sticky($post->ID) ? 'sticky' : '') . '</div>'; 335 336 if ( post_type_supports( $post->post_type, 'post-formats' ) ) 337 echo '<div class="post_format">' . esc_html( get_post_format( $post->ID ) ) . '</div>'; 338 339 echo '</div>'; 340 } 341 342 /** 343 * {@internal Missing Short Description}} 344 * 345 * @since 2.7.0 346 * 347 * @param unknown_type $position 348 * @param unknown_type $checkbox 349 * @param unknown_type $mode 350 */ 351 function wp_comment_reply($position = '1', $checkbox = false, $mode = 'single', $table_row = true) { 352 // allow plugin to replace the popup content 353 $content = apply_filters( 'wp_comment_reply', '', array('position' => $position, 'checkbox' => $checkbox, 'mode' => $mode) ); 354 355 if ( ! empty($content) ) { 356 echo $content; 357 return; 358 } 359 360 if ( $mode == 'single' ) { 361 $wp_list_table = _get_list_table('WP_Post_Comments_List_Table'); 362 } else { 363 $wp_list_table = _get_list_table('WP_Comments_List_Table'); 364 } 365 366 ?> 367 <form method="get" action=""> 368 <?php if ( $table_row ) : ?> 369 <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"> 370 <?php else : ?> 371 <div id="com-reply" style="display:none;"><div id="replyrow" style="display:none;"> 372 <?php endif; ?> 373 <div id="replyhead" style="display:none;"><h5><?php _e( 'Reply to Comment' ); ?></h5></div> 374 <div id="addhead" style="display:none;"><h5><?php _e('Add new Comment'); ?></h5></div> 375 <div id="edithead" style="display:none;"> 376 <div class="inside"> 377 <label for="author"><?php _e('Name') ?></label> 378 <input type="text" name="newcomment_author" size="50" value="" id="author" /> 379 </div> 380 381 <div class="inside"> 382 <label for="author-email"><?php _e('E-mail') ?></label> 383 <input type="text" name="newcomment_author_email" size="50" value="" id="author-email" /> 384 </div> 385 386 <div class="inside"> 387 <label for="author-url"><?php _e('URL') ?></label> 388 <input type="text" id="author-url" name="newcomment_author_url" size="103" value="" /> 389 </div> 390 <div style="clear:both;"></div> 391 </div> 392 393 <div id="replycontainer"> 394 <?php 395 $quicktags_settings = array( 'buttons' => 'strong,em,link,block,del,ins,img,ul,ol,li,code,close' ); 396 wp_editor( '', 'replycontent', array( 'media_buttons' => false, 'tinymce' => false, 'quicktags' => $quicktags_settings ) ); 397 ?> 398 </div> 399 400 <p id="replysubmit" class="submit"> 401 <a href="#comments-form" class="save button-primary alignright"> 402 <span id="addbtn" style="display:none;"><?php _e('Add Comment'); ?></span> 403 <span id="savebtn" style="display:none;"><?php _e('Update Comment'); ?></span> 404 <span id="replybtn" style="display:none;"><?php _e('Submit Reply'); ?></span></a> 405 <a href="#comments-form" class="cancel button-secondary alignleft"><?php _e('Cancel'); ?></a> 406 <span class="waiting spinner"></span> 407 <span class="error" style="display:none;"></span> 408 <br class="clear" /> 409 </p> 410 411 <input type="hidden" name="user_ID" id="user_ID" value="<?php echo get_current_user_id(); ?>" /> 412 <input type="hidden" name="action" id="action" value="" /> 413 <input type="hidden" name="comment_ID" id="comment_ID" value="" /> 414 <input type="hidden" name="comment_post_ID" id="comment_post_ID" value="" /> 415 <input type="hidden" name="status" id="status" value="" /> 416 <input type="hidden" name="position" id="position" value="<?php echo $position; ?>" /> 417 <input type="hidden" name="checkbox" id="checkbox" value="<?php echo $checkbox ? 1 : 0; ?>" /> 418 <input type="hidden" name="mode" id="mode" value="<?php echo esc_attr($mode); ?>" /> 419 <?php 420 wp_nonce_field( 'replyto-comment', '_ajax_nonce-replyto-comment', false ); 421 if ( current_user_can( 'unfiltered_html' ) ) 422 wp_nonce_field( 'unfiltered-html-comment', '_wp_unfiltered_html_comment', false ); 423 ?> 424 <?php if ( $table_row ) : ?> 425 </td></tr></tbody></table> 426 <?php else : ?> 427 </div></div> 428 <?php endif; ?> 429 </form> 430 <?php 431 } 432 433 /** 434 * Output 'undo move to trash' text for comments 435 * 436 * @since 2.9.0 437 */ 438 function wp_comment_trashnotice() { 439 ?> 440 <div class="hidden" id="trash-undo-holder"> 441 <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> 442 </div> 443 <div class="hidden" id="spam-undo-holder"> 444 <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> 445 </div> 446 <?php 447 } 448 449 /** 450 * {@internal Missing Short Description}} 451 * 452 * @since 1.2.0 453 * 454 * @param unknown_type $meta 455 */ 456 function list_meta( $meta ) { 457 // Exit if no meta 458 if ( ! $meta ) { 459 echo ' 460 <table id="list-table" style="display: none;"> 461 <thead> 462 <tr> 463 <th class="left">' . _x( 'Name', 'meta name' ) . '</th> 464 <th>' . __( 'Value' ) . '</th> 465 </tr> 466 </thead> 467 <tbody id="the-list" data-wp-lists="list:meta"> 468 <tr><td></td></tr> 469 </tbody> 470 </table>'; //TBODY needed for list-manipulation JS 471 return; 472 } 473 $count = 0; 474 ?> 475 <table id="list-table"> 476 <thead> 477 <tr> 478 <th class="left"><?php _ex( 'Name', 'meta name' ) ?></th> 479 <th><?php _e( 'Value' ) ?></th> 480 </tr> 481 </thead> 482 <tbody id='the-list' data-wp-lists='list:meta'> 483 <?php 484 foreach ( $meta as $entry ) 485 echo _list_meta_row( $entry, $count ); 486 ?> 487 </tbody> 488 </table> 489 <?php 490 } 491 492 /** 493 * {@internal Missing Short Description}} 494 * 495 * @since 2.5.0 496 * 497 * @param unknown_type $entry 498 * @param unknown_type $count 499 * @return unknown 500 */ 501 function _list_meta_row( $entry, &$count ) { 502 static $update_nonce = false; 503 504 if ( is_protected_meta( $entry['meta_key'], 'post' ) ) 505 return; 506 507 if ( !$update_nonce ) 508 $update_nonce = wp_create_nonce( 'add-meta' ); 509 510 $r = ''; 511 ++ $count; 512 if ( $count % 2 ) 513 $style = 'alternate'; 514 else 515 $style = ''; 516 517 if ( is_serialized( $entry['meta_value'] ) ) { 518 if ( is_serialized_string( $entry['meta_value'] ) ) { 519 // this is a serialized string, so we should display it 520 $entry['meta_value'] = maybe_unserialize( $entry['meta_value'] ); 521 } else { 522 // this is a serialized array/object so we should NOT display it 523 --$count; 524 return; 525 } 526 } 527 528 $entry['meta_key'] = esc_attr($entry['meta_key']); 529 $entry['meta_value'] = esc_textarea( $entry['meta_value'] ); // using a <textarea /> 530 $entry['meta_id'] = (int) $entry['meta_id']; 531 532 $delete_nonce = wp_create_nonce( 'delete-meta_' . $entry['meta_id'] ); 533 534 $r .= "\n\t<tr id='meta-{$entry['meta_id']}' class='$style'>"; 535 $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']}' />"; 536 537 $r .= "\n\t\t<div class='submit'>"; 538 $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" ) ); 539 $r .= "\n\t\t"; 540 $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" ) ); 541 $r .= "</div>"; 542 $r .= wp_nonce_field( 'change-meta', '_ajax_nonce', false, false ); 543 $r .= "</td>"; 544 545 $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>"; 546 return $r; 547 } 548 549 /** 550 * Prints the form in the Custom Fields meta box. 551 * 552 * @since 1.2.0 553 * 554 * @param WP_Post $post Optional. The post being edited. 555 */ 556 function meta_form( $post = null ) { 557 global $wpdb; 558 $post = get_post( $post ); 559 $limit = (int) apply_filters( 'postmeta_form_limit', 30 ); 560 $keys = $wpdb->get_col( " 561 SELECT meta_key 562 FROM $wpdb->postmeta 563 GROUP BY meta_key 564 HAVING meta_key NOT LIKE '\_%' 565 ORDER BY meta_key 566 LIMIT $limit" ); 567 if ( $keys ) 568 natcasesort($keys); 569 ?> 570 <p><strong><?php _e( 'Add New Custom Field:' ) ?></strong></p> 571 <table id="newmeta"> 572 <thead> 573 <tr> 574 <th class="left"><label for="metakeyselect"><?php _ex( 'Name', 'meta name' ) ?></label></th> 575 <th><label for="metavalue"><?php _e( 'Value' ) ?></label></th> 576 </tr> 577 </thead> 578 579 <tbody> 580 <tr> 581 <td id="newmetaleft" class="left"> 582 <?php if ( $keys ) { ?> 583 <select id="metakeyselect" name="metakeyselect"> 584 <option value="#NONE#"><?php _e( '— Select —' ); ?></option> 585 <?php 586 587 foreach ( $keys as $key ) { 588 if ( is_protected_meta( $key, 'post' ) || ! current_user_can( 'add_post_meta', $post->ID, $key ) ) 589 continue; 590 echo "\n<option value='" . esc_attr($key) . "'>" . esc_html($key) . "</option>"; 591 } 592 ?> 593 </select> 594 <input class="hide-if-js" type="text" id="metakeyinput" name="metakeyinput" value="" /> 595 <a href="#postcustomstuff" class="hide-if-no-js" onclick="jQuery('#metakeyinput, #metakeyselect, #enternew, #cancelnew').toggle();return false;"> 596 <span id="enternew"><?php _e('Enter new'); ?></span> 597 <span id="cancelnew" class="hidden"><?php _e('Cancel'); ?></span></a> 598 <?php } else { ?> 599 <input type="text" id="metakeyinput" name="metakeyinput" value="" /> 600 <?php } ?> 601 </td> 602 <td><textarea id="metavalue" name="metavalue" rows="2" cols="25"></textarea></td> 603 </tr> 604 605 <tr><td colspan="2"> 606 <div class="submit"> 607 <?php submit_button( __( 'Add Custom Field' ), 'secondary', 'addmeta', false, array( 'id' => 'newmeta-submit', 'data-wp-lists' => 'add:the-list:newmeta' ) ); ?> 608 </div> 609 <?php wp_nonce_field( 'add-meta', '_ajax_nonce-add-meta', false ); ?> 610 </td></tr> 611 </tbody> 612 </table> 613 <?php 614 615 } 616 617 /** 618 * {@internal Missing Short Description}} 619 * 620 * @since 0.71 621 * 622 * @param unknown_type $edit 623 * @param unknown_type $for_post 624 * @param unknown_type $tab_index 625 * @param unknown_type $multi 626 */ 627 function touch_time( $edit = 1, $for_post = 1, $tab_index = 0, $multi = 0 ) { 628 global $wp_locale, $comment; 629 $post = get_post(); 630 631 if ( $for_post ) 632 $edit = ! ( in_array($post->post_status, array('draft', 'pending') ) && (!$post->post_date_gmt || '0000-00-00 00:00:00' == $post->post_date_gmt ) ); 633 634 $tab_index_attribute = ''; 635 if ( (int) $tab_index > 0 ) 636 $tab_index_attribute = " tabindex=\"$tab_index\""; 637 638 // 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 />'; 639 640 $time_adj = current_time('timestamp'); 641 $post_date = ($for_post) ? $post->post_date : $comment->comment_date; 642 $jj = ($edit) ? mysql2date( 'd', $post_date, false ) : gmdate( 'd', $time_adj ); 643 $mm = ($edit) ? mysql2date( 'm', $post_date, false ) : gmdate( 'm', $time_adj ); 644 $aa = ($edit) ? mysql2date( 'Y', $post_date, false ) : gmdate( 'Y', $time_adj ); 645 $hh = ($edit) ? mysql2date( 'H', $post_date, false ) : gmdate( 'H', $time_adj ); 646 $mn = ($edit) ? mysql2date( 'i', $post_date, false ) : gmdate( 'i', $time_adj ); 647 $ss = ($edit) ? mysql2date( 's', $post_date, false ) : gmdate( 's', $time_adj ); 648 649 $cur_jj = gmdate( 'd', $time_adj ); 650 $cur_mm = gmdate( 'm', $time_adj ); 651 $cur_aa = gmdate( 'Y', $time_adj ); 652 $cur_hh = gmdate( 'H', $time_adj ); 653 $cur_mn = gmdate( 'i', $time_adj ); 654 655 $month = "<select " . ( $multi ? '' : 'id="mm" ' ) . "name=\"mm\"$tab_index_attribute>\n"; 656 for ( $i = 1; $i < 13; $i = $i +1 ) { 657 $monthnum = zeroise($i, 2); 658 $month .= "\t\t\t" . '<option value="' . $monthnum . '"'; 659 if ( $i == $mm ) 660 $month .= ' selected="selected"'; 661 /* translators: 1: month number (01, 02, etc.), 2: month abbreviation */ 662 $month .= '>' . sprintf( __( '%1$s-%2$s' ), $monthnum, $wp_locale->get_month_abbrev( $wp_locale->get_month( $i ) ) ) . "</option>\n"; 663 } 664 $month .= '</select>'; 665 666 $day = '<input type="text" ' . ( $multi ? '' : 'id="jj" ' ) . 'name="jj" value="' . $jj . '" size="2" maxlength="2"' . $tab_index_attribute . ' autocomplete="off" />'; 667 $year = '<input type="text" ' . ( $multi ? '' : 'id="aa" ' ) . 'name="aa" value="' . $aa . '" size="4" maxlength="4"' . $tab_index_attribute . ' autocomplete="off" />'; 668 $hour = '<input type="text" ' . ( $multi ? '' : 'id="hh" ' ) . 'name="hh" value="' . $hh . '" size="2" maxlength="2"' . $tab_index_attribute . ' autocomplete="off" />'; 669 $minute = '<input type="text" ' . ( $multi ? '' : 'id="mn" ' ) . 'name="mn" value="' . $mn . '" size="2" maxlength="2"' . $tab_index_attribute . ' autocomplete="off" />'; 670 671 echo '<div class="timestamp-wrap">'; 672 /* translators: 1: month, 2: day, 3: year, 4: hour, 5: minute */ 673 printf( __( '%1$s %2$s, %3$s @ %4$s : %5$s' ), $month, $day, $year, $hour, $minute ); 674 675 echo '</div><input type="hidden" id="ss" name="ss" value="' . $ss . '" />'; 676 677 if ( $multi ) return; 678 679 echo "\n\n"; 680 foreach ( array('mm', 'jj', 'aa', 'hh', 'mn') as $timeunit ) { 681 echo '<input type="hidden" id="hidden_' . $timeunit . '" name="hidden_' . $timeunit . '" value="' . $$timeunit . '" />' . "\n"; 682 $cur_timeunit = 'cur_' . $timeunit; 683 echo '<input type="hidden" id="'. $cur_timeunit . '" name="'. $cur_timeunit . '" value="' . $$cur_timeunit . '" />' . "\n"; 684 } 685 ?> 686 687 <p> 688 <a href="#edit_timestamp" class="save-timestamp hide-if-no-js button"><?php _e('OK'); ?></a> 689 <a href="#edit_timestamp" class="cancel-timestamp hide-if-no-js button-cancel"><?php _e('Cancel'); ?></a> 690 </p> 691 <?php 692 } 693 694 /** 695 * {@internal Missing Short Description}} 696 * 697 * @since 1.5.0 698 * 699 * @param unknown_type $default 700 */ 701 function page_template_dropdown( $default = '' ) { 702 $templates = get_page_templates(); 703 ksort( $templates ); 704 foreach (array_keys( $templates ) as $template ) 705 : if ( $default == $templates[$template] ) 706 $selected = " selected='selected'"; 707 else 708 $selected = ''; 709 echo "\n\t<option value='".$templates[$template]."' $selected>$template</option>"; 710 endforeach; 711 } 712 713 /** 714 * {@internal Missing Short Description}} 715 * 716 * @since 1.5.0 717 * 718 * @param unknown_type $default 719 * @param unknown_type $parent 720 * @param unknown_type $level 721 * @return unknown 722 */ 723 function parent_dropdown( $default = 0, $parent = 0, $level = 0 ) { 724 global $wpdb; 725 $post = get_post(); 726 $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) ); 727 728 if ( $items ) { 729 foreach ( $items as $item ) { 730 // A page cannot be its own parent. 731 if ( $post && $post->ID && $item->ID == $post->ID ) 732 continue; 733 734 $pad = str_repeat( ' ', $level * 3 ); 735 if ( $item->ID == $default) 736 $current = ' selected="selected"'; 737 else 738 $current = ''; 739 740 echo "\n\t<option class='level-$level' value='$item->ID'$current>$pad " . esc_html($item->post_title) . "</option>"; 741 parent_dropdown( $default, $item->ID, $level +1 ); 742 } 743 } else { 744 return false; 745 } 746 } 747 748 /** 749 * Print out <option> html elements for role selectors 750 * 751 * @since 2.1.0 752 * 753 * @param string $selected slug for the role that should be already selected 754 */ 755 function wp_dropdown_roles( $selected = false ) { 756 $p = ''; 757 $r = ''; 758 759 $editable_roles = array_reverse( get_editable_roles() ); 760 761 foreach ( $editable_roles as $role => $details ) { 762 $name = translate_user_role($details['name'] ); 763 if ( $selected == $role ) // preselect specified role 764 $p = "\n\t<option selected='selected' value='" . esc_attr($role) . "'>$name</option>"; 765 else 766 $r .= "\n\t<option value='" . esc_attr($role) . "'>$name</option>"; 767 } 768 echo $p . $r; 769 } 770 771 /** 772 * Outputs the form used by the importers to accept the data to be imported 773 * 774 * @since 2.0.0 775 * 776 * @param string $action The action attribute for the form. 777 */ 778 function wp_import_upload_form( $action ) { 779 $bytes = apply_filters( 'import_upload_size_limit', wp_max_upload_size() ); 780 $size = size_format( $bytes ); 781 $upload_dir = wp_upload_dir(); 782 if ( ! empty( $upload_dir['error'] ) ) : 783 ?><div class="error"><p><?php _e('Before you can upload your import file, you will need to fix the following error:'); ?></p> 784 <p><strong><?php echo $upload_dir['error']; ?></strong></p></div><?php 785 else : 786 ?> 787 <form enctype="multipart/form-data" id="import-upload-form" method="post" class="wp-upload-form" action="<?php echo esc_url( wp_nonce_url( $action, 'import-upload' ) ); ?>"> 788 <p> 789 <label for="upload"><?php _e( 'Choose a file from your computer:' ); ?></label> (<?php printf( __('Maximum size: %s' ), $size ); ?>) 790 <input type="file" id="upload" name="import" size="25" /> 791 <input type="hidden" name="action" value="save" /> 792 <input type="hidden" name="max_file_size" value="<?php echo $bytes; ?>" /> 793 </p> 794 <?php submit_button( __('Upload file and import'), 'button' ); ?> 795 </form> 796 <?php 797 endif; 798 } 799 800 /** 801 * Add a meta box to an edit form. 802 * 803 * @since 2.5.0 804 * 805 * @param string $id String for use in the 'id' attribute of tags. 806 * @param string $title Title of the meta box. 807 * @param string $callback Function that fills the box with the desired content. The function should echo its output. 808 * @param string|object $screen Optional. The screen on which to show the box (post, page, link). Defaults to current screen. 809 * @param string $context Optional. The context within the page where the boxes should show ('normal', 'advanced'). 810 * @param string $priority Optional. The priority within the context where the boxes should show ('high', 'low'). 811 * @param array $callback_args Optional. Data that should be set as the "args" property of the box array (which is the second parameter passed to your callback). 812 */ 813 function add_meta_box( $id, $title, $callback, $screen = null, $context = 'advanced', $priority = 'default', $callback_args = null ) { 814 global $wp_meta_boxes; 815 816 if ( empty( $screen ) ) 817 $screen = get_current_screen(); 818 elseif ( is_string( $screen ) ) 819 $screen = convert_to_screen( $screen ); 820 821 $page = $screen->id; 822 823 if ( !isset($wp_meta_boxes) ) 824 $wp_meta_boxes = array(); 825 if ( !isset($wp_meta_boxes[$page]) ) 826 $wp_meta_boxes[$page] = array(); 827 if ( !isset($wp_meta_boxes[$page][$context]) ) 828 $wp_meta_boxes[$page][$context] = array(); 829 830 foreach ( array_keys($wp_meta_boxes[$page]) as $a_context ) { 831 foreach ( array('high', 'core', 'default', 'low') as $a_priority ) { 832 if ( !isset($wp_meta_boxes[$page][$a_context][$a_priority][$id]) ) 833 continue; 834 835 // If a core box was previously added or removed by a plugin, don't add. 836 if ( 'core' == $priority ) { 837 // If core box previously deleted, don't add 838 if ( false === $wp_meta_boxes[$page][$a_context][$a_priority][$id] ) 839 return; 840 // If box was added with default priority, give it core priority to maintain sort order 841 if ( 'default' == $a_priority ) { 842 $wp_meta_boxes[$page][$a_context]['core'][$id] = $wp_meta_boxes[$page][$a_context]['default'][$id]; 843 unset($wp_meta_boxes[$page][$a_context]['default'][$id]); 844 } 845 return; 846 } 847 // If no priority given and id already present, use existing priority 848 if ( empty($priority) ) { 849 $priority = $a_priority; 850 // 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. 851 } elseif ( 'sorted' == $priority ) { 852 $title = $wp_meta_boxes[$page][$a_context][$a_priority][$id]['title']; 853 $callback = $wp_meta_boxes[$page][$a_context][$a_priority][$id]['callback']; 854 $callback_args = $wp_meta_boxes[$page][$a_context][$a_priority][$id]['args']; 855 } 856 // An id can be in only one priority and one context 857 if ( $priority != $a_priority || $context != $a_context ) 858 unset($wp_meta_boxes[$page][$a_context][$a_priority][$id]); 859 } 860 } 861 862 if ( empty($priority) ) 863 $priority = 'low'; 864 865 if ( !isset($wp_meta_boxes[$page][$context][$priority]) ) 866 $wp_meta_boxes[$page][$context][$priority] = array(); 867 868 $wp_meta_boxes[$page][$context][$priority][$id] = array('id' => $id, 'title' => $title, 'callback' => $callback, 'args' => $callback_args); 869 } 870 871 /** 872 * Meta-Box template function 873 * 874 * @since 2.5.0 875 * 876 * @param string|object $screen Screen identifier 877 * @param string $context box context 878 * @param mixed $object gets passed to the box callback function as first parameter 879 * @return int number of meta_boxes 880 */ 881 function do_meta_boxes( $screen, $context, $object ) { 882 global $wp_meta_boxes; 883 static $already_sorted = false; 884 885 if ( empty( $screen ) ) 886 $screen = get_current_screen(); 887 elseif ( is_string( $screen ) ) 888 $screen = convert_to_screen( $screen ); 889 890 $page = $screen->id; 891 892 $hidden = get_hidden_meta_boxes( $screen ); 893 894 printf('<div id="%s-sortables" class="meta-box-sortables">', htmlspecialchars($context)); 895 896 $i = 0; 897 do { 898 // Grab the ones the user has manually sorted. Pull them out of their previous context/priority and into the one the user chose 899 if ( !$already_sorted && $sorted = get_user_option( "meta-box-order_$page" ) ) { 900 foreach ( $sorted as $box_context => $ids ) { 901 foreach ( explode(',', $ids ) as $id ) { 902 if ( $id && 'dashboard_browser_nag' !== $id ) 903 add_meta_box( $id, null, null, $screen, $box_context, 'sorted' ); 904 } 905 } 906 } 907 $already_sorted = true; 908 909 if ( !isset($wp_meta_boxes) || !isset($wp_meta_boxes[$page]) || !isset($wp_meta_boxes[$page][$context]) ) 910 break; 911 912 foreach ( array('high', 'sorted', 'core', 'default', 'low') as $priority ) { 913 if ( isset($wp_meta_boxes[$page][$context][$priority]) ) { 914 foreach ( (array) $wp_meta_boxes[$page][$context][$priority] as $box ) { 915 if ( false == $box || ! $box['title'] ) 916 continue; 917 $i++; 918 $hidden_class = in_array($box['id'], $hidden) ? ' hide-if-js' : ''; 919 echo '<div id="' . $box['id'] . '" class="postbox ' . postbox_classes($box['id'], $page) . $hidden_class . '" ' . '>' . "\n"; 920 if ( 'dashboard_browser_nag' != $box['id'] ) 921 echo '<div class="handlediv" title="' . esc_attr__('Click to toggle') . '"><br /></div>'; 922 echo "<h3 class='hndle'><span>{$box['title']}</span></h3>\n"; 923 echo '<div class="inside">' . "\n"; 924 call_user_func($box['callback'], $object, $box); 925 echo "</div>\n"; 926 echo "</div>\n"; 927 } 928 } 929 } 930 } while(0); 931 932 echo "</div>"; 933 934 return $i; 935 936 } 937 938 /** 939 * Remove a meta box from an edit form. 940 * 941 * @since 2.6.0 942 * 943 * @param string $id String for use in the 'id' attribute of tags. 944 * @param string|object $screen The screen on which to show the box (post, page, link). 945 * @param string $context The context within the page where the boxes should show ('normal', 'advanced'). 946 */ 947 function remove_meta_box($id, $screen, $context) { 948 global $wp_meta_boxes; 949 950 if ( empty( $screen ) ) 951 $screen = get_current_screen(); 952 elseif ( is_string( $screen ) ) 953 $screen = convert_to_screen( $screen ); 954 955 $page = $screen->id; 956 957 if ( !isset($wp_meta_boxes) ) 958 $wp_meta_boxes = array(); 959 if ( !isset($wp_meta_boxes[$page]) ) 960 $wp_meta_boxes[$page] = array(); 961 if ( !isset($wp_meta_boxes[$page][$context]) ) 962 $wp_meta_boxes[$page][$context] = array(); 963 964 foreach ( array('high', 'core', 'default', 'low') as $priority ) 965 $wp_meta_boxes[$page][$context][$priority][$id] = false; 966 } 967 968 /** 969 * Meta Box Accordion Template Function 970 * 971 * Largely made up of abstracted code from {@link do_meta_boxes()}, this 972 * function serves to build meta boxes as list items for display as 973 * a collapsible accordion. 974 * 975 * @since 3.6.0 976 * 977 * @uses global $wp_meta_boxes Used to retrieve registered meta boxes. 978 * 979 * @param string|object $screen The screen identifier. 980 * @param string $context The meta box context. 981 * @param mixed $object gets passed to the section callback function as first parameter. 982 * @return int number of meta boxes as accordion sections. 983 */ 984 function do_accordion_sections( $screen, $context, $object ) { 985 global $wp_meta_boxes; 986 987 wp_enqueue_script( 'accordion' ); 988 989 if ( empty( $screen ) ) 990 $screen = get_current_screen(); 991 elseif ( is_string( $screen ) ) 992 $screen = convert_to_screen( $screen ); 993 994 $page = $screen->id; 995 996 $hidden = get_hidden_meta_boxes( $screen ); 997 ?> 998 <div id="side-sortables" class="accordion-container"> 999 <ul class="outer-border"> 1000 <?php 1001 $i = 0; 1002 $first_open = false; 1003 do { 1004 if ( ! isset( $wp_meta_boxes ) || ! isset( $wp_meta_boxes[$page] ) || ! isset( $wp_meta_boxes[$page][$context] ) ) 1005 break; 1006 1007 foreach ( array( 'high', 'core', 'default', 'low' ) as $priority ) { 1008 if ( isset( $wp_meta_boxes[$page][$context][$priority] ) ) { 1009 foreach ( $wp_meta_boxes[$page][$context][$priority] as $box ) { 1010 if ( false == $box || ! $box['title'] ) 1011 continue; 1012 $i++; 1013 $hidden_class = in_array( $box['id'], $hidden ) ? 'hide-if-js' : ''; 1014 1015 $open_class = ''; 1016 if ( ! $first_open && empty( $hidden_class ) ) { 1017 $first_open = true; 1018 $open_class = 'open'; 1019 } 1020 ?> 1021 <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'] ); ?>"> 1022 <h3 class="accordion-section-title hndle" tabindex="0" title="<?php echo esc_attr( $box['title'] ); ?>"><?php echo esc_html( $box['title'] ); ?></h3> 1023 <div class="accordion-section-content <?php postbox_classes( $box['id'], $page ); ?>"> 1024 <div class="inside"> 1025 <?php call_user_func( $box['callback'], $object, $box ); ?> 1026 </div><!-- .inside --> 1027 </div><!-- .accordion-section-content --> 1028 </li><!-- .accordion-section --> 1029 <?php 1030 } 1031 } 1032 } 1033 } while(0); 1034 ?> 1035 </ul><!-- .outer-border --> 1036 </div><!-- .accordion-container --> 1037 <?php 1038 return $i; 1039 } 1040 1041 /** 1042 * Add a new section to a settings page. 1043 * 1044 * Part of the Settings API. Use this to define new settings sections for an admin page. 1045 * Show settings sections in your admin page callback function with do_settings_sections(). 1046 * Add settings fields to your section with add_settings_field() 1047 * 1048 * The $callback argument should be the name of a function that echoes out any 1049 * content you want to show at the top of the settings section before the actual 1050 * fields. It can output nothing if you want. 1051 * 1052 * @since 2.7.0 1053 * 1054 * @global $wp_settings_sections Storage array of all settings sections added to admin pages 1055 * 1056 * @param string $id Slug-name to identify the section. Used in the 'id' attribute of tags. 1057 * @param string $title Formatted title of the section. Shown as the heading for the section. 1058 * @param string $callback Function that echos out any content at the top of the section (between heading and fields). 1059 * @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(); 1060 */ 1061 function add_settings_section($id, $title, $callback, $page) { 1062 global $wp_settings_sections; 1063 1064 if ( 'misc' == $page ) { 1065 _deprecated_argument( __FUNCTION__, '3.0', sprintf( __( 'The "%s" options group has been removed. Use another settings group.' ), 'misc' ) ); 1066 $page = 'general'; 1067 } 1068 1069 if ( 'privacy' == $page ) { 1070 _deprecated_argument( __FUNCTION__, '3.5', sprintf( __( 'The "%s" options group has been removed. Use another settings group.' ), 'privacy' ) ); 1071 $page = 'reading'; 1072 } 1073 1074 $wp_settings_sections[$page][$id] = array('id' => $id, 'title' => $title, 'callback' => $callback); 1075 } 1076 1077 /** 1078 * Add a new field to a section of a settings page 1079 * 1080 * Part of the Settings API. Use this to define a settings field that will show 1081 * as part of a settings section inside a settings page. The fields are shown using 1082 * do_settings_fields() in do_settings-sections() 1083 * 1084 * The $callback argument should be the name of a function that echoes out the 1085 * html input tags for this setting field. Use get_option() to retrieve existing 1086 * values to show. 1087 * 1088 * @since 2.7.0 1089 * 1090 * @global $wp_settings_fields Storage array of settings fields and info about their pages/sections 1091 * 1092 * @param string $id Slug-name to identify the field. Used in the 'id' attribute of tags. 1093 * @param string $title Formatted title of the field. Shown as the label for the field during output. 1094 * @param string $callback Function that fills the field with the desired form inputs. The function should echo its output. 1095 * @param string $page The slug-name of the settings page on which to show the section (general, reading, writing, ...). 1096 * @param string $section The slug-name of the section of the settings page in which to show the box (default, ...). 1097 * @param array $args Additional arguments 1098 */ 1099 function add_settings_field($id, $title, $callback, $page, $section = 'default', $args = array()) { 1100 global $wp_settings_fields; 1101 1102 if ( 'misc' == $page ) { 1103 _deprecated_argument( __FUNCTION__, '3.0', __( 'The miscellaneous options group has been removed. Use another settings group.' ) ); 1104 $page = 'general'; 1105 } 1106 1107 if ( 'privacy' == $page ) { 1108 _deprecated_argument( __FUNCTION__, '3.5', __( 'The privacy options group has been removed. Use another settings group.' ) ); 1109 $page = 'reading'; 1110 } 1111 1112 $wp_settings_fields[$page][$section][$id] = array('id' => $id, 'title' => $title, 'callback' => $callback, 'args' => $args); 1113 } 1114 1115 /** 1116 * Prints out all settings sections added to a particular settings page 1117 * 1118 * Part of the Settings API. Use this in a settings page callback function 1119 * to output all the sections and fields that were added to that $page with 1120 * add_settings_section() and add_settings_field() 1121 * 1122 * @global $wp_settings_sections Storage array of all settings sections added to admin pages 1123 * @global $wp_settings_fields Storage array of settings fields and info about their pages/sections 1124 * @since 2.7.0 1125 * 1126 * @param string $page The slug name of the page whos settings sections you want to output 1127 */ 1128 function do_settings_sections( $page ) { 1129 global $wp_settings_sections, $wp_settings_fields; 1130 1131 if ( ! isset( $wp_settings_sections[$page] ) ) 1132 return; 1133 1134 foreach ( (array) $wp_settings_sections[$page] as $section ) { 1135 if ( $section['title'] ) 1136 echo "<h3>{$section['title']}</h3>\n"; 1137 1138 if ( $section['callback'] ) 1139 call_user_func( $section['callback'], $section ); 1140 1141 if ( ! isset( $wp_settings_fields ) || !isset( $wp_settings_fields[$page] ) || !isset( $wp_settings_fields[$page][$section['id']] ) ) 1142 continue; 1143 echo '<table class="form-table">'; 1144 do_settings_fields( $page, $section['id'] ); 1145 echo '</table>'; 1146 } 1147 } 1148 1149 /** 1150 * Print out the settings fields for a particular settings section 1151 * 1152 * Part of the Settings API. Use this in a settings page to output 1153 * a specific section. Should normally be called by do_settings_sections() 1154 * rather than directly. 1155 * 1156 * @global $wp_settings_fields Storage array of settings fields and their pages/sections 1157 * 1158 * @since 2.7.0 1159 * 1160 * @param string $page Slug title of the admin page who's settings fields you want to show. 1161 * @param section $section Slug title of the settings section who's fields you want to show. 1162 */ 1163 function do_settings_fields($page, $section) { 1164 global $wp_settings_fields; 1165 1166 if ( ! isset( $wp_settings_fields[$page][$section] ) ) 1167 return; 1168 1169 foreach ( (array) $wp_settings_fields[$page][$section] as $field ) { 1170 echo '<tr valign="top">'; 1171 if ( !empty($field['args']['label_for']) ) 1172 echo '<th scope="row"><label for="' . esc_attr( $field['args']['label_for'] ) . '">' . $field['title'] . '</label></th>'; 1173 else 1174 echo '<th scope="row">' . $field['title'] . '</th>'; 1175 echo '<td>'; 1176 call_user_func($field['callback'], $field['args']); 1177 echo '</td>'; 1178 echo '</tr>'; 1179 } 1180 } 1181 1182 /** 1183 * Register a settings error to be displayed to the user 1184 * 1185 * Part of the Settings API. Use this to show messages to users about settings validation 1186 * problems, missing settings or anything else. 1187 * 1188 * Settings errors should be added inside the $sanitize_callback function defined in 1189 * register_setting() for a given setting to give feedback about the submission. 1190 * 1191 * By default messages will show immediately after the submission that generated the error. 1192 * Additional calls to settings_errors() can be used to show errors even when the settings 1193 * page is first accessed. 1194 * 1195 * @since 3.0.0 1196 * 1197 * @global array $wp_settings_errors Storage array of errors registered during this pageload 1198 * 1199 * @param string $setting Slug title of the setting to which this error applies 1200 * @param string $code Slug-name to identify the error. Used as part of 'id' attribute in HTML output. 1201 * @param string $message The formatted message text to display to the user (will be shown inside styled <div> and <p>) 1202 * @param string $type The type of message it is, controls HTML class. Use 'error' or 'updated'. 1203 */ 1204 function add_settings_error( $setting, $code, $message, $type = 'error' ) { 1205 global $wp_settings_errors; 1206 1207 $new_error = array( 1208 'setting' => $setting, 1209 'code' => $code, 1210 'message' => $message, 1211 'type' => $type 1212 ); 1213 $wp_settings_errors[] = $new_error; 1214 } 1215 1216 /** 1217 * Fetch settings errors registered by add_settings_error() 1218 * 1219 * Checks the $wp_settings_errors array for any errors declared during the current 1220 * pageload and returns them. 1221 * 1222 * If changes were just submitted ($_GET['settings-updated']) and settings errors were saved 1223 * to the 'settings_errors' transient then those errors will be returned instead. This 1224 * is used to pass errors back across pageloads. 1225 * 1226 * Use the $sanitize argument to manually re-sanitize the option before returning errors. 1227 * This is useful if you have errors or notices you want to show even when the user 1228 * hasn't submitted data (i.e. when they first load an options page, or in admin_notices action hook) 1229 * 1230 * @since 3.0.0 1231 * 1232 * @global array $wp_settings_errors Storage array of errors registered during this pageload 1233 * 1234 * @param string $setting Optional slug title of a specific setting who's errors you want. 1235 * @param boolean $sanitize Whether to re-sanitize the setting value before returning errors. 1236 * @return array Array of settings errors 1237 */ 1238 function get_settings_errors( $setting = '', $sanitize = false ) { 1239 global $wp_settings_errors; 1240 1241 // If $sanitize is true, manually re-run the sanitization for this option 1242 // This allows the $sanitize_callback from register_setting() to run, adding 1243 // any settings errors you want to show by default. 1244 if ( $sanitize ) 1245 sanitize_option( $setting, get_option( $setting ) ); 1246 1247 // If settings were passed back from options.php then use them 1248 if ( isset( $_GET['settings-updated'] ) && $_GET['settings-updated'] && get_transient( 'settings_errors' ) ) { 1249 $wp_settings_errors = array_merge( (array) $wp_settings_errors, get_transient( 'settings_errors' ) ); 1250 delete_transient( 'settings_errors' ); 1251 } 1252 1253 // Check global in case errors have been added on this pageload 1254 if ( ! count( $wp_settings_errors ) ) 1255 return array(); 1256 1257 // Filter the results to those of a specific setting if one was set 1258 if ( $setting ) { 1259 $setting_errors = array(); 1260 foreach ( (array) $wp_settings_errors as $key => $details ) { 1261 if ( $setting == $details['setting'] ) 1262 $setting_errors[] = $wp_settings_errors[$key]; 1263 } 1264 return $setting_errors; 1265 } 1266 1267 return $wp_settings_errors; 1268 } 1269 1270 /** 1271 * Display settings errors registered by add_settings_error() 1272 * 1273 * Part of the Settings API. Outputs a <div> for each error retrieved by get_settings_errors(). 1274 * 1275 * This is called automatically after a settings page based on the Settings API is submitted. 1276 * Errors should be added during the validation callback function for a setting defined in register_setting() 1277 * 1278 * The $sanitize option is passed into get_settings_errors() and will re-run the setting sanitization 1279 * on its current value. 1280 * 1281 * The $hide_on_update option will cause errors to only show when the settings page is first loaded. 1282 * if the user has already saved new values it will be hidden to avoid repeating messages already 1283 * shown in the default error reporting after submission. This is useful to show general errors like missing 1284 * settings when the user arrives at the settings page. 1285 * 1286 * @since 3.0.0 1287 * 1288 * @param string $setting Optional slug title of a specific setting who's errors you want. 1289 * @param boolean $sanitize Whether to re-sanitize the setting value before returning errors. 1290 * @param boolean $hide_on_update If set to true errors will not be shown if the settings page has already been submitted. 1291 */ 1292 function settings_errors( $setting = '', $sanitize = false, $hide_on_update = false ) { 1293 1294 if ( $hide_on_update && ! empty( $_GET['settings-updated'] ) ) 1295 return; 1296 1297 $settings_errors = get_settings_errors( $setting, $sanitize ); 1298 1299 if ( empty( $settings_errors ) ) 1300 return; 1301 1302 $output = ''; 1303 foreach ( $settings_errors as $key => $details ) { 1304 $css_id = 'setting-error-' . $details['code']; 1305 $css_class = $details['type'] . ' settings-error'; 1306 $output .= "<div id='$css_id' class='$css_class'> \n"; 1307 $output .= "<p><strong>{$details['message']}</strong></p>"; 1308 $output .= "</div> \n"; 1309 } 1310 echo $output; 1311 } 1312 1313 /** 1314 * {@internal Missing Short Description}} 1315 * 1316 * @since 2.7.0 1317 * 1318 * @param unknown_type $found_action 1319 */ 1320 function find_posts_div($found_action = '') { 1321 ?> 1322 <div id="find-posts" class="find-box" style="display:none;"> 1323 <div id="find-posts-head" class="find-box-head"><?php _e('Find Posts or Pages'); ?></div> 1324 <div class="find-box-inside"> 1325 <div class="find-box-search"> 1326 <?php if ( $found_action ) { ?> 1327 <input type="hidden" name="found_action" value="<?php echo esc_attr($found_action); ?>" /> 1328 <?php } ?> 1329 1330 <input type="hidden" name="affected" id="affected" value="" /> 1331 <?php wp_nonce_field( 'find-posts', '_ajax_nonce', false ); ?> 1332 <label class="screen-reader-text" for="find-posts-input"><?php _e( 'Search' ); ?></label> 1333 <input type="text" id="find-posts-input" name="ps" value="" /> 1334 <span class="spinner"></span> 1335 <input type="button" id="find-posts-search" value="<?php esc_attr_e( 'Search' ); ?>" class="button" /> 1336 </div> 1337 <div id="find-posts-response"></div> 1338 </div> 1339 <div class="find-box-buttons"> 1340 <input id="find-posts-close" type="button" class="button alignleft" value="<?php esc_attr_e('Close'); ?>" /> 1341 <?php submit_button( __( 'Select' ), 'button-primary alignright', 'find-posts-submit', false ); ?> 1342 </div> 1343 </div> 1344 <?php 1345 } 1346 1347 /** 1348 * Display the post password. 1349 * 1350 * The password is passed through {@link esc_attr()} to ensure that it 1351 * is safe for placing in an html attribute. 1352 * 1353 * @uses attr 1354 * @since 2.7.0 1355 */ 1356 function the_post_password() { 1357 $post = get_post(); 1358 if ( isset( $post->post_password ) ) 1359 echo esc_attr( $post->post_password ); 1360 } 1361 1362 /** 1363 * Get the post title. 1364 * 1365 * The post title is fetched and if it is blank then a default string is 1366 * returned. 1367 * 1368 * @since 2.7.0 1369 * @param mixed $post Post id or object. If not supplied the global $post is used. 1370 * @return string The post title if set 1371 */ 1372 function _draft_or_post_title( $post = 0 ) { 1373 $title = get_the_title( $post ); 1374 if ( empty( $title ) ) 1375 $title = __( '(no title)' ); 1376 return $title; 1377 } 1378 1379 /** 1380 * Display the search query. 1381 * 1382 * A simple wrapper to display the "s" parameter in a GET URI. This function 1383 * should only be used when {@link the_search_query()} cannot. 1384 * 1385 * @uses attr 1386 * @since 2.7.0 1387 * 1388 */ 1389 function _admin_search_query() { 1390 echo isset($_REQUEST['s']) ? esc_attr( wp_unslash( $_REQUEST['s'] ) ) : ''; 1391 } 1392 1393 /** 1394 * Generic Iframe header for use with Thickbox 1395 * 1396 * @since 2.7.0 1397 * @param string $title Title of the Iframe page. 1398 * @param bool $limit_styles Limit styles to colour-related styles only (unless others are enqueued). 1399 * 1400 */ 1401 function iframe_header( $title = '', $limit_styles = false ) { 1402 show_admin_bar( false ); 1403 global $hook_suffix, $current_user, $admin_body_class, $wp_locale; 1404 $admin_body_class = preg_replace('/[^a-z0-9_-]+/i', '-', $hook_suffix); 1405 1406 $current_screen = get_current_screen(); 1407 1408 @header( 'Content-Type: ' . get_option( 'html_type' ) . '; charset=' . get_option( 'blog_charset' ) ); 1409 _wp_admin_html_begin(); 1410 ?> 1411 <title><?php bloginfo('name') ?> › <?php echo $title ?> — <?php _e('WordPress'); ?></title> 1412 <?php 1413 wp_enqueue_style( 'colors' ); 1414 ?> 1415 <script type="text/javascript"> 1416 //<![CDATA[ 1417 addLoadEvent = function(func){if(typeof jQuery!="undefined")jQuery(document).ready(func);else if(typeof wpOnload!='function'){wpOnload=func;}else{var oldonload=wpOnload;wpOnload=function(){oldonload();func();}}}; 1418 function tb_close(){var win=window.dialogArguments||opener||parent||top;win.tb_remove();} 1419 var ajaxurl = '<?php echo admin_url( 'admin-ajax.php', 'relative' ); ?>', 1420 pagenow = '<?php echo $current_screen->id; ?>', 1421 typenow = '<?php echo $current_screen->post_type; ?>', 1422 adminpage = '<?php echo $admin_body_class; ?>', 1423 thousandsSeparator = '<?php echo addslashes( $wp_locale->number_format['thousands_sep'] ); ?>', 1424 decimalPoint = '<?php echo addslashes( $wp_locale->number_format['decimal_point'] ); ?>', 1425 isRtl = <?php echo (int) is_rtl(); ?>; 1426 //]]> 1427 </script> 1428 <?php 1429 do_action('admin_enqueue_scripts', $hook_suffix); 1430 do_action("admin_print_styles-$hook_suffix"); 1431 do_action('admin_print_styles'); 1432 do_action("admin_print_scripts-$hook_suffix"); 1433 do_action('admin_print_scripts'); 1434 do_action("admin_head-$hook_suffix"); 1435 do_action('admin_head'); 1436 1437 $admin_body_class .= ' locale-' . sanitize_html_class( strtolower( str_replace( '_', '-', get_locale() ) ) ); 1438 1439 if ( is_rtl() ) 1440 $admin_body_class .= ' rtl'; 1441 1442 ?> 1443 </head> 1444 <body<?php if ( isset($GLOBALS['body_id']) ) echo ' id="' . $GLOBALS['body_id'] . '"'; ?> class="wp-admin wp-core-ui no-js iframe <?php echo apply_filters( 'admin_body_class', '' ) . ' ' . $admin_body_class; ?>"> 1445 <script type="text/javascript"> 1446 //<![CDATA[ 1447 (function(){ 1448 var c = document.body.className; 1449 c = c.replace(/no-js/, 'js'); 1450 document.body.className = c; 1451 })(); 1452 //]]> 1453 </script> 1454 <?php 1455 } 1456 1457 /** 1458 * Generic Iframe footer for use with Thickbox 1459 * 1460 * @since 2.7.0 1461 * 1462 */ 1463 function iframe_footer() { 1464 //We're going to hide any footer output on iframe pages, but run the hooks anyway since they output Javascript or other needed content. ?> 1465 <div class="hidden"> 1466 <?php 1467 do_action('admin_footer', ''); 1468 do_action('admin_print_footer_scripts'); ?> 1469 </div> 1470 <script type="text/javascript">if(typeof wpOnload=="function")wpOnload();</script> 1471 </body> 1472 </html> 1473 <?php 1474 } 1475 1476 function _post_states($post) { 1477 $post_states = array(); 1478 if ( isset( $_REQUEST['post_status'] ) ) 1479 $post_status = $_REQUEST['post_status']; 1480 else 1481 $post_status = ''; 1482 1483 if ( !empty($post->post_password) ) 1484 $post_states['protected'] = __('Password protected'); 1485 if ( 'private' == $post->post_status && 'private' != $post_status ) 1486 $post_states['private'] = __('Private'); 1487 if ( 'draft' == $post->post_status && 'draft' != $post_status ) 1488 $post_states['draft'] = __('Draft'); 1489 if ( 'pending' == $post->post_status && 'pending' != $post_status ) 1490 /* translators: post state */ 1491 $post_states['pending'] = _x('Pending', 'post state'); 1492 if ( is_sticky($post->ID) ) 1493 $post_states['sticky'] = __('Sticky'); 1494 1495 $post_states = apply_filters( 'display_post_states', $post_states, $post ); 1496 1497 if ( ! empty($post_states) ) { 1498 $state_count = count($post_states); 1499 $i = 0; 1500 echo ' - '; 1501 foreach ( $post_states as $state ) { 1502 ++$i; 1503 ( $i == $state_count ) ? $sep = '' : $sep = ', '; 1504 echo "<span class='post-state'>$state$sep</span>"; 1505 } 1506 } 1507 1508 } 1509 1510 function _media_states( $post ) { 1511 $media_states = array(); 1512 $stylesheet = get_option('stylesheet'); 1513 1514 if ( current_theme_supports( 'custom-header') ) { 1515 $meta_header = get_post_meta($post->ID, '_wp_attachment_is_custom_header', true ); 1516 if ( ! empty( $meta_header ) && $meta_header == $stylesheet ) 1517 $media_states[] = __( 'Header Image' ); 1518 } 1519 1520 if ( current_theme_supports( 'custom-background') ) { 1521 $meta_background = get_post_meta($post->ID, '_wp_attachment_is_custom_background', true ); 1522 if ( ! empty( $meta_background ) && $meta_background == $stylesheet ) 1523 $media_states[] = __( 'Background Image' ); 1524 } 1525 1526 $media_states = apply_filters( 'display_media_states', $media_states ); 1527 1528 if ( ! empty( $media_states ) ) { 1529 $state_count = count( $media_states ); 1530 $i = 0; 1531 echo ' - '; 1532 foreach ( $media_states as $state ) { 1533 ++$i; 1534 ( $i == $state_count ) ? $sep = '' : $sep = ', '; 1535 echo "<span class='post-state'>$state$sep</span>"; 1536 } 1537 } 1538 } 1539 1540 /** 1541 * Test support for compressing JavaScript from PHP 1542 * 1543 * Outputs JavaScript that tests if compression from PHP works as expected 1544 * and sets an option with the result. Has no effect when the current user 1545 * is not an administrator. To run the test again the option 'can_compress_scripts' 1546 * has to be deleted. 1547 * 1548 * @since 2.8.0 1549 */ 1550 function compression_test() { 1551 ?> 1552 <script type="text/javascript"> 1553 /* <![CDATA[ */ 1554 var testCompression = { 1555 get : function(test) { 1556 var x; 1557 if ( window.XMLHttpRequest ) { 1558 x = new XMLHttpRequest(); 1559 } else { 1560 try{x=new ActiveXObject('Msxml2.XMLHTTP');}catch(e){try{x=new ActiveXObject('Microsoft.XMLHTTP');}catch(e){};} 1561 } 1562 1563 if (x) { 1564 x.onreadystatechange = function() { 1565 var r, h; 1566 if ( x.readyState == 4 ) { 1567 r = x.responseText.substr(0, 18); 1568 h = x.getResponseHeader('Content-Encoding'); 1569 testCompression.check(r, h, test); 1570 } 1571 } 1572 1573 x.open('GET', ajaxurl + '?action=wp-compression-test&test='+test+'&'+(new Date()).getTime(), true); 1574 x.send(''); 1575 } 1576 }, 1577 1578 check : function(r, h, test) { 1579 if ( ! r && ! test ) 1580 this.get(1); 1581 1582 if ( 1 == test ) { 1583 if ( h && ( h.match(/deflate/i) || h.match(/gzip/i) ) ) 1584 this.get('no'); 1585 else 1586 this.get(2); 1587 1588 return; 1589 } 1590 1591 if ( 2 == test ) { 1592 if ( '"wpCompressionTest' == r ) 1593 this.get('yes'); 1594 else 1595 this.get('no'); 1596 } 1597 } 1598 }; 1599 testCompression.check(); 1600 /* ]]> */ 1601 </script> 1602 <?php 1603 } 1604 1605 /** 1606 * Echos a submit button, with provided text and appropriate class 1607 * 1608 * @since 3.1.0 1609 * 1610 * @param string $text The text of the button (defaults to 'Save Changes') 1611 * @param string $type The type of button. One of: primary, secondary, delete 1612 * @param string $name The HTML name of the submit button. Defaults to "submit". If no id attribute 1613 * is given in $other_attributes below, $name will be used as the button's id. 1614 * @param bool $wrap True if the output button should be wrapped in a paragraph tag, 1615 * false otherwise. Defaults to true 1616 * @param array|string $other_attributes Other attributes that should be output with the button, 1617 * mapping attributes to their values, such as array( 'tabindex' => '1' ). 1618 * These attributes will be output as attribute="value", such as tabindex="1". 1619 * Defaults to no other attributes. Other attributes can also be provided as a 1620 * string such as 'tabindex="1"', though the array format is typically cleaner. 1621 */ 1622 function submit_button( $text = null, $type = 'primary', $name = 'submit', $wrap = true, $other_attributes = null ) { 1623 echo get_submit_button( $text, $type, $name, $wrap, $other_attributes ); 1624 } 1625 1626 /** 1627 * Returns a submit button, with provided text and appropriate class 1628 * 1629 * @since 3.1.0 1630 * 1631 * @param string $text The text of the button (defaults to 'Save Changes') 1632 * @param string $type The type of button. One of: primary, secondary, delete 1633 * @param string $name The HTML name of the submit button. Defaults to "submit". If no id attribute 1634 * is given in $other_attributes below, $name will be used as the button's id. 1635 * @param bool $wrap True if the output button should be wrapped in a paragraph tag, 1636 * false otherwise. Defaults to true 1637 * @param array|string $other_attributes Other attributes that should be output with the button, 1638 * mapping attributes to their values, such as array( 'tabindex' => '1' ). 1639 * These attributes will be output as attribute="value", such as tabindex="1". 1640 * Defaults to no other attributes. Other attributes can also be provided as a 1641 * string such as 'tabindex="1"', though the array format is typically cleaner. 1642 */ 1643 function get_submit_button( $text = null, $type = 'primary large', $name = 'submit', $wrap = true, $other_attributes = null ) { 1644 if ( ! is_array( $type ) ) 1645 $type = explode( ' ', $type ); 1646 1647 $button_shorthand = array( 'primary', 'small', 'large' ); 1648 $classes = array( 'button' ); 1649 foreach ( $type as $t ) { 1650 if ( 'secondary' === $t || 'button-secondary' === $t ) 1651 continue; 1652 $classes[] = in_array( $t, $button_shorthand ) ? 'button-' . $t : $t; 1653 } 1654 $class = implode( ' ', array_unique( $classes ) ); 1655 1656 if ( 'delete' === $type ) 1657 $class = 'button-secondary delete'; 1658 1659 $text = $text ? $text : __( 'Save Changes' ); 1660 1661 // Default the id attribute to $name unless an id was specifically provided in $other_attributes 1662 $id = $name; 1663 if ( is_array( $other_attributes ) && isset( $other_attributes['id'] ) ) { 1664 $id = $other_attributes['id']; 1665 unset( $other_attributes['id'] ); 1666 } 1667 1668 $attributes = ''; 1669 if ( is_array( $other_attributes ) ) { 1670 foreach ( $other_attributes as $attribute => $value ) { 1671 $attributes .= $attribute . '="' . esc_attr( $value ) . '" '; // Trailing space is important 1672 } 1673 } else if ( !empty( $other_attributes ) ) { // Attributes provided as a string 1674 $attributes = $other_attributes; 1675 } 1676 1677 $button = '<input type="submit" name="' . esc_attr( $name ) . '" id="' . esc_attr( $id ) . '" class="' . esc_attr( $class ); 1678 $button .= '" value="' . esc_attr( $text ) . '" ' . $attributes . ' />'; 1679 1680 if ( $wrap ) { 1681 $button = '<p class="submit">' . $button . '</p>'; 1682 } 1683 1684 return $button; 1685 } 1686 1687 function _wp_admin_html_begin() { 1688 global $is_IE; 1689 1690 $admin_html_class = ( is_admin_bar_showing() ) ? 'wp-toolbar' : ''; 1691 1692 if ( $is_IE ) 1693 @header('X-UA-Compatible: IE=edge'); 1694 1695 ?> 1696 <!DOCTYPE html> 1697 <!--[if IE 8]> 1698 <html xmlns="http://www.w3.org/1999/xhtml" class="ie8 <?php echo $admin_html_class; ?>" <?php do_action('admin_xml_ns'); ?> <?php language_attributes(); ?>> 1699 <![endif]--> 1700 <!--[if !(IE 8) ]><!--> 1701 <html xmlns="http://www.w3.org/1999/xhtml" class="<?php echo $admin_html_class; ?>" <?php do_action('admin_xml_ns'); ?> <?php language_attributes(); ?>> 1702 <!--<![endif]--> 1703 <head> 1704 <meta http-equiv="Content-Type" content="<?php bloginfo('html_type'); ?>; charset=<?php echo get_option('blog_charset'); ?>" /> 1705 <?php 1706 } 1707 1708 final class WP_Internal_Pointers { 1709 /** 1710 * Initializes the new feature pointers. 1711 * 1712 * @since 3.3.0 1713 * 1714 * All pointers can be disabled using the following: 1715 * remove_action( 'admin_enqueue_scripts', array( 'WP_Internal_Pointers', 'enqueue_scripts' ) ); 1716 * 1717 * Individual pointers (e.g. wp330_toolbar) can be disabled using the following: 1718 * remove_action( 'admin_print_footer_scripts', array( 'WP_Internal_Pointers', 'pointer_wp330_toolbar' ) ); 1719 */ 1720 public static function enqueue_scripts( $hook_suffix ) { 1721 /* 1722 * Register feature pointers 1723 * Format: array( hook_suffix => pointer_id ) 1724 */ 1725 1726 $registered_pointers = array( 1727 'index.php' => 'wp330_toolbar', 1728 'post-new.php' => 'wp350_media', 1729 'post.php' => array( 'wp350_media', 'wp360_revisions' ), 1730 'edit.php' => 'wp360_locks', 1731 'themes.php' => array( 'wp330_saving_widgets', 'wp340_customize_current_theme_link' ), 1732 'appearance_page_custom-header' => 'wp340_choose_image_from_library', 1733 'appearance_page_custom-background' => 'wp340_choose_image_from_library', 1734 ); 1735 1736 // Check if screen related pointer is registered 1737 if ( empty( $registered_pointers[ $hook_suffix ] ) ) 1738 return; 1739 1740 $pointers = (array) $registered_pointers[ $hook_suffix ]; 1741 1742 $caps_required = array( 1743 'wp330_saving_widgets' => array( 'edit_theme_options', 'switch_themes' ), 1744 'wp340_customize_current_theme_link' => array( 'edit_theme_options' ), 1745 'wp340_choose_image_from_library' => array( 'edit_theme_options' ), 1746 'wp350_media' => array( 'upload_files' ), 1747 ); 1748 1749 // Get dismissed pointers 1750 $dismissed = explode( ',', (string) get_user_meta( get_current_user_id(), 'dismissed_wp_pointers', true ) ); 1751 1752 $got_pointers = false; 1753 foreach ( array_diff( $pointers, $dismissed ) as $pointer ) { 1754 if ( isset( $caps_required[ $pointer ] ) ) { 1755 foreach ( $caps_required[ $pointer ] as $cap ) { 1756 if ( ! current_user_can( $cap ) ) 1757 continue 2; 1758 } 1759 } 1760 1761 // Bind pointer print function 1762 add_action( 'admin_print_footer_scripts', array( 'WP_Internal_Pointers', 'pointer_' . $pointer ) ); 1763 $got_pointers = true; 1764 } 1765 1766 if ( ! $got_pointers ) 1767 return; 1768 1769 // Add pointers script and style to queue 1770 wp_enqueue_style( 'wp-pointer' ); 1771 wp_enqueue_script( 'wp-pointer' ); 1772 } 1773 1774 /** 1775 * Print the pointer javascript data. 1776 * 1777 * @since 3.3.0 1778 * 1779 * @param string $pointer_id The pointer ID. 1780 * @param string $selector The HTML elements, on which the pointer should be attached. 1781 * @param array $args Arguments to be passed to the pointer JS (see wp-pointer.js). 1782 */ 1783 private static function print_js( $pointer_id, $selector, $args ) { 1784 if ( empty( $pointer_id ) || empty( $selector ) || empty( $args ) || empty( $args['content'] ) ) 1785 return; 1786 1787 ?> 1788 <script type="text/javascript"> 1789 //<![CDATA[ 1790 (function($){ 1791 var options = <?php echo json_encode( $args ); ?>, setup; 1792 1793 if ( ! options ) 1794 return; 1795 1796 options = $.extend( options, { 1797 close: function() { 1798 $.post( ajaxurl, { 1799 pointer: '<?php echo $pointer_id; ?>', 1800 action: 'dismiss-wp-pointer' 1801 }); 1802 } 1803 }); 1804 1805 setup = function() { 1806 $('<?php echo $selector; ?>').first().pointer( options ).pointer('open'); 1807 }; 1808 1809 if ( options.position && options.position.defer_loading ) 1810 $(window).bind( 'load.wp-pointers', setup ); 1811 else 1812 $(document).ready( setup ); 1813 1814 })( jQuery ); 1815 //]]> 1816 </script> 1817 <?php 1818 } 1819 1820 public static function pointer_wp330_toolbar() { 1821 $content = '<h3>' . __( 'New Feature: Toolbar' ) . '</h3>'; 1822 $content .= '<p>' . __( 'We’ve combined the admin bar and the old Dashboard header into one persistent toolbar. Hover over the toolbar items to see what’s new.' ) . '</p>'; 1823 1824 if ( is_multisite() && is_super_admin() ) 1825 $content .= '<p>' . __( 'Network Admin is now located in the My Sites menu.' ) . '</p>'; 1826 1827 WP_Internal_Pointers::print_js( 'wp330_toolbar', '#wpadminbar', array( 1828 'content' => $content, 1829 'position' => array( 'edge' => 'top', 'align' => 'center' ), 1830 ) ); 1831 } 1832 1833 /** 1834 * Print 'Updated Media Uploader' for 3.3.0. 1835 * 1836 * @since 3.3.0 1837 */ 1838 public static function pointer_wp330_media_uploader() {} 1839 1840 /** 1841 * Print 'New Feature: Saving Widgets' for 3.3.0. 1842 * 1843 * @since 3.3.0 1844 */ 1845 public static function pointer_wp330_saving_widgets() { 1846 $content = '<h3>' . __( 'New Feature: Saving Widgets' ) . '</h3>'; 1847 $content .= '<p>' . __( 'If you change your mind and revert to your previous theme, we’ll put the widgets back the way you had them.' ) . '</p>'; 1848 1849 WP_Internal_Pointers::print_js( 'wp330_saving_widgets', '#message2', array( 1850 'content' => $content, 1851 'position' => array( 'edge' => 'top', 'align' => is_rtl() ? 'right' : 'left' ), 1852 ) ); 1853 } 1854 1855 /** 1856 * Print 'New Feature: Current Theme Customize Link' for 3.4.0. 1857 * 1858 * @since 3.4.0 1859 */ 1860 public static function pointer_wp340_customize_current_theme_link() { 1861 $content = '<h3>' . __( 'New Feature: Customizer' ) . '</h3>'; 1862 $content .= '<p>' . __( 'Click Customize to change the header, background, title and menus of the current theme, all in one place.' ) . '</p>'; 1863 $content .= '<p>' . __( 'Click the Live Preview links in the Available Themes list below to customize and preview another theme before activating it.' ) . '</p>'; 1864 1865 WP_Internal_Pointers::print_js( 'wp340_customize_current_theme_link', '#customize-current-theme-link', array( 1866 'content' => $content, 1867 'position' => array( 'edge' => 'top', 'align' => is_rtl() ? 'right' : 'left', 'offset' => is_rtl() ? '32 0' : '-32 0' ), 1868 ) ); 1869 } 1870 1871 /** 1872 * Print 'New Feature: Choose Image from Library' for 3.4.0. 1873 * 1874 * @since 3.4.0 1875 */ 1876 public static function pointer_wp340_choose_image_from_library() { 1877 $content = '<h3>' . __( 'New Feature: Choose Image from Library' ) . '</h3>'; 1878 $content .= '<p>' . __( 'Want to use an image you uploaded earlier? Select it from your media library instead of uploading it again.' ) . '</p>'; 1879 1880 WP_Internal_Pointers::print_js( 'wp340_choose_image_from_library', '#choose-from-library-link', array( 1881 'content' => $content, 1882 'position' => array( 'edge' => 'top', 'align' => is_rtl() ? 'right' : 'left', 'defer_loading' => true ), 1883 ) ); 1884 } 1885 1886 public static function pointer_wp350_media() { 1887 $content = '<h3>' . __( 'New Media Manager' ) . '</h3>'; 1888 $content .= '<p>' . __( 'Uploading files and creating image galleries has a whole new look. Check it out!' ) . '</p>'; 1889 1890 self::print_js( 'wp350_media', '.insert-media', array( 1891 'content' => $content, 1892 'position' => array( 'edge' => is_rtl() ? 'right' : 'left', 'align' => 'center' ), 1893 ) ); 1894 } 1895 1896 public static function pointer_wp360_revisions() { 1897 $content = '<h3>' . __( 'Compare Revisions' ) . '</h3>'; 1898 $content .= '<p>' . __( 'View, compare, and restore other versions of this content on the improved revisions screen.' ) . '</p>'; 1899 1900 self::print_js( 'wp360_revisions', '.misc-pub-section.misc-pub-revisions', array( 1901 'content' => $content, 1902 'position' => array( 'edge' => is_rtl() ? 'left' : 'right', 'align' => 'center', 'my' => is_rtl() ? 'left' : 'right-14px' ), 1903 ) ); 1904 } 1905 1906 public static function pointer_wp360_locks() { 1907 $content = '<h3>' . __( 'Edit Lock' ) . '</h3>'; 1908 $content .= '<p>' . __( 'Someone else is editing this. No need to refresh; the lock will disappear when they’re done.' ) . '</p>'; 1909 1910 if ( ! is_multi_author() ) 1911 return; 1912 1913 self::print_js( 'wp360_locks', 'tr.wp-locked .locked-indicator', array( 1914 'content' => $content, 1915 'position' => array( 'edge' => 'left', 'align' => 'left' ), 1916 ) ); 1917 } 1918 1919 /** 1920 * Prevents new users from seeing existing 'new feature' pointers. 1921 * 1922 * @since 3.3.0 1923 */ 1924 public static function dismiss_pointers_for_new_users( $user_id ) { 1925 add_user_meta( $user_id, 'dismissed_wp_pointers', 'wp330_toolbar,wp330_saving_widgets,wp340_choose_image_from_library,wp340_customize_current_theme_link,wp350_media,wp360_revisions,wp360_locks' ); 1926 } 1927 } 1928 1929 add_action( 'admin_enqueue_scripts', array( 'WP_Internal_Pointers', 'enqueue_scripts' ) ); 1930 add_action( 'user_register', array( 'WP_Internal_Pointers', 'dismiss_pointers_for_new_users' ) ); 1931 1932 /** 1933 * Convert a screen string to a screen object 1934 * 1935 * @since 3.0.0 1936 * 1937 * @param string $hook_name The hook name (also known as the hook suffix) used to determine the screen. 1938 * @return WP_Screen Screen object. 1939 */ 1940 function convert_to_screen( $hook_name ) { 1941 if ( ! class_exists( 'WP_Screen' ) ) { 1942 _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' ); 1943 return (object) array( 'id' => '_invalid', 'base' => '_are_belong_to_us' ); 1944 } 1945 1946 return WP_Screen::get( $hook_name ); 1947 } 1948 1949 /** 1950 * Output the HTML for restoring the post data from DOM storage 1951 * 1952 * @since 3.6 1953 * @access private 1954 */ 1955 function _local_storage_notice() { 1956 ?> 1957 <div id="local-storage-notice" class="hidden"> 1958 <p class="local-restore"> 1959 <?php _e('The backup of this post in your browser is different from the version below.'); ?> 1960 <a class="restore-backup" href="#"><?php _e('Restore the backup.'); ?></a> 1961 </p> 1962 <p class="undo-restore hidden"> 1963 <?php _e('Post restored successfully.'); ?> 1964 <a class="undo-restore-backup" href="#"><?php _e('Undo.'); ?></a> 1965 </p> 1966 </div> 1967 <?php 1968 } 1969 1970 /** 1971 * Output a HTML element with a star rating for a given rating. 1972 * 1973 * Outputs a HTML element with the star rating exposed on a 0..5 scale in 1974 * half star increments (ie. 1, 1.5, 2 stars). Optionally, if specified, the 1975 * number of ratings may also be displayed by passing the $number parameter. 1976 * 1977 * @since 3.8.0 1978 * @param array $args { 1979 * Optional. Array of star ratings arguments. 1980 * 1981 * @type int $rating The rating to display, expressed in either a 0.5 rating increment, 1982 * or percentage. Default 0. 1983 * @type string $type Format that the $rating is in. Valid values are 'rating' (default), 1984 * or, 'percent'. Default 'rating'. 1985 * @type int $number The number of ratings that makes up this rating. Default 0. 1986 * } 1987 */ 1988 function wp_star_rating( $args = array() ) { 1989 $defaults = array( 1990 'rating' => 0, 1991 'type' => 'rating', 1992 'number' => 0, 1993 ); 1994 $r = wp_parse_args( $args, $defaults ); 1995 extract( $r, EXTR_SKIP ); 1996 1997 // Non-english decimal places when the $rating is coming from a string 1998 $rating = str_replace( ',', '.', $rating ); 1999 2000 // Convert Percentage to star rating, 0..5 in .5 increments 2001 if ( 'percent' == $type ) { 2002 $rating = round( $rating / 10, 0 ) / 2; 2003 } 2004 2005 // Calculate the number of each type of star needed 2006 $full_stars = floor( $rating ); 2007 $half_stars = ceil( $rating - $full_stars ); 2008 $empty_stars = 5 - $full_stars - $half_stars; 2009 2010 if ( $number ) { 2011 /* translators: 1: The rating, 2: The number of ratings */ 2012 $title = _n( '%1$s rating based on %2$s rating', '%1$s rating based on %2$s ratings', $number ); 2013 $title = sprintf( $title, number_format_i18n( $rating, 1 ), number_format_i18n( $number ) ); 2014 } else { 2015 /* translators: 1: The rating */ 2016 $title = sprintf( __( '%s rating' ), number_format_i18n( $rating, 1 ) ); 2017 } 2018 2019 echo '<div class="star-rating" title="' . esc_attr( $title ) . '">'; 2020 echo str_repeat( '<div class="star star-full"></div>', $full_stars ); 2021 echo str_repeat( '<div class="star star-half"></div>', $half_stars ); 2022 echo str_repeat( '<div class="star star-empty"></div>', $empty_stars); 2023 echo '</div>'; 2024 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Tue Mar 25 01:41:18 2014 | WordPress honlapkészítés: online1.hu |