WP_Post_Type

Core class used for interacting with post types.

Defined (1)

The class is defined in the following location(s).

/wp-includes/class-wp-post-type.php  
  1. final class WP_Post_Type { 
  2. /** 
  3. * Post type key. 
  4. * @since 4.6.0 
  5. * @access public 
  6. * @var string $name 
  7. */ 
  8. public $name; 
  9.  
  10. /** 
  11. * Name of the post type shown in the menu. Usually plural. 
  12. * @since 4.6.0 
  13. * @access public 
  14. * @var string $label 
  15. */ 
  16. public $label; 
  17.  
  18. /** 
  19. * Labels object for this post type. 
  20. * If not set, post labels are inherited for non-hierarchical types 
  21. * and page labels for hierarchical ones. 
  22. * @see get_post_type_labels() 
  23. * @since 4.6.0 
  24. * @access public 
  25. * @var object $labels 
  26. */ 
  27. public $labels; 
  28.  
  29. /** 
  30. * A short descriptive summary of what the post type is. 
  31. * Default empty. 
  32. * @since 4.6.0 
  33. * @access public 
  34. * @var string $description 
  35. */ 
  36. public $description = ''; 
  37.  
  38. /** 
  39. * Whether a post type is intended for use publicly either via the admin interface or by front-end users. 
  40. * While the default settings of $exclude_from_search, $publicly_queryable, $show_ui, and $show_in_nav_menus 
  41. * are inherited from public, each does not rely on this relationship and controls a very specific intention. 
  42. * Default false. 
  43. * @since 4.6.0 
  44. * @access public 
  45. * @var bool $public 
  46. */ 
  47. public $public = false; 
  48.  
  49. /** 
  50. * Whether the post type is hierarchical (e.g. page). 
  51. * Default false. 
  52. * @since 4.6.0 
  53. * @access public 
  54. * @var bool $hierarchical 
  55. */ 
  56. public $hierarchical = false; 
  57.  
  58. /** 
  59. * Whether to exclude posts with this post type from front end search 
  60. * results. 
  61. * Default is the opposite value of $public. 
  62. * @since 4.6.0 
  63. * @access public 
  64. * @var bool $exclude_from_search 
  65. */ 
  66. public $exclude_from_search = null; 
  67.  
  68. /** 
  69. * Whether queries can be performed on the front end for the post type as part of `parse_request()`. 
  70. * Endpoints would include: 
  71. * - `?post_type={post_type_key}` 
  72. * - `?{post_type_key}={single_post_slug}` 
  73. * - `?{post_type_query_var}={single_post_slug}` 
  74. * Default is the value of $public. 
  75. * @since 4.6.0 
  76. * @access public 
  77. * @var bool $publicly_queryable 
  78. */ 
  79. public $publicly_queryable = null; 
  80.  
  81. /** 
  82. * Whether to generate and allow a UI for managing this post type in the admin. 
  83. * Default is the value of $public. 
  84. * @since 4.6.0 
  85. * @access public 
  86. * @var bool $show_ui 
  87. */ 
  88. public $show_ui = null; 
  89.  
  90. /** 
  91. * Where to show the post type in the admin menu. 
  92. * 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 
  93. * shown. If a string of an existing top level menu (eg. 'tools.php' or 'edit.php?post_type=page'), the post type 
  94. * will be placed as a sub-menu of that. 
  95. * Default is the value of $show_ui. 
  96. * @since 4.6.0 
  97. * @access public 
  98. * @var bool $show_in_menu 
  99. */ 
  100. public $show_in_menu = null; 
  101.  
  102. /** 
  103. * Makes this post type available for selection in navigation menus. 
  104. * Default is the value $public. 
  105. * @since 4.6.0 
  106. * @access public 
  107. * @var bool $show_in_nav_menus 
  108. */ 
  109. public $show_in_nav_menus = null; 
  110.  
  111. /** 
  112. * Makes this post type available via the admin bar. 
  113. * Default is the value of $show_in_menu. 
  114. * @since 4.6.0 
  115. * @access public 
  116. * @var bool $show_in_admin_bar 
  117. */ 
  118. public $show_in_admin_bar = null; 
  119.  
  120. /** 
  121. * The position in the menu order the post type should appear. 
  122. * To work, $show_in_menu must be true. Default null (at the bottom). 
  123. * @since 4.6.0 
  124. * @access public 
  125. * @var int $menu_position 
  126. */ 
  127. public $menu_position = null; 
  128.  
  129. /** 
  130. * The URL to the icon to be used for this menu. 
  131. * Pass a base64-encoded SVG using a data URI, which will be colored to match the color scheme. 
  132. * This should begin with 'data:image/svg+xml;base64, '. Pass the name of a Dashicons helper class 
  133. * to use a font icon, e.g. 'dashicons-chart-pie'. Pass 'none' to leave div.wp-menu-image empty 
  134. * so an icon can be added via CSS. 
  135. * Defaults to use the posts icon. 
  136. * @since 4.6.0 
  137. * @access public 
  138. * @var string $menu_icon 
  139. */ 
  140. public $menu_icon = null; 
  141.  
  142. /** 
  143. * The string to use to build the read, edit, and delete capabilities. 
  144. * May be passed as an array to allow for alternative plurals when using 
  145. * this argument as a base to construct the capabilities, e.g. 
  146. * array( 'story', 'stories' ). Default 'post'. 
  147. * @since 4.6.0 
  148. * @access public 
  149. * @var string $capability_type 
  150. */ 
  151. public $capability_type = 'post'; 
  152.  
  153. /** 
  154. * Whether to use the internal default meta capability handling. 
  155. * Default false. 
  156. * @since 4.6.0 
  157. * @access public 
  158. * @var bool $map_meta_cap 
  159. */ 
  160. public $map_meta_cap = false; 
  161.  
  162. /** 
  163. * Provide a callback function that sets up the meta boxes for the edit form. 
  164. * Do `remove_meta_box()` and `add_meta_box()` calls in the callback. Default null. 
  165. * @since 4.6.0 
  166. * @access public 
  167. * @var string $register_meta_box_cb 
  168. */ 
  169. public $register_meta_box_cb = null; 
  170.  
  171. /** 
  172. * An array of taxonomy identifiers that will be registered for the post type. 
  173. * Taxonomies can be registered later with `register_taxonomy()` or `register_taxonomy_for_object_type()`. 
  174. * Default empty array. 
  175. * @since 4.6.0 
  176. * @access public 
  177. * @var array $taxonomies 
  178. */ 
  179. public $taxonomies = array(); 
  180.  
  181. /** 
  182. * Whether there should be post type archives, or if a string, the archive slug to use. 
  183. * Will generate the proper rewrite rules if $rewrite is enabled. Default false. 
  184. * @since 4.6.0 
  185. * @access public 
  186. * @var bool|string $has_archive 
  187. */ 
  188. public $has_archive = false; 
  189.  
  190. /** 
  191. * Sets the query_var key for this post type. 
  192. * Defaults to $post_type key. If false, a post type cannot be loaded at `?{query_var}={post_slug}`. 
  193. * If specified as a string, the query `?{query_var_string}={post_slug}` will be valid. 
  194. * @since 4.6.0 
  195. * @access public 
  196. * @var string|bool $query_var 
  197. */ 
  198. public $query_var; 
  199.  
  200. /** 
  201. * Whether to allow this post type to be exported. 
  202. * Default true. 
  203. * @since 4.6.0 
  204. * @access public 
  205. * @var bool $can_export 
  206. */ 
  207. public $can_export = true; 
  208.  
  209. /** 
  210. * Whether to delete posts of this type when deleting a user. 
  211. * If true, posts of this type belonging to the user will be moved to trash when then user is deleted. 
  212. * If false, posts of this type belonging to the user will *not* be trashed or deleted. 
  213. * If not set (the default), posts are trashed if post_type_supports( 'author' ). 
  214. * Otherwise posts are not trashed or deleted. Default null. 
  215. * @since 4.6.0 
  216. * @access public 
  217. * @var bool $delete_with_user 
  218. */ 
  219. public $delete_with_user = null; 
  220.  
  221. /** 
  222. * Whether this post type is a native or "built-in" post_type. 
  223. * Default false. 
  224. * @since 4.6.0 
  225. * @access public 
  226. * @var bool $_builtin 
  227. */ 
  228. public $_builtin = false; 
  229.  
  230. /** 
  231. * URL segment to use for edit link of this post type. 
  232. * Default 'post.php?post=%d'. 
  233. * @since 4.6.0 
  234. * @access public 
  235. * @var string $_edit_link 
  236. */ 
  237. public $_edit_link = 'post.php?post=%d'; 
  238.  
  239. /** 
  240. * Post type capabilities. 
  241. * @since 4.6.0 
  242. * @access public 
  243. * @var object $cap 
  244. */ 
  245. public $cap; 
  246.  
  247. /** 
  248. * Triggers the handling of rewrites for this post type. 
  249. * Defaults to true, using $post_type as slug. 
  250. * @since 4.6.0 
  251. * @access public 
  252. * @var array|false $rewrite 
  253. */ 
  254. public $rewrite; 
  255.  
  256. /** 
  257. * The features supported by the post type. 
  258. * @since 4.6.0 
  259. * @access public 
  260. * @var array|bool $supports 
  261. */ 
  262. public $supports; 
  263.  
  264. /** 
  265. * Constructor. 
  266. * Will populate object properties from the provided arguments and assign other 
  267. * default properties based on that information. 
  268. * @since 4.6.0 
  269. * @access public 
  270. * @see register_post_type() 
  271. * @param string $post_type Post type key. 
  272. * @param array|string $args Optional. Array or string of arguments for registering a post type. 
  273. * Default empty array. 
  274. */ 
  275. public function __construct( $post_type, $args = array() ) { 
  276. $this->name = $post_type; 
  277.  
  278. $this->set_props( $args ); 
  279.  
  280. /** 
  281. * Sets post type properties. 
  282. * @since 4.6.0 
  283. * @access public 
  284. * @param array|string $args Array or string of arguments for registering a post type. 
  285. */ 
  286. public function set_props( $args ) { 
  287. $args = wp_parse_args( $args ); 
  288.  
  289. /** 
  290. * Filter the arguments for registering a post type. 
  291. * @since 4.4.0 
  292. * @param array $args Array of arguments for registering a post type. 
  293. * @param string $post_type Post type key. 
  294. */ 
  295. $args = apply_filters( 'register_post_type_args', $args, $this->name ); 
  296.  
  297. $has_edit_link = ! empty( $args['_edit_link'] ); 
  298.  
  299. // Args prefixed with an underscore are reserved for internal use. 
  300. $defaults = array( 
  301. 'labels' => array(),  
  302. 'description' => '',  
  303. 'public' => false,  
  304. 'hierarchical' => false,  
  305. 'exclude_from_search' => null,  
  306. 'publicly_queryable' => null,  
  307. 'show_ui' => null,  
  308. 'show_in_menu' => null,  
  309. 'show_in_nav_menus' => null,  
  310. 'show_in_admin_bar' => null,  
  311. 'menu_position' => null,  
  312. 'menu_icon' => null,  
  313. 'capability_type' => 'post',  
  314. 'capabilities' => array(),  
  315. 'map_meta_cap' => null,  
  316. 'supports' => array(),  
  317. 'register_meta_box_cb' => null,  
  318. 'taxonomies' => array(),  
  319. 'has_archive' => false,  
  320. 'rewrite' => true,  
  321. 'query_var' => true,  
  322. 'can_export' => true,  
  323. 'delete_with_user' => null,  
  324. '_builtin' => false,  
  325. '_edit_link' => 'post.php?post=%d',  
  326. ); 
  327.  
  328. $args = array_merge( $defaults, $args ); 
  329.  
  330. $args['name'] = $this->name; 
  331.  
  332. // If not set, default to the setting for public. 
  333. if ( null === $args['publicly_queryable'] ) { 
  334. $args['publicly_queryable'] = $args['public']; 
  335.  
  336. // If not set, default to the setting for public. 
  337. if ( null === $args['show_ui'] ) { 
  338. $args['show_ui'] = $args['public']; 
  339.  
  340. // If not set, default to the setting for show_ui. 
  341. if ( null === $args['show_in_menu'] || ! $args['show_ui'] ) { 
  342. $args['show_in_menu'] = $args['show_ui']; 
  343.  
  344. // If not set, default to the whether the full UI is shown. 
  345. if ( null === $args['show_in_admin_bar'] ) { 
  346. $args['show_in_admin_bar'] = (bool) $args['show_in_menu']; 
  347.  
  348. // If not set, default to the setting for public. 
  349. if ( null === $args['show_in_nav_menus'] ) { 
  350. $args['show_in_nav_menus'] = $args['public']; 
  351.  
  352. // If not set, default to true if not public, false if public. 
  353. if ( null === $args['exclude_from_search'] ) { 
  354. $args['exclude_from_search'] = ! $args['public']; 
  355.  
  356. // Back compat with quirky handling in version 3.0. #14122. 
  357. if ( empty( $args['capabilities'] ) && null === $args['map_meta_cap'] && in_array( $args['capability_type'], array( 'post', 'page' ) ) ) { 
  358. $args['map_meta_cap'] = true; 
  359.  
  360. // If not set, default to false. 
  361. if ( null === $args['map_meta_cap'] ) { 
  362. $args['map_meta_cap'] = false; 
  363.  
  364. // If there's no specified edit link and no UI, remove the edit link. 
  365. if ( ! $args['show_ui'] && ! $has_edit_link ) { 
  366. $args['_edit_link'] = ''; 
  367.  
  368. $this->cap = get_post_type_capabilities( (object) $args ); 
  369. unset( $args['capabilities'] ); 
  370.  
  371. if ( is_array( $args['capability_type'] ) ) { 
  372. $args['capability_type'] = $args['capability_type'][0]; 
  373.  
  374. if ( false !== $args['query_var'] ) { 
  375. if ( true === $args['query_var'] ) { 
  376. $args['query_var'] = $this->name; 
  377. } else { 
  378. $args['query_var'] = sanitize_title_with_dashes( $args['query_var'] ); 
  379.  
  380. if ( false !== $args['rewrite'] && ( is_admin() || '' != get_option( 'permalink_structure' ) ) ) { 
  381. if ( ! is_array( $args['rewrite'] ) ) { 
  382. $args['rewrite'] = array(); 
  383. if ( empty( $args['rewrite']['slug'] ) ) { 
  384. $args['rewrite']['slug'] = $this->name; 
  385. if ( ! isset( $args['rewrite']['with_front'] ) ) { 
  386. $args['rewrite']['with_front'] = true; 
  387. if ( ! isset( $args['rewrite']['pages'] ) ) { 
  388. $args['rewrite']['pages'] = true; 
  389. if ( ! isset( $args['rewrite']['feeds'] ) || ! $args['has_archive'] ) { 
  390. $args['rewrite']['feeds'] = (bool) $args['has_archive']; 
  391. if ( ! isset( $args['rewrite']['ep_mask'] ) ) { 
  392. if ( isset( $args['permalink_epmask'] ) ) { 
  393. $args['rewrite']['ep_mask'] = $args['permalink_epmask']; 
  394. } else { 
  395. $args['rewrite']['ep_mask'] = EP_PERMALINK; 
  396.  
  397. foreach ( $args as $property_name => $property_value ) { 
  398. $this->$property_name = $property_value; 
  399.  
  400. $this->labels = get_post_type_labels( $this ); 
  401. $this->label = $this->labels->name; 
  402.  
  403. /** 
  404. * Sets the features support for the post type. 
  405. * @since 4.6.0 
  406. * @access public 
  407. */ 
  408. public function add_supports() { 
  409. if ( ! empty( $this->supports ) ) { 
  410. add_post_type_support( $this->name, $this->supports ); 
  411. unset( $this->supports ); 
  412. } elseif ( false !== $this->supports ) { 
  413. // Add default features. 
  414. add_post_type_support( $this->name, array( 'title', 'editor' ) ); 
  415.  
  416. /** 
  417. * Adds the necessary rewrite rules for the post type. 
  418. * @since 4.6.0 
  419. * @access public 
  420. * @global WP_Rewrite $wp_rewrite WordPress Rewrite Component. 
  421. * @global WP $wp Current WordPress environment instance. 
  422. */ 
  423. public function add_rewrite_rules() { 
  424. global $wp_rewrite, $wp; 
  425.  
  426. if ( false !== $this->query_var && $wp && is_post_type_viewable( $this ) ) { 
  427. $wp->add_query_var( $this->query_var ); 
  428.  
  429. if ( false !== $this->rewrite && ( is_admin() || '' != get_option( 'permalink_structure' ) ) ) { 
  430. if ( $this->hierarchical ) { 
  431. add_rewrite_tag( "%$this->name%", '(.+?)', $this->query_var ? "{$this->query_var}=" : "post_type=$this->name&pagename=" ); 
  432. } else { 
  433. add_rewrite_tag( "%$this->name%", '([^/]+)', $this->query_var ? "{$this->query_var}=" : "post_type=$this->name&name=" ); 
  434.  
  435. if ( $this->has_archive ) { 
  436. $archive_slug = true === $this->has_archive ? $this->rewrite['slug'] : $this->has_archive; 
  437. if ( $this->rewrite['with_front'] ) { 
  438. $archive_slug = substr( $wp_rewrite->front, 1 ) . $archive_slug; 
  439. } else { 
  440. $archive_slug = $wp_rewrite->root . $archive_slug; 
  441.  
  442. add_rewrite_rule( "{$archive_slug}/?$", "index.php?post_type=$this->name", 'top' ); 
  443. if ( $this->rewrite['feeds'] && $wp_rewrite->feeds ) { 
  444. $feeds = '(' . trim( implode( '|', $wp_rewrite->feeds ) ) . ')'; 
  445. add_rewrite_rule( "{$archive_slug}/feed/$feeds/?$", "index.php?post_type=$this->name" . '&feed=$matches[1]', 'top' ); 
  446. add_rewrite_rule( "{$archive_slug}/$feeds/?$", "index.php?post_type=$this->name" . '&feed=$matches[1]', 'top' ); 
  447. if ( $this->rewrite['pages'] ) { 
  448. add_rewrite_rule( "{$archive_slug}/{$wp_rewrite->pagination_base}/([0-9]{1, })/?$", "index.php?post_type=$this->name" . '&paged=$matches[1]', 'top' ); 
  449.  
  450. $permastruct_args = $this->rewrite; 
  451. $permastruct_args['feed'] = $permastruct_args['feeds']; 
  452. add_permastruct( $this->name, "{$this->rewrite['slug']}/%$this->name%", $permastruct_args ); 
  453.  
  454. /** 
  455. * Registers the post type meta box if a custom callback was specified. 
  456. * @since 4.6.0 
  457. * @access public 
  458. */ 
  459. public function register_meta_boxes() { 
  460. if ( $this->register_meta_box_cb ) { 
  461. add_action( 'add_meta_boxes_' . $this->name, $this->register_meta_box_cb, 10, 1 ); 
  462.  
  463. /** 
  464. * Adds the future post hook action for the post type. 
  465. * @since 4.6.0 
  466. * @access public 
  467. */ 
  468. public function add_hooks() { 
  469. add_action( 'future_' . $this->name, '_future_post_hook', 5, 2 ); 
  470.  
  471. /** 
  472. * Registers the taxonomies for the post type. 
  473. * @since 4.6.0 
  474. * @access public 
  475. */ 
  476. public function register_taxonomies() { 
  477. foreach ( $this->taxonomies as $taxonomy ) { 
  478. register_taxonomy_for_object_type( $taxonomy, $this->name ); 
  479.  
  480. /** 
  481. * Removes the features support for the post type. 
  482. * @since 4.6.0 
  483. * @access public 
  484. * @global array $_wp_post_type_features Post type features. 
  485. */ 
  486. public function remove_supports() { 
  487. global $_wp_post_type_features; 
  488.  
  489. unset( $_wp_post_type_features[ $this->name ] ); 
  490.  
  491. /** 
  492. * Removes any rewrite rules, permastructs, and rules for the post type. 
  493. * @since 4.6.0 
  494. * @access public 
  495. * @global WP_Rewrite $wp_rewrite WordPress rewrite component. 
  496. * @global WP $wp Current WordPress environment instance. 
  497. * @global array $post_type_meta_caps Used to remove meta capabilities. 
  498. */ 
  499. public function remove_rewrite_rules() { 
  500. global $wp, $wp_rewrite, $post_type_meta_caps; 
  501.  
  502. // Remove query var. 
  503. if ( false !== $this->query_var ) { 
  504. $wp->remove_query_var( $this->query_var ); 
  505.  
  506. // Remove any rewrite rules, permastructs, and rules. 
  507. if ( false !== $this->rewrite ) { 
  508. remove_rewrite_tag( "%$this->name%" ); 
  509. remove_permastruct( $this->name ); 
  510. foreach ( $wp_rewrite->extra_rules_top as $regex => $query ) { 
  511. if ( false !== strpos( $query, "index.php?post_type=$this->name" ) ) { 
  512. unset( $wp_rewrite->extra_rules_top[ $regex ] ); 
  513.  
  514. // Remove registered custom meta capabilities. 
  515. foreach ( $this->cap as $cap ) { 
  516. unset( $post_type_meta_caps[ $cap ] ); 
  517.  
  518. /** 
  519. * Unregisters the post type meta box if a custom callback was specified. 
  520. * @since 4.6.0 
  521. * @access public 
  522. */ 
  523. public function unregister_meta_boxes() { 
  524. if ( $this->register_meta_box_cb ) { 
  525. remove_action( 'add_meta_boxes_' . $this->name, $this->register_meta_box_cb, 10 ); 
  526.  
  527. /** 
  528. * Removes the post type from all taxonomies. 
  529. * @since 4.6.0 
  530. * @access public 
  531. */ 
  532. public function unregister_taxonomies() { 
  533. foreach ( get_object_taxonomies( $this->name ) as $taxonomy ) { 
  534. unregister_taxonomy_for_object_type( $taxonomy, $this->name ); 
  535.  
  536. /** 
  537. * Removes the future post hook action for the post type. 
  538. * @since 4.6.0 
  539. * @access public 
  540. */ 
  541. public function remove_hooks() { 
  542. remove_action( 'future_' . $this->name, '_future_post_hook', 5 );