PluginProbe
Parse.ly / 3.24.2
Parse.ly v3.24.2
3.24.2 3.24.1 3.24.0 3.23.7 3.23.6 3.23.5 3.23.4 3.23.3 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.17.0 3.18.0 3.18.1 3.19.0 3.19.1 3.19.2 3.19.3 3.2.0 3.2.1 3.20.0 3.20.1 3.20.2 All 106 releases
wp-parsely / src / rest-api / trait-use-post-id-parameter.php

trait-use-post-id-parameter.php in Parse.ly 3.24.2, at src/rest-api/trait-use-post-id-parameter.php

140 lines 3.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Trait allowing to register a REST route with a post ID parameter
4 *
5 * @package Parsely
6 * @since 3.17.0
7 */
8
9 declare( strict_types = 1 );
10
11 namespace Parsely\REST_API;
12
13 use WP_Error;
14 use WP_Post;
15 use WP_REST_Request;
16
17 /**
18 * Trait to register a REST route with a post ID parameter.
19 *
20 * @since 3.17.0
21 */
22 trait Use_Post_ID_Parameter_Trait {
23 /**
24 * Registers a REST route with a post ID parameter in the route.
25 *
26 * @since 3.17.0
27 *
28 * @param string $route The route.
29 * @param array<string> $methods The HTTP methods.
30 * @param callable $callback The callback function.
31 * @param array<mixed> $args The route arguments.
32 */
33 public function register_rest_route_with_post_id(
34 string $route,
35 array $methods,
36 callable $callback,
37 array $args = array()
38 ): void {
39 // Append the post_id parameter to the route.
40 $route = '/(?P<post_id>\d+)/' . trim( $route, '/' );
41
42 // Add the post_id parameter to the args.
43 $args = array_merge(
44 $args,
45 array(
46 'post_id' => array(
47 'description' => __( 'The ID of the post.', 'wp-parsely' ),
48 'type' => 'integer',
49 'required' => true,
50 'validate_callback' => array( $this, 'validate_post_id' ),
51 ),
52 )
53 );
54
55 $this->register_rest_route(
56 $route,
57 $methods,
58 $callback,
59 $args,
60 array( $this, 'can_access_request_post' )
61 );
62 }
63
64 /**
65 * Validates the post ID parameter.
66 *
67 * @since 3.16.0
68 * @since 3.17.0 Moved from the `Smart_Linking_Endpoint` class.
69 * @since 3.24.2 Stopped storing the post object in the request object.
70 * @access private
71 *
72 * @param string $param The parameter value.
73 * @param WP_REST_Request|null $request The request object.
74 * @return bool Whether the parameter is valid.
75 */
76 public function validate_post_id( string $param, ?WP_REST_Request $request = null ): bool { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter
77 if ( ! is_numeric( $param ) ) {
78 return false;
79 }
80
81 $param = filter_var( $param, FILTER_VALIDATE_INT );
82
83 if ( false === $param ) {
84 return false;
85 }
86
87 return null !== get_post( $param );
88 }
89
90 /**
91 * Returns the post that the request's post ID parameter refers to.
92 *
93 * @since 3.24.2
94 *
95 * @param WP_REST_Request $request The request object.
96 * @return WP_Post|null The post object, or null if it doesn't exist.
97 */
98 protected function get_request_post( WP_REST_Request $request ): ?WP_Post {
99 $post_id = (int) $request->get_param( 'post_id' );
100
101 return $post_id > 0 ? get_post( $post_id ) : null;
102 }
103
104 /**
105 * Checks whether the current user can access the post referenced by the
106 * request, on top of the endpoint's own access checks.
107 *
108 * Parse.ly data for a post is available to users who can edit that post,
109 * as the post itself might not be publicly available.
110 *
111 * @since 3.24.2
112 * @access private
113 *
114 * @param WP_REST_Request $request The request object.
115 * @return WP_Error|bool True if the request is allowed.
116 */
117 public function can_access_request_post( WP_REST_Request $request ) {
118 $endpoint_access = $this->is_available_to_current_user( $request );
119
120 if ( true !== $endpoint_access ) {
121 return $endpoint_access;
122 }
123
124 $post_id = (int) $request->get_param( 'post_id' );
125
126 if ( $post_id > 0 && ! current_user_can( 'edit_post', $post_id ) ) {
127 return new WP_Error(
128 'parsely_post_access_denied',
129 __(
130 'Sorry, you are not allowed to access Parse.ly data for this post.',
131 'wp-parsely'
132 ),
133 array( 'status' => rest_authorization_required_code() )
134 );
135 }
136
137 return true;
138 }
139 }
140