home *** CD-ROM | disk | FTP | other *** search
/ HTML Examples / WP.iso / wordpress / wp-includes / class-wp-post-type.php < prev    next >
Encoding:
PHP Script  |  2017-07-26  |  17.8 KB  |  680 lines

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