Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.
 
 
 
 
 

319 righe
9.1 KiB

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