home *** CD-ROM | disk | FTP | other *** search
/ HTML Examples / WP.iso / wordpress / wp-includes / rest-api / endpoints / class-wp-rest-post-statuses-controller.php < prev    next >
Encoding:
PHP Script  |  2017-10-04  |  8.9 KB  |  309 lines

  1. <?php
  2. /**
  3.  * REST API: WP_REST_Post_Statuses_Controller class
  4.  *
  5.  * @package WordPress
  6.  * @subpackage REST_API
  7.  * @since 4.7.0
  8.  */
  9.  
  10. /**
  11.  * Core class used to access post statuses via the REST API.
  12.  *
  13.  * @since 4.7.0
  14.  *
  15.  * @see WP_REST_Controller
  16.  */
  17. class WP_REST_Post_Statuses_Controller extends WP_REST_Controller {
  18.  
  19.     /**
  20.      * Constructor.
  21.      *
  22.      * @since 4.7.0
  23.      */
  24.     public function __construct() {
  25.         $this->namespace = 'wp/v2';
  26.         $this->rest_base = 'statuses';
  27.     }
  28.  
  29.     /**
  30.      * Registers the routes for the objects of the controller.
  31.      *
  32.      * @since 4.7.0
  33.      *
  34.      * @see register_rest_route()
  35.      */
  36.     public function register_routes() {
  37.  
  38.         register_rest_route( $this->namespace, '/' . $this->rest_base, array(
  39.             array(
  40.                 'methods'             => WP_REST_Server::READABLE,
  41.                 'callback'            => array( $this, 'get_items' ),
  42.                 'permission_callback' => array( $this, 'get_items_permissions_check' ),
  43.                 'args'                => $this->get_collection_params(),
  44.             ),
  45.             'schema' => array( $this, 'get_public_item_schema' ),
  46.         ) );
  47.  
  48.         register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<status>[\w-]+)', array(
  49.             'args' => array(
  50.                 'status' => array(
  51.                     'description' => __( 'An alphanumeric identifier for the status.' ),
  52.                     'type'        => 'string',
  53.                 ),
  54.             ),
  55.             array(
  56.                 'methods'             => WP_REST_Server::READABLE,
  57.                 'callback'            => array( $this, 'get_item' ),
  58.                 'permission_callback' => array( $this, 'get_item_permissions_check' ),
  59.                 'args'                => array(
  60.                     'context' => $this->get_context_param( array( 'default' => 'view' ) ),
  61.                 ),
  62.             ),
  63.             'schema' => array( $this, 'get_public_item_schema' ),
  64.         ) );
  65.     }
  66.  
  67.     /**
  68.      * Checks whether a given request has permission to read post statuses.
  69.      *
  70.      * @since 4.7.0
  71.      *
  72.      * @param WP_REST_Request $request Full details about the request.
  73.      * @return WP_Error|bool True if the request has read access, WP_Error object otherwise.
  74.      */
  75.     public function get_items_permissions_check( $request ) {
  76.         if ( 'edit' === $request['context'] ) {
  77.             $types = get_post_types( array( 'show_in_rest' => true ), 'objects' );
  78.  
  79.             foreach ( $types as $type ) {
  80.                 if ( current_user_can( $type->cap->edit_posts ) ) {
  81.                     return true;
  82.                 }
  83.             }
  84.             return new WP_Error( 'rest_cannot_view', __( 'Sorry, you are not allowed to edit posts in this post type.' ), array( 'status' => rest_authorization_required_code() ) );
  85.         }
  86.  
  87.         return true;
  88.     }
  89.  
  90.     /**
  91.      * Retrieves all post statuses, depending on user context.
  92.      *
  93.      * @since 4.7.0
  94.      *
  95.      * @param WP_REST_Request $request Full details about the request.
  96.      * @return WP_Error|WP_REST_Response Response object on success, or WP_Error object on failure.
  97.      */
  98.     public function get_items( $request ) {
  99.         $data = array();
  100.         $statuses = get_post_stati( array( 'internal' => false ), 'object' );
  101.         $statuses['trash'] = get_post_status_object( 'trash' );
  102.  
  103.         foreach ( $statuses as $slug => $obj ) {
  104.             $ret = $this->check_read_permission( $obj );
  105.  
  106.             if ( ! $ret ) {
  107.                 continue;
  108.             }
  109.  
  110.             $status = $this->prepare_item_for_response( $obj, $request );
  111.             $data[ $obj->name ] = $this->prepare_response_for_collection( $status );
  112.         }
  113.  
  114.         return rest_ensure_response( $data );
  115.     }
  116.  
  117.     /**
  118.      * Checks if a given request has access to read a post status.
  119.      *
  120.      * @since 4.7.0
  121.      *
  122.      * @param WP_REST_Request $request Full details about the request.
  123.      * @return WP_Error|bool True if the request has read access for the item, WP_Error object otherwise.
  124.      */
  125.     public function get_item_permissions_check( $request ) {
  126.         $status = get_post_status_object( $request['status'] );
  127.  
  128.         if ( empty( $status ) ) {
  129.             return new WP_Error( 'rest_status_invalid', __( 'Invalid status.' ), array( 'status' => 404 ) );
  130.         }
  131.  
  132.         $check = $this->check_read_permission( $status );
  133.  
  134.         if ( ! $check ) {
  135.             return new WP_Error( 'rest_cannot_read_status', __( 'Cannot view status.' ), array( 'status' => rest_authorization_required_code() ) );
  136.         }
  137.  
  138.         return true;
  139.     }
  140.  
  141.     /**
  142.      * Checks whether a given post status should be visible.
  143.      *
  144.      * @since 4.7.0
  145.      *
  146.      * @param object $status Post status.
  147.      * @return bool True if the post status is visible, otherwise false.
  148.      */
  149.     protected function check_read_permission( $status ) {
  150.         if ( true === $status->public ) {
  151.             return true;
  152.         }
  153.  
  154.         if ( false === $status->internal || 'trash' === $status->name ) {
  155.             $types = get_post_types( array( 'show_in_rest' => true ), 'objects' );
  156.  
  157.             foreach ( $types as $type ) {
  158.                 if ( current_user_can( $type->cap->edit_posts ) ) {
  159.                     return true;
  160.                 }
  161.             }
  162.         }
  163.  
  164.         return false;
  165.     }
  166.  
  167.     /**
  168.      * Retrieves a specific post status.
  169.      *
  170.      * @since 4.7.0
  171.      *
  172.      * @param WP_REST_Request $request Full details about the request.
  173.      * @return WP_Error|WP_REST_Response Response object on success, or WP_Error object on failure.
  174.      */
  175.     public function get_item( $request ) {
  176.         $obj = get_post_status_object( $request['status'] );
  177.  
  178.         if ( empty( $obj ) ) {
  179.             return new WP_Error( 'rest_status_invalid', __( 'Invalid status.' ), array( 'status' => 404 ) );
  180.         }
  181.  
  182.         $data = $this->prepare_item_for_response( $obj, $request );
  183.  
  184.         return rest_ensure_response( $data );
  185.     }
  186.  
  187.     /**
  188.      * Prepares a post status object for serialization.
  189.      *
  190.      * @since 4.7.0
  191.      *
  192.      * @param stdClass        $status  Post status data.
  193.      * @param WP_REST_Request $request Full details about the request.
  194.      * @return WP_REST_Response Post status data.
  195.      */
  196.     public function prepare_item_for_response( $status, $request ) {
  197.  
  198.         $data = array(
  199.             'name'         => $status->label,
  200.             'private'      => (bool) $status->private,
  201.             'protected'    => (bool) $status->protected,
  202.             'public'       => (bool) $status->public,
  203.             'queryable'    => (bool) $status->publicly_queryable,
  204.             'show_in_list' => (bool) $status->show_in_admin_all_list,
  205.             'slug'         => $status->name,
  206.         );
  207.  
  208.         $context = ! empty( $request['context'] ) ? $request['context'] : 'view';
  209.         $data = $this->add_additional_fields_to_object( $data, $request );
  210.         $data = $this->filter_response_by_context( $data, $context );
  211.  
  212.         $response = rest_ensure_response( $data );
  213.  
  214.         if ( 'publish' === $status->name ) {
  215.             $response->add_link( 'archives', rest_url( 'wp/v2/posts' ) );
  216.         } else {
  217.             $response->add_link( 'archives', add_query_arg( 'status', $status->name, rest_url( 'wp/v2/posts' ) ) );
  218.         }
  219.  
  220.         /**
  221.          * Filters a status returned from the REST API.
  222.          *
  223.          * Allows modification of the status data right before it is returned.
  224.          *
  225.          * @since 4.7.0
  226.          *
  227.          * @param WP_REST_Response $response The response object.
  228.          * @param object           $status   The original status object.
  229.          * @param WP_REST_Request  $request  Request used to generate the response.
  230.          */
  231.         return apply_filters( 'rest_prepare_status', $response, $status, $request );
  232.     }
  233.  
  234.     /**
  235.      * Retrieves the post status' schema, conforming to JSON Schema.
  236.      *
  237.      * @since 4.7.0
  238.      *
  239.      * @return array Item schema data.
  240.      */
  241.     public function get_item_schema() {
  242.         $schema = array(
  243.             '$schema'              => 'http://json-schema.org/draft-04/schema#',
  244.             'title'                => 'status',
  245.             'type'                 => 'object',
  246.             'properties'           => array(
  247.                 'name'             => array(
  248.                     'description'  => __( 'The title for the status.' ),
  249.                     'type'         => 'string',
  250.                     'context'      => array( 'embed', 'view', 'edit' ),
  251.                     'readonly'     => true,
  252.                 ),
  253.                 'private'          => array(
  254.                     'description'  => __( 'Whether posts with this status should be private.' ),
  255.                     'type'         => 'boolean',
  256.                     'context'      => array( 'edit' ),
  257.                     'readonly'     => true,
  258.                 ),
  259.                 'protected'        => array(
  260.                     'description'  => __( 'Whether posts with this status should be protected.' ),
  261.                     'type'         => 'boolean',
  262.                     'context'      => array( 'edit' ),
  263.                     'readonly'     => true,
  264.                 ),
  265.                 'public'           => array(
  266.                     'description'  => __( 'Whether posts of this status should be shown in the front end of the site.' ),
  267.                     'type'         => 'boolean',
  268.                     'context'      => array( 'view', 'edit' ),
  269.                     'readonly'     => true,
  270.                 ),
  271.                 'queryable'        => array(
  272.                     'description'  => __( 'Whether posts with this status should be publicly-queryable.' ),
  273.                     'type'         => 'boolean',
  274.                     'context'      => array( 'view', 'edit' ),
  275.                     'readonly'     => true,
  276.                 ),
  277.                 'show_in_list'     => array(
  278.                     'description'  => __( 'Whether to include posts in the edit listing for their post type.' ),
  279.                     'type'         => 'boolean',
  280.                     'context'      => array( 'edit' ),
  281.                     'readonly'     => true,
  282.                 ),
  283.                 'slug'             => array(
  284.                     'description'  => __( 'An alphanumeric identifier for the status.' ),
  285.                     'type'         => 'string',
  286.                     'context'      => array( 'embed', 'view', 'edit' ),
  287.                     'readonly'     => true,
  288.                 ),
  289.             ),
  290.         );
  291.  
  292.         return $this->add_additional_fields_schema( $schema );
  293.     }
  294.  
  295.     /**
  296.      * Retrieves the query params for collections.
  297.      *
  298.      * @since 4.7.0
  299.      *
  300.      * @return array Collection parameters.
  301.      */
  302.     public function get_collection_params() {
  303.         return array(
  304.             'context' => $this->get_context_param( array( 'default' => 'view' ) ),
  305.         );
  306.     }
  307.  
  308. }
  309.