Ticket #36217: 36217.8.diff
File 36217.8.diff, 40.9 KB (added by , 8 years ago) |
---|
-
src/wp-admin/edit.php
23 23 } 24 24 25 25 /** 26 * @global string $post_type27 * @global object$post_type_object26 * @global string $post_type 27 * @global WP_Post_Type $post_type_object 28 28 */ 29 29 global $post_type, $post_type_object; 30 30 -
src/wp-admin/includes/class-wp-posts-list-table.php
72 72 * 73 73 * @see WP_List_Table::__construct() for more information on default arguments. 74 74 * 75 * @global object$post_type_object76 * @global wpdb $wpdb75 * @global WP_Post_Type $post_type_object 76 * @global wpdb $wpdb 77 77 * 78 78 * @param array $args An associative array of arguments. 79 79 */ -
src/wp-admin/includes/nav-menu.php
522 522 * 523 523 * @see WP_Query::query() 524 524 * 525 * @param array $posts The posts for the current post type.526 * @param array $args An array of WP_Query arguments.527 * @param object$post_type The current post type object for this menu item meta box.525 * @param array $posts The posts for the current post type. 526 * @param array $args An array of WP_Query arguments. 527 * @param WP_Post_Type $post_type The current post type object for this menu item meta box. 528 528 */ 529 529 $posts = apply_filters( "nav_menu_items_{$post_type_name}", $posts, $args, $post_type ); 530 530 $checkbox_items = walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', $posts), 0, (object) $args ); -
src/wp-includes/class-wp-post-type.php
1 <?php 2 /** 3 * Post API: WP_Post_Type class 4 * 5 * @package WordPress 6 * @subpackage Post 7 * @since 4.6.0 8 */ 9 10 /** 11 * Core class used for interacting with post types. 12 * 13 * @since 4.6.0 14 */ 15 final class WP_Post_Type { 16 /** 17 * Post type key. 18 * 19 * @since 4.6.0 20 * @access public 21 * @var string $name 22 */ 23 public $name; 24 25 /** 26 * Name of the post type shown in the menu. Usually plural. 27 * 28 * @since 4.6.0 29 * @access public 30 * @var string $label 31 */ 32 public $label; 33 34 /** 35 * An array of labels for this post type. 36 * 37 * If not set, post labels are inherited for non-hierarchical types 38 * and page labels for hierarchical ones. 39 * 40 * @see get_post_type_labels() 41 * 42 * @since 4.6.0 43 * @access public 44 * @var array $labels 45 */ 46 public $labels; 47 48 /** 49 * A short descriptive summary of what the post type is. 50 * 51 * Default empty. 52 * 53 * @since 4.6.0 54 * @access public 55 * @var string $description 56 */ 57 public $description = ''; 58 59 /** 60 * Whether a post type is intended for use publicly either via the admin interface or by front-end users. 61 * 62 * While the default settings of $exclude_from_search, $publicly_queryable, $show_ui, and $show_in_nav_menus 63 * are inherited from public, each does not rely on this relationship and controls a very specific intention. 64 * 65 * Default false. 66 * 67 * @since 4.6.0 68 * @access public 69 * @var bool $public 70 */ 71 public $public = false; 72 73 /** 74 * Whether the post type is hierarchical (e.g. page). 75 * 76 * Default false. 77 * 78 * @since 4.6.0 79 * @access public 80 * @var bool $hierarchical 81 */ 82 public $hierarchical = false; 83 84 /** 85 * Whether to exclude posts with this post type from front end search 86 * results. 87 * 88 * Default is the opposite value of $public. 89 * 90 * @since 4.6.0 91 * @access public 92 * @var bool $exclude_from_search 93 */ 94 public $exclude_from_search = null; 95 96 /** 97 * Whether queries can be performed on the front end for the post type as part of `parse_request()`. 98 * 99 * Endpoints would include: 100 * - `?post_type={post_type_key}` 101 * - `?{post_type_key}={single_post_slug}` 102 * - `?{post_type_query_var}={single_post_slug}` 103 * 104 * Default is the value of $public. 105 * 106 * @since 4.6.0 107 * @access public 108 * @var bool $publicly_queryable 109 */ 110 public $publicly_queryable = null; 111 112 /** 113 * Whether to generate and allow a UI for managing this post type in the admin. 114 * 115 * Default is the value of $public. 116 * 117 * @since 4.6.0 118 * @access public 119 * @var bool $show_ui 120 */ 121 public $show_ui = null; 122 123 /** 124 * Where to show the post type in the admin menu. 125 * 126 * To work, $show_ui must be true. If true, the post type is shown in its own top level menu. If false, no menu is 127 * shown. If a string of an existing top level menu (eg. 'tools.php' or 'edit.php?post_type=page'), the post type 128 * will be placed as a sub-menu of that. 129 * 130 * Default is the value of $show_ui. 131 * 132 * @since 4.6.0 133 * @access public 134 * @var bool $show_in_menu 135 */ 136 public $show_in_menu = null; 137 138 /** 139 * Makes this post type available for selection in navigation menus. 140 * 141 * Default is the value $public. 142 * 143 * @since 4.6.0 144 * @access public 145 * @var bool $show_in_nav_menus 146 */ 147 public $show_in_nav_menus = null; 148 149 /** 150 * Makes this post type available via the admin bar. 151 * 152 * Default is the value of $show_in_menu. 153 * 154 * @since 4.6.0 155 * @access public 156 * @var bool $show_in_admin_bar 157 */ 158 public $show_in_admin_bar = null; 159 160 /** 161 * The position in the menu order the post type should appear. 162 * 163 * To work, $show_in_menu must be true. Default null (at the bottom). 164 * 165 * @since 4.6.0 166 * @access public 167 * @var int $menu_position 168 */ 169 public $menu_position = null; 170 171 /** 172 * The URL to the icon to be used for this menu. 173 * 174 * Pass a base64-encoded SVG using a data URI, which will be colored to match the color scheme. 175 * This should begin with 'data:image/svg+xml;base64,'. Pass the name of a Dashicons helper class 176 * to use a font icon, e.g. 'dashicons-chart-pie'. Pass 'none' to leave div.wp-menu-image empty 177 * so an icon can be added via CSS. 178 * 179 * Defaults to use the posts icon. 180 * 181 * @since 4.6.0 182 * @access public 183 * @var string $menu_icon 184 */ 185 public $menu_icon = null; 186 187 /** 188 * The string to use to build the read, edit, and delete capabilities. 189 * 190 * May be passed as an array to allow for alternative plurals when using 191 * this argument as a base to construct the capabilities, e.g. 192 * array( 'story', 'stories' ). Default 'post'. 193 * 194 * @since 4.6.0 195 * @access public 196 * @var string $capability_type 197 */ 198 public $capability_type = 'post'; 199 200 /** 201 * Whether to use the internal default meta capability handling. 202 * 203 * Default false. 204 * 205 * @since 4.6.0 206 * @access public 207 * @var bool $map_meta_cap 208 */ 209 public $map_meta_cap = false; 210 211 /** 212 * Provide a callback function that sets up the meta boxes for the edit form. 213 * 214 * Do `remove_meta_box()` and `add_meta_box()` calls in the callback. Default null. 215 * 216 * @since 4.6.0 217 * @access public 218 * @var string $register_meta_box_cb 219 */ 220 public $register_meta_box_cb = null; 221 222 /** 223 * An array of taxonomy identifiers that will be registered for the post type. 224 * 225 * Taxonomies can be registered later with `register_taxonomy()` or `register_taxonomy_for_object_type()`. 226 * 227 * Default empty array. 228 * 229 * @since 4.6.0 230 * @access public 231 * @var array $taxonomies 232 */ 233 public $taxonomies = array(); 234 235 /** 236 * Whether there should be post type archives, or if a string, the archive slug to use. 237 * 238 * Will generate the proper rewrite rules if $rewrite is enabled. Default false. 239 * 240 * @since 4.6.0 241 * @access public 242 * @var bool|string $has_archive 243 */ 244 public $has_archive = false; 245 246 /** 247 * Sets the query_var key for this post type. 248 * 249 * Defaults to $post_type key. If false, a post type cannot be loaded at `?{query_var}={post_slug}`. 250 * If specified as a string, the query `?{query_var_string}={post_slug}` will be valid. 251 * 252 * @since 4.6.0 253 * @access public 254 * @var string|bool $query_var 255 */ 256 public $query_var; 257 258 /** 259 * Whether to allow this post type to be exported. 260 * 261 * Default true. 262 * 263 * @since 4.6.0 264 * @access public 265 * @var bool $can_export 266 */ 267 public $can_export = true; 268 269 /** 270 * Whether to delete posts of this type when deleting a user. 271 * 272 * If true, posts of this type belonging to the user will be moved to trash when then user is deleted. 273 * If false, posts of this type belonging to the user will *not* be trashed or deleted. 274 * If not set (the default), posts are trashed if post_type_supports( 'author' ). 275 * Otherwise posts are not trashed or deleted. Default null. 276 * 277 * @since 4.6.0 278 * @access public 279 * @var bool $delete_with_user 280 */ 281 public $delete_with_user = null; 282 283 /** 284 * Whether this post type is a native or "built-in" post_type. 285 * 286 * Default false. 287 * 288 * @since 4.6.0 289 * @access public 290 * @var bool $_builtin 291 */ 292 public $_builtin = false; 293 294 /** 295 * URL segment to use for edit link of this post type. 296 * 297 * Default 'post.php?post=%d'. 298 * 299 * @since 4.6.0 300 * @access public 301 * @var string $_edit_link 302 */ 303 public $_edit_link = 'post.php?post=%d'; 304 305 306 /** 307 * Post type capabilities. 308 * 309 * @since 4.6.0 310 * @access public 311 * @var array $cap 312 */ 313 public $cap; 314 315 /** 316 * Triggers the handling of rewrites for this post type. 317 * 318 * Defaults to true, using $post_type as slug. 319 * 320 * @since 4.6.0 321 * @access public 322 * @var array|false $rewrite 323 */ 324 public $rewrite; 325 326 /** 327 * The features supported by the post type. 328 * 329 * @since 4.6.0 330 * @access public 331 * @var array|bool $supports 332 */ 333 public $supports; 334 335 /** 336 * Constructor. 337 * 338 * Will populate object properties from the provided arguments and assign other 339 * default properties based on that information. 340 * 341 * @since 4.6.0 342 * @access public 343 * 344 * @see register_post_type() 345 * 346 * @param string $post_type Post type key. 347 * @param array|string $args Optional. Array or string of arguments for registering a post type. 348 * Default empty array. 349 */ 350 public function __construct( $post_type, $args = array() ) { 351 $this->name = $post_type; 352 353 $this->set_props( $args ); 354 } 355 356 /** 357 * Sets post type properties. 358 * 359 * @since 4.6.0 360 * @access public 361 * 362 * @param array|string $args Array or string of arguments for registering a post type. 363 */ 364 public function set_props( $args ) { 365 $args = wp_parse_args( $args ); 366 367 /** 368 * Filter the arguments for registering a post type. 369 * 370 * @since 4.4.0 371 * 372 * @param array $args Array of arguments for registering a post type. 373 * @param string $post_type Post type key. 374 */ 375 $args = apply_filters( 'register_post_type_args', $args, $this->name ); 376 377 $has_edit_link = ! empty( $args['_edit_link'] ); 378 379 // Args prefixed with an underscore are reserved for internal use. 380 $defaults = array( 381 'labels' => array(), 382 'description' => '', 383 'public' => false, 384 'hierarchical' => false, 385 'exclude_from_search' => null, 386 'publicly_queryable' => null, 387 'show_ui' => null, 388 'show_in_menu' => null, 389 'show_in_nav_menus' => null, 390 'show_in_admin_bar' => null, 391 'menu_position' => null, 392 'menu_icon' => null, 393 'capability_type' => 'post', 394 'capabilities' => array(), 395 'map_meta_cap' => null, 396 'supports' => array(), 397 'register_meta_box_cb' => null, 398 'taxonomies' => array(), 399 'has_archive' => false, 400 'rewrite' => true, 401 'query_var' => true, 402 'can_export' => true, 403 'delete_with_user' => null, 404 '_builtin' => false, 405 '_edit_link' => 'post.php?post=%d', 406 ); 407 408 $args = array_merge( $defaults, $args ); 409 410 $args['name'] = $this->name; 411 412 // If not set, default to the setting for public. 413 if ( null === $args['publicly_queryable'] ) { 414 $args['publicly_queryable'] = $args['public']; 415 } 416 417 // If not set, default to the setting for public. 418 if ( null === $args['show_ui'] ) { 419 $args['show_ui'] = $args['public']; 420 } 421 422 // If not set, default to the setting for show_ui. 423 if ( null === $args['show_in_menu'] || ! $args['show_ui'] ) { 424 $args['show_in_menu'] = $args['show_ui']; 425 } 426 427 // If not set, default to the whether the full UI is shown. 428 if ( null === $args['show_in_admin_bar'] ) { 429 $args['show_in_admin_bar'] = (bool) $args['show_in_menu']; 430 } 431 432 // If not set, default to the setting for public. 433 if ( null === $args['show_in_nav_menus'] ) { 434 $args['show_in_nav_menus'] = $args['public']; 435 } 436 437 // If not set, default to true if not public, false if public. 438 if ( null === $args['exclude_from_search'] ) { 439 $args['exclude_from_search'] = ! $args['public']; 440 } 441 442 // Back compat with quirky handling in version 3.0. #14122. 443 if ( empty( $args['capabilities'] ) && null === $args['map_meta_cap'] && in_array( $args['capability_type'], array( 'post', 'page' ) ) ) { 444 $args['map_meta_cap'] = true; 445 } 446 447 // If not set, default to false. 448 if ( null === $args['map_meta_cap'] ) { 449 $args['map_meta_cap'] = false; 450 } 451 452 // If there's no specified edit link and no UI, remove the edit link. 453 if ( ! $args['show_ui'] && ! $has_edit_link ) { 454 $args['_edit_link'] = ''; 455 } 456 457 $this->cap = get_post_type_capabilities( (object) $args ); 458 unset( $args['capabilities'] ); 459 460 if ( is_array( $args['capability_type'] ) ) { 461 $args['capability_type'] = $args['capability_type'][0]; 462 } 463 464 if ( false !== $args['query_var'] ) { 465 if ( true === $args['query_var'] ) { 466 $args['query_var'] = $this->name; 467 } else { 468 $args['query_var'] = sanitize_title_with_dashes( $args['query_var'] ); 469 } 470 } 471 472 if ( false !== $args['rewrite'] && ( is_admin() || '' != get_option( 'permalink_structure' ) ) ) { 473 if ( ! is_array( $args['rewrite'] ) ) { 474 $args['rewrite'] = array(); 475 } 476 if ( empty( $args['rewrite']['slug'] ) ) { 477 $args['rewrite']['slug'] = $this->name; 478 } 479 if ( ! isset( $args['rewrite']['with_front'] ) ) { 480 $args['rewrite']['with_front'] = true; 481 } 482 if ( ! isset( $args['rewrite']['pages'] ) ) { 483 $args['rewrite']['pages'] = true; 484 } 485 if ( ! isset( $args['rewrite']['feeds'] ) || ! $args['has_archive'] ) { 486 $args['rewrite']['feeds'] = (bool) $args['has_archive']; 487 } 488 if ( ! isset( $args['rewrite']['ep_mask'] ) ) { 489 if ( isset( $args['permalink_epmask'] ) ) { 490 $args['rewrite']['ep_mask'] = $args['permalink_epmask']; 491 } else { 492 $args['rewrite']['ep_mask'] = EP_PERMALINK; 493 } 494 } 495 } 496 497 foreach ( $args as $property_name => $property_value ) { 498 $this->$property_name = $property_value; 499 } 500 501 $this->labels = get_post_type_labels( $this ); 502 $this->label = $this->labels->name; 503 } 504 505 /** 506 * Sets the features support for the post type. 507 * 508 * @since 4.6.0 509 * @access public 510 */ 511 public function add_supports() { 512 if ( ! empty( $this->supports ) ) { 513 add_post_type_support( $this->name, $this->supports ); 514 unset( $this->supports ); 515 } elseif ( false !== $this->supports ) { 516 // Add default features. 517 add_post_type_support( $this->name, array( 'title', 'editor' ) ); 518 } 519 } 520 521 /** 522 * Adds the necessary rewrite rules for the post type. 523 * 524 * @since 4.6.0 525 * @access public 526 * 527 * @global WP_Rewrite $wp_rewrite WordPress Rewrite Component. 528 * @global WP $wp Current WordPress environment instance. 529 */ 530 public function add_rewrite_rules() { 531 global $wp_rewrite, $wp; 532 533 if ( false !== $this->query_var && $wp && is_post_type_viewable( $this ) ) { 534 $wp->add_query_var( $this->query_var ); 535 } 536 537 if ( false !== $this->rewrite && ( is_admin() || '' != get_option( 'permalink_structure' ) ) ) { 538 if ( $this->hierarchical ) { 539 add_rewrite_tag( "%$this->name%", '(.+?)', $this->query_var ? "{$this->query_var}=" : "post_type=$this->name&pagename=" ); 540 } else { 541 add_rewrite_tag( "%$this->name%", '([^/]+)', $this->query_var ? "{$this->query_var}=" : "post_type=$this->name&name=" ); 542 } 543 544 if ( $this->has_archive ) { 545 $archive_slug = true === $this->has_archive ? $this->rewrite['slug'] : $this->has_archive; 546 if ( $this->rewrite['with_front'] ) { 547 $archive_slug = substr( $wp_rewrite->front, 1 ) . $archive_slug; 548 } else { 549 $archive_slug = $wp_rewrite->root . $archive_slug; 550 } 551 552 add_rewrite_rule( "{$archive_slug}/?$", "index.php?post_type=$this->name", 'top' ); 553 if ( $this->rewrite['feeds'] && $wp_rewrite->feeds ) { 554 $feeds = '(' . trim( implode( '|', $wp_rewrite->feeds ) ) . ')'; 555 add_rewrite_rule( "{$archive_slug}/feed/$feeds/?$", "index.php?post_type=$this->name" . '&feed=$matches[1]', 'top' ); 556 add_rewrite_rule( "{$archive_slug}/$feeds/?$", "index.php?post_type=$this->name" . '&feed=$matches[1]', 'top' ); 557 } 558 if ( $this->rewrite['pages'] ) { 559 add_rewrite_rule( "{$archive_slug}/{$wp_rewrite->pagination_base}/([0-9]{1,})/?$", "index.php?post_type=$this->name" . '&paged=$matches[1]', 'top' ); 560 } 561 } 562 563 $permastruct_args = $this->rewrite; 564 $permastruct_args['feed'] = $permastruct_args['feeds']; 565 add_permastruct( $this->name, "{$this->rewrite['slug']}/%$this->name%", $permastruct_args ); 566 } 567 } 568 569 /** 570 * Registers the post type meta box if a custom callback was specified. 571 * 572 * @since 4.6.0 573 * @access public 574 */ 575 public function register_meta_boxes() { 576 if ( $this->register_meta_box_cb ) { 577 add_action( 'add_meta_boxes_' . $this->name, $this->register_meta_box_cb, 10, 1 ); 578 } 579 } 580 581 /** 582 * Adds the future post hook action for the post type. 583 * 584 * @since 4.6.0 585 * @access public 586 */ 587 public function add_hooks() { 588 add_action( 'future_' . $this->name, '_future_post_hook', 5, 2 ); 589 } 590 591 /** 592 * Registers the taxonomies for the post type. 593 * 594 * @since 4.6.0 595 * @access public 596 */ 597 public function register_taxonomies() { 598 foreach ( $this->taxonomies as $taxonomy ) { 599 register_taxonomy_for_object_type( $taxonomy, $this->name ); 600 } 601 } 602 603 /** 604 * Removes the features support for the post type. 605 * 606 * @since 4.6.0 607 * @access public 608 * 609 * @global array $_wp_post_type_features Post type features. 610 */ 611 public function remove_supports() { 612 global $_wp_post_type_features; 613 614 unset( $_wp_post_type_features[ $this->name ] ); 615 } 616 617 /** 618 * Removes any rewrite rules, permastructs, and rules for the post type. 619 * 620 * @since 4.6.0 621 * @access public 622 * 623 * @global WP_Rewrite $wp_rewrite WordPress rewrite component. 624 * @global WP $wp Current WordPress environment instance. 625 * @global array $post_type_meta_caps Used to remove meta capabilities. 626 */ 627 public function remove_rewrite_rules() { 628 global $wp, $wp_rewrite, $post_type_meta_caps; 629 630 // Remove query var. 631 if ( false !== $this->query_var ) { 632 $wp->remove_query_var( $this->query_var ); 633 } 634 635 // Remove any rewrite rules, permastructs, and rules. 636 if ( false !== $this->rewrite ) { 637 remove_rewrite_tag( "%$this->name%" ); 638 remove_permastruct( $this->name ); 639 foreach ( $wp_rewrite->extra_rules_top as $regex => $query ) { 640 if ( false !== strpos( $query, "index.php?post_type=$this->name" ) ) { 641 unset( $wp_rewrite->extra_rules_top[ $regex ] ); 642 } 643 } 644 } 645 646 // Remove registered custom meta capabilities. 647 foreach ( $this->cap as $cap ) { 648 unset( $post_type_meta_caps[ $cap ] ); 649 } 650 } 651 652 /** 653 * Unregisters the post type meta box if a custom callback was specified. 654 * 655 * @since 4.6.0 656 * @access public 657 */ 658 public function unregister_meta_boxes() { 659 if ( $this->register_meta_box_cb ) { 660 remove_action( 'add_meta_boxes_' . $this->name, $this->register_meta_box_cb, 10 ); 661 } 662 } 663 664 /** 665 * Removes the post type from all taxonomies. 666 * 667 * @since 4.6.0 668 * @access public 669 */ 670 public function unregister_taxonomies() { 671 foreach ( get_object_taxonomies( $this->name ) as $taxonomy ) { 672 unregister_taxonomy_for_object_type( $taxonomy, $this->name ); 673 } 674 } 675 676 /** 677 * Removes the future post hook action for the post type. 678 * 679 * @since 4.6.0 680 * @access public 681 */ 682 public function remove_hooks() { 683 remove_action( 'future_' . $this->name, '_future_post_hook', 5 ); 684 } 685 } -
src/wp-includes/class-wp-xmlrpc-server.php
883 883 * 884 884 * @access protected 885 885 * 886 * @param object$post_type Post type object.887 * @param array $fields The subset of post fields to return.886 * @param WP_Post_Type $post_type Post type object. 887 * @param array $fields The subset of post fields to return. 888 888 * @return array The prepared post type data. 889 889 */ 890 890 protected function _prepare_post_type( $post_type, $fields ) { … … 922 922 * 923 923 * @since 3.4.0 924 924 * 925 * @param array $_post_type An array of post type data.926 * @param object$post_type Post type object.925 * @param array $_post_type An array of post type data. 926 * @param WP_Post_Type $post_type Post type object. 927 927 */ 928 928 return apply_filters( 'xmlrpc_prepare_post_type', $_post_type, $post_type ); 929 929 } -
src/wp-includes/post.php
819 819 } 820 820 821 821 /** 822 * Retrieve the post type of the current post or of a given post.822 * Retrieves the post type of the current post or of a given post. 823 823 * 824 824 * @since 2.1.0 825 825 * … … 834 834 } 835 835 836 836 /** 837 * Retrieve a post type object by name.837 * Retrieves a post type object by name. 838 838 * 839 839 * @since 3.0.0 840 840 * … … 843 843 * @see register_post_type() 844 844 * 845 845 * @param string $post_type The name of a registered post type. 846 * @return object|null A post type object.846 * @return WP_Post_Type|null WP_Post_Type object if it exists, null otherwise. 847 847 */ 848 848 function get_post_type_object( $post_type ) { 849 849 global $wp_post_types; … … 899 899 * @since 3.0.0 The `show_ui` argument is now enforced on the new post screen. 900 900 * @since 4.4.0 The `show_ui` argument is now enforced on the post type listing 901 901 * screen and post editing screen. 902 * @since 4.6.0 Converted to use `WP_Post_Type`. 902 903 * 903 * @global array $wp_post_types List of post types. 904 * @global WP_Rewrite $wp_rewrite Used for default feeds. 905 * @global WP $wp Used to add query vars. 904 * @global array $wp_post_types List of post types. 906 905 * 907 906 * @param string $post_type Post type key. Must not exceed 20 characters and may 908 907 * only contain lowercase alphanumeric characters, dashes, … … 1011 1010 * @type string $_edit_link FOR INTERNAL USE ONLY! URL segment to use for edit link of 1012 1011 * this post type. Default 'post.php?post=%d'. 1013 1012 * } 1014 * @return object|WP_Error The registered post type object, or an error object.1013 * @return WP_Post_Type|WP_Error The registered post type object, or an error object. 1015 1014 */ 1016 1015 function register_post_type( $post_type, $args = array() ) { 1017 global $wp_post_types , $wp_rewrite, $wp;1016 global $wp_post_types; 1018 1017 1019 1018 if ( ! is_array( $wp_post_types ) ) { 1020 1019 $wp_post_types = array(); … … 1022 1021 1023 1022 // Sanitize post type name 1024 1023 $post_type = sanitize_key( $post_type ); 1025 $args = wp_parse_args( $args );1026 1024 1027 /**1028 * Filters the arguments for registering a post type.1029 *1030 * @since 4.4.01031 *1032 * @param array $args Array of arguments for registering a post type.1033 * @param string $post_type Post type key.1034 */1035 $args = apply_filters( 'register_post_type_args', $args, $post_type );1036 1037 $has_edit_link = ! empty( $args['_edit_link'] );1038 1039 // Args prefixed with an underscore are reserved for internal use.1040 $defaults = array(1041 'labels' => array(),1042 'description' => '',1043 'public' => false,1044 'hierarchical' => false,1045 'exclude_from_search' => null,1046 'publicly_queryable' => null,1047 'show_ui' => null,1048 'show_in_menu' => null,1049 'show_in_nav_menus' => null,1050 'show_in_admin_bar' => null,1051 'menu_position' => null,1052 'menu_icon' => null,1053 'capability_type' => 'post',1054 'capabilities' => array(),1055 'map_meta_cap' => null,1056 'supports' => array(),1057 'register_meta_box_cb' => null,1058 'taxonomies' => array(),1059 'has_archive' => false,1060 'rewrite' => true,1061 'query_var' => true,1062 'can_export' => true,1063 'delete_with_user' => null,1064 '_builtin' => false,1065 '_edit_link' => 'post.php?post=%d',1066 );1067 $args = array_merge( $defaults, $args );1068 $args = (object) $args;1069 1070 $args->name = $post_type;1071 1072 1025 if ( empty( $post_type ) || strlen( $post_type ) > 20 ) { 1073 1026 _doing_it_wrong( __FUNCTION__, __( 'Post type names must be between 1 and 20 characters in length.' ), '4.2' ); 1074 1027 return new WP_Error( 'post_type_length_invalid', __( 'Post type names must be between 1 and 20 characters in length.' ) ); 1075 1028 } 1076 1029 1077 // If not set, default to the setting for public. 1078 if ( null === $args->publicly_queryable ) 1079 $args->publicly_queryable = $args->public; 1030 $post_type_object = new WP_Post_Type( $post_type, $args ); 1031 $post_type_object->add_supports(); 1032 $post_type_object->add_rewrite_rules(); 1033 $post_type_object->register_meta_boxes(); 1080 1034 1081 // If not set, default to the setting for public. 1082 if ( null === $args->show_ui ) 1083 $args->show_ui = $args->public; 1035 $wp_post_types[ $post_type ] = $post_type_object; 1084 1036 1085 // If not set, default to the setting for show_ui. 1086 if ( null === $args->show_in_menu || ! $args->show_ui ) 1087 $args->show_in_menu = $args->show_ui; 1037 $post_type_object->add_hooks(); 1038 $post_type_object->register_taxonomies(); 1088 1039 1089 // If not set, default to the whether the full UI is shown.1090 if ( null === $args->show_in_admin_bar )1091 $args->show_in_admin_bar = (bool) $args->show_in_menu;1092 1093 // If not set, default to the setting for public.1094 if ( null === $args->show_in_nav_menus )1095 $args->show_in_nav_menus = $args->public;1096 1097 // If not set, default to true if not public, false if public.1098 if ( null === $args->exclude_from_search )1099 $args->exclude_from_search = !$args->public;1100 1101 // Back compat with quirky handling in version 3.0. #14122.1102 if ( empty( $args->capabilities ) && null === $args->map_meta_cap && in_array( $args->capability_type, array( 'post', 'page' ) ) )1103 $args->map_meta_cap = true;1104 1105 // If not set, default to false.1106 if ( null === $args->map_meta_cap )1107 $args->map_meta_cap = false;1108 1109 // If there's no specified edit link and no UI, remove the edit link.1110 if ( ! $args->show_ui && ! $has_edit_link ) {1111 $args->_edit_link = '';1112 }1113 1114 $args->cap = get_post_type_capabilities( $args );1115 unset( $args->capabilities );1116 1117 if ( is_array( $args->capability_type ) )1118 $args->capability_type = $args->capability_type[0];1119 1120 if ( ! empty( $args->supports ) ) {1121 add_post_type_support( $post_type, $args->supports );1122 unset( $args->supports );1123 } elseif ( false !== $args->supports ) {1124 // Add default features1125 add_post_type_support( $post_type, array( 'title', 'editor' ) );1126 }1127 1128 if ( false !== $args->query_var ) {1129 if ( true === $args->query_var )1130 $args->query_var = $post_type;1131 else1132 $args->query_var = sanitize_title_with_dashes( $args->query_var );1133 1134 if ( $wp && is_post_type_viewable( $args ) ) {1135 $wp->add_query_var( $args->query_var );1136 }1137 }1138 1139 if ( false !== $args->rewrite && ( is_admin() || '' != get_option( 'permalink_structure' ) ) ) {1140 if ( ! is_array( $args->rewrite ) )1141 $args->rewrite = array();1142 if ( empty( $args->rewrite['slug'] ) )1143 $args->rewrite['slug'] = $post_type;1144 if ( ! isset( $args->rewrite['with_front'] ) )1145 $args->rewrite['with_front'] = true;1146 if ( ! isset( $args->rewrite['pages'] ) )1147 $args->rewrite['pages'] = true;1148 if ( ! isset( $args->rewrite['feeds'] ) || ! $args->has_archive )1149 $args->rewrite['feeds'] = (bool) $args->has_archive;1150 if ( ! isset( $args->rewrite['ep_mask'] ) ) {1151 if ( isset( $args->permalink_epmask ) )1152 $args->rewrite['ep_mask'] = $args->permalink_epmask;1153 else1154 $args->rewrite['ep_mask'] = EP_PERMALINK;1155 }1156 1157 if ( $args->hierarchical )1158 add_rewrite_tag( "%$post_type%", '(.+?)', $args->query_var ? "{$args->query_var}=" : "post_type=$post_type&pagename=" );1159 else1160 add_rewrite_tag( "%$post_type%", '([^/]+)', $args->query_var ? "{$args->query_var}=" : "post_type=$post_type&name=" );1161 1162 if ( $args->has_archive ) {1163 $archive_slug = $args->has_archive === true ? $args->rewrite['slug'] : $args->has_archive;1164 if ( $args->rewrite['with_front'] )1165 $archive_slug = substr( $wp_rewrite->front, 1 ) . $archive_slug;1166 else1167 $archive_slug = $wp_rewrite->root . $archive_slug;1168 1169 add_rewrite_rule( "{$archive_slug}/?$", "index.php?post_type=$post_type", 'top' );1170 if ( $args->rewrite['feeds'] && $wp_rewrite->feeds ) {1171 $feeds = '(' . trim( implode( '|', $wp_rewrite->feeds ) ) . ')';1172 add_rewrite_rule( "{$archive_slug}/feed/$feeds/?$", "index.php?post_type=$post_type" . '&feed=$matches[1]', 'top' );1173 add_rewrite_rule( "{$archive_slug}/$feeds/?$", "index.php?post_type=$post_type" . '&feed=$matches[1]', 'top' );1174 }1175 if ( $args->rewrite['pages'] )1176 add_rewrite_rule( "{$archive_slug}/{$wp_rewrite->pagination_base}/([0-9]{1,})/?$", "index.php?post_type=$post_type" . '&paged=$matches[1]', 'top' );1177 }1178 1179 $permastruct_args = $args->rewrite;1180 $permastruct_args['feed'] = $permastruct_args['feeds'];1181 add_permastruct( $post_type, "{$args->rewrite['slug']}/%$post_type%", $permastruct_args );1182 }1183 1184 // Register the post type meta box if a custom callback was specified.1185 if ( $args->register_meta_box_cb )1186 add_action( 'add_meta_boxes_' . $post_type, $args->register_meta_box_cb, 10, 1 );1187 1188 $args->labels = get_post_type_labels( $args );1189 $args->label = $args->labels->name;1190 1191 $wp_post_types[ $post_type ] = $args;1192 1193 add_action( 'future_' . $post_type, '_future_post_hook', 5, 2 );1194 1195 foreach ( $args->taxonomies as $taxonomy ) {1196 register_taxonomy_for_object_type( $taxonomy, $post_type );1197 }1198 1199 1040 /** 1200 1041 * Fires after a post type is registered. 1201 1042 * 1202 1043 * @since 3.3.0 1203 1044 * 1204 * @param string $post_typePost type.1205 * @param object $argsArguments used to register the post type.1045 * @param string $post_type Post type. 1046 * @param WP_Post_Type $post_type_object Arguments used to register the post type. 1206 1047 */ 1207 do_action( 'registered_post_type', $post_type, $ args);1048 do_action( 'registered_post_type', $post_type, $post_type_object ); 1208 1049 1209 return $ args;1050 return $post_type_object; 1210 1051 } 1211 1052 1212 1053 /** … … 1215 1056 * Can not be used to unregister built-in post types. 1216 1057 * 1217 1058 * @since 4.5.0 1059 * @since 4.6.0 Converted to use `WP_Post_Type`. 1218 1060 * 1219 * @global WP_Rewrite $wp_rewrite WordPress rewrite component. 1220 * @global WP $wp Current WordPress environment instance. 1221 * @global array $_wp_post_type_features Used to remove post type features. 1222 * @global array $post_type_meta_caps Used to remove meta capabilities. 1223 * @global array $wp_post_types List of post types. 1061 * @global array $wp_post_types List of post types. 1224 1062 * 1225 1063 * @param string $post_type Post type to unregister. 1226 1064 * @return bool|WP_Error True on success, WP_Error on failure or if the post type doesn't exist. 1227 1065 */ 1228 1066 function unregister_post_type( $post_type ) { 1067 global $wp_post_types; 1068 1229 1069 if ( ! post_type_exists( $post_type ) ) { 1230 1070 return new WP_Error( 'invalid_post_type', __( 'Invalid post type' ) ); 1231 1071 } 1232 1072 1233 $post_type_ args= get_post_type_object( $post_type );1073 $post_type_object = get_post_type_object( $post_type ); 1234 1074 1235 1075 // Do not allow unregistering internal post types. 1236 if ( $post_type_ args->_builtin ) {1076 if ( $post_type_object->_builtin ) { 1237 1077 return new WP_Error( 'invalid_post_type', __( 'Unregistering a built-in post type is not allowed' ) ); 1238 1078 } 1239 1079 1240 global $wp, $wp_rewrite, $_wp_post_type_features, $post_type_meta_caps, $wp_post_types; 1080 $post_type_object->remove_supports(); 1081 $post_type_object->remove_rewrite_rules(); 1082 $post_type_object->unregister_meta_boxes(); 1083 $post_type_object->remove_hooks(); 1084 $post_type_object->unregister_taxonomies(); 1241 1085 1242 // Remove query var.1243 if ( false !== $post_type_args->query_var ) {1244 $wp->remove_query_var( $post_type_args->query_var );1245 }1246 1247 // Remove any rewrite rules, permastructs, and rules.1248 if ( false !== $post_type_args->rewrite ) {1249 remove_rewrite_tag( "%$post_type%" );1250 remove_permastruct( $post_type );1251 foreach ( $wp_rewrite->extra_rules_top as $regex => $query ) {1252 if ( false !== strpos( $query, "index.php?post_type=$post_type" ) ) {1253 unset( $wp_rewrite->extra_rules_top[ $regex ] );1254 }1255 }1256 }1257 1258 // Remove registered custom meta capabilities.1259 foreach ( $post_type_args->cap as $cap ) {1260 unset( $post_type_meta_caps[ $cap ] );1261 }1262 1263 // Remove all post type support.1264 unset( $_wp_post_type_features[ $post_type ] );1265 1266 // Unregister the post type meta box if a custom callback was specified.1267 if ( $post_type_args->register_meta_box_cb ) {1268 remove_action( 'add_meta_boxes_' . $post_type, $post_type_args->register_meta_box_cb );1269 }1270 1271 // Remove the post type from all taxonomies.1272 foreach ( get_object_taxonomies( $post_type ) as $taxonomy ) {1273 unregister_taxonomy_for_object_type( $taxonomy, $post_type );1274 }1275 1276 // Remove the future post hook action.1277 remove_action( 'future_' . $post_type, '_future_post_hook', 5 );1278 1279 // Remove the post type.1280 1086 unset( $wp_post_types[ $post_type ] ); 1281 1087 1282 1088 /** … … 1462 1268 * 1463 1269 * @access private 1464 1270 * 1465 * @param object $post_type_object Post type object.1271 * @param object|WP_Post_Type $post_type_object Post type object. 1466 1272 * @return object Object with all the labels as member variables. 1467 1273 */ 1468 1274 function get_post_type_labels( $post_type_object ) { … … 1717 1523 * @since 4.4.0 1718 1524 * @since 4.5.0 Added the ability to pass a post type name in addition to object. 1719 1525 * 1720 * @param object$post_type Post type name or object.1526 * @param string|WP_Post_Type $post_type Post type name or object. 1721 1527 * @return bool Whether the post type should be considered viewable. 1722 1528 */ 1723 1529 function is_post_type_viewable( $post_type ) { -
src/wp-settings.php
158 158 require( ABSPATH . WPINC . '/post.php' ); 159 159 require( ABSPATH . WPINC . '/class-walker-page.php' ); 160 160 require( ABSPATH . WPINC . '/class-walker-page-dropdown.php' ); 161 require( ABSPATH . WPINC . '/class-wp-post-type.php' ); 161 162 require( ABSPATH . WPINC . '/class-wp-post.php' ); 162 163 require( ABSPATH . WPINC . '/post-template.php' ); 163 164 require( ABSPATH . WPINC . '/revision.php' ); -
tests/phpunit/tests/post/types.php
29 29 register_post_type( 'foo' ); 30 30 31 31 $pobj = get_post_type_object( 'foo' ); 32 $this->assertInstanceOf( ' stdClass', $pobj );32 $this->assertInstanceOf( 'WP_Post_Type', $pobj ); 33 33 $this->assertEquals( 'foo', $pobj->name ); 34 34 35 35 // Test some defaults … … 554 554 * @since 4.5.0 555 555 * 556 556 * @param array $args register_post_type() arguments. 557 * @return stdClassPost type object for `$this->post_type`.557 * @return WP_Post_Type Post type object for `$this->post_type`. 558 558 */ 559 559 public function register_post_type( $args = array() ) { 560 560 register_post_type( $this->post_type, $args ); -
tests/phpunit/tests/post/wpPostType.php
1 <?php 2 3 /** 4 * @group post 5 */ 6 class Tests_WP_Post_Type extends WP_UnitTestCase { 7 public function test_instances() { 8 global $wp_post_types; 9 10 foreach ( $wp_post_types as $post_type ) { 11 $this->assertInstanceOf( 'WP_Post_Type', $post_type ); 12 } 13 } 14 15 public function test_add_supports_defaults() { 16 $post_type = rand_str(); 17 $post_type_object = new WP_Post_Type( $post_type ); 18 19 $post_type_object->add_supports(); 20 $post_type_supports = get_all_post_type_supports( $post_type ); 21 22 $post_type_object->remove_supports(); 23 $post_type_supports_after = get_all_post_type_supports( $post_type ); 24 25 $this->assertEqualSets( array( 'title' => true, 'editor' => true ), $post_type_supports ); 26 $this->assertEqualSets( array(), $post_type_supports_after ); 27 } 28 29 public function test_add_supports_custom() { 30 $post_type = rand_str(); 31 $post_type_object = new WP_Post_Type( $post_type, array( 32 'supports' => array( 33 'editor', 34 'comments', 35 'revisions', 36 ), 37 ) ); 38 39 $post_type_object->add_supports(); 40 $post_type_supports = get_all_post_type_supports( $post_type ); 41 42 $post_type_object->remove_supports(); 43 $post_type_supports_after = get_all_post_type_supports( $post_type ); 44 45 $this->assertEqualSets( array( 46 'editor' => true, 47 'comments' => true, 48 'revisions' => true, 49 ), $post_type_supports ); 50 $this->assertEqualSets( array(), $post_type_supports_after ); 51 } 52 53 public function test_does_not_add_query_var_if_not_public() { 54 $this->set_permalink_structure( '/%postname%' ); 55 56 /* @var WP $wp */ 57 global $wp; 58 59 $post_type = rand_str(); 60 $post_type_object = new WP_Post_Type( $post_type, array( 'rewrite' => false, 'query_var' => 'foobar' ) ); 61 $post_type_object->add_rewrite_rules(); 62 63 $this->assertFalse( in_array( 'foobar', $wp->public_query_vars ) ); 64 } 65 66 public function test_adds_query_var_if_public() { 67 $this->set_permalink_structure( '/%postname%' ); 68 69 /* @var WP $wp */ 70 global $wp; 71 72 $post_type = rand_str(); 73 $post_type_object = new WP_Post_Type( $post_type, array( 74 'public' => true, 75 'rewrite' => false, 76 'query_var' => 'foobar', 77 ) ); 78 79 $post_type_object->add_rewrite_rules(); 80 $in_array = in_array( 'foobar', $wp->public_query_vars ); 81 82 $post_type_object->remove_rewrite_rules(); 83 $in_array_after = in_array( 'foobar', $wp->public_query_vars ); 84 85 $this->assertTrue( $in_array ); 86 $this->assertFalse( $in_array_after ); 87 } 88 89 public function test_adds_rewrite_rules() { 90 $this->set_permalink_structure( '/%postname%' ); 91 92 /* @var WP_Rewrite $wp_rewrite */ 93 global $wp_rewrite; 94 95 $post_type = rand_str(); 96 $post_type_object = new WP_Post_Type( $post_type, array( 'public' => true, 'rewrite' => true ) ); 97 98 $post_type_object->add_rewrite_rules(); 99 $rewrite_tags = $wp_rewrite->rewritecode; 100 101 $post_type_object->remove_rewrite_rules(); 102 $rewrite_tags_after = $wp_rewrite->rewritecode; 103 104 $this->assertTrue( false !== array_search( "%$post_type%", $rewrite_tags ) ); 105 $this->assertFalse( array_search( "%$post_type%", $rewrite_tags_after ) ); 106 } 107 108 public function test_register_meta_boxes() { 109 $post_type = rand_str(); 110 $post_type_object = new WP_Post_Type( $post_type, array( 'register_meta_box_cb' => '__return_false' ) ); 111 112 $post_type_object->register_meta_boxes(); 113 $has_action = has_action( "add_meta_boxes_$post_type", '__return_false' ); 114 $post_type_object->unregister_meta_boxes(); 115 $has_action_after = has_action( "add_meta_boxes_$post_type", '__return_false' ); 116 117 $this->assertSame( 10, $has_action ); 118 $this->assertFalse( $has_action_after ); 119 } 120 121 public function test_adds_future_post_hook() { 122 $post_type = rand_str(); 123 $post_type_object = new WP_Post_Type( $post_type ); 124 $post_type_object->add_hooks(); 125 $has_action = has_action( "future_$post_type", '_future_post_hook' ); 126 $post_type_object->remove_hooks(); 127 $has_action_after = has_action( "future_$post_type", '_future_post_hook' ); 128 129 $this->assertSame( 5, $has_action ); 130 $this->assertFalse( $has_action_after ); 131 } 132 133 public function test_register_taxonomies() { 134 global $wp_post_types; 135 136 $post_type = rand_str(); 137 $post_type_object = new WP_Post_Type( $post_type, array( 'taxonomies' => array( 'post_tag' ) ) ); 138 139 $wp_post_types[ $post_type ] = $post_type_object; 140 141 $post_type_object->register_taxonomies(); 142 $taxonomies = get_object_taxonomies( $post_type ); 143 $post_type_object->unregister_taxonomies(); 144 $taxonomies_after = get_object_taxonomies( $post_type ); 145 146 unset( $wp_post_types[ $post_type ] ); 147 148 $this->assertEqualSets( array( 'post_tag' ), $taxonomies ); 149 $this->assertEqualSets( array(), $taxonomies_after ); 150 } 151 }