PluginProbe
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments / 3.11.0
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments v3.11.0
4.7.2 4.7.1 4.7.0 4.6.6 4.6.5 4.6.4 4.6.3 4.6.2 4.6.1 4.6.0 4.5.1 4.5.0 4.4.2 4.4.1 4.4.0 4.3.3 4.3.2 4.3.1 4.3.0 4.2.3 4.2.2 4.2.1 1.0.3 1.0.4 1.0.5 All 281 releases
surecart / app / src / Rest / RestServiceProvider.php
RestServiceProvider.php
341 lines 8.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace SureCart\Rest;
4
5 use SureCart\Models\Model;
6 use SureCart\Rest\RestServiceInterface;
7
8 /**
9 * Abstract Rest Service Provider interface
10 */
11 abstract class RestServiceProvider extends \WP_REST_Controller implements RestServiceInterface {
12 /**
13 * Whether the rest service provider converts currency.
14 *
15 * @var boolean
16 */
17 protected $converts_currency = false;
18
19 /**
20 * Mark specific properties that need additional permissions checks
21 * before modifying. We don't want customers being able to modify these.
22 *
23 * @var array
24 */
25 protected $property_permissions = [];
26
27 /**
28 * Plugin namespace.
29 *
30 * @var string
31 */
32 protected $name = 'surecart';
33
34 /**
35 * API Version
36 *
37 * @var string
38 */
39 protected $version = '1';
40
41 /**
42 * Endpoint.
43 *
44 * @var string
45 */
46 protected $endpoint = '';
47
48 /**
49 * Controller class
50 *
51 * @var string
52 */
53 protected $controller = '';
54
55 /**
56 * Methods allowed for the model.
57 *
58 * @var array
59 */
60 protected $methods = [ 'index', 'create', 'find', 'edit', 'delete' ];
61
62 /**
63 * {@inheritDoc}
64 *
65 * @param \Pimple\Container $container Service Container.
66 */
67 public function register( $container ) {
68 // nothing to register.
69 }
70
71 /**
72 * Bootstrap routes
73 *
74 * @param \Pimple\Container $container Service Container.
75 *
76 * @return void
77 */
78 public function bootstrap( $container ) {
79 add_action( 'rest_api_init', [ $this, 'registerModelRoutes' ] );
80 }
81
82 /**
83 * Do we have the method
84 *
85 * @param string $name
86 * @return boolean
87 */
88 public function hasMethod( $name ) {
89 return in_array( $name, $this->methods, true );
90 }
91
92 /**
93 * Do we have all these methods.
94 *
95 * @param array $methods Array of method names.
96 * @return boolean
97 */
98 public function hasAnyMethods( $methods = [] ) {
99 foreach ( $methods as $method ) {
100 if ( $this->hasMethod( $method ) ) {
101 return true;
102 }
103 }
104 return false;
105 }
106
107 /**
108 * Register REST Routes
109 *
110 * @return void
111 */
112 public function registerModelRoutes() {
113 $this->registerRoutes();
114 if ( $this->hasAnyMethods( [ 'index', 'create' ] ) ) {
115 register_rest_route(
116 "$this->name/v$this->version",
117 "$this->endpoint",
118 array_filter(
119 [
120 ( $this->hasMethod( 'index' ) ? [
121 'methods' => \WP_REST_Server::READABLE,
122 'callback' => $this->callback( $this->controller, 'index' ),
123 'permission_callback' => [ $this, 'get_items_permissions_check' ],
124 'args' => $this->get_collection_params(),
125 ] : [] ),
126 ( $this->hasMethod( 'create' ) ? [
127 'methods' => \WP_REST_Server::CREATABLE,
128 'callback' => $this->callback( $this->controller, 'create' ),
129 'permission_callback' => [ $this, 'create_item_permissions_check' ],
130 ] : [] ),
131 'schema' => [ $this, 'get_item_schema' ],
132 ]
133 )
134 );
135 }
136
137 if ( $this->hasAnyMethods( [ 'find', 'edit', 'delete' ] ) ) {
138 register_rest_route(
139 "$this->name/v$this->version",
140 $this->endpoint . '/(?P<id>[^/]+)',
141 array_filter(
142 [
143 ( $this->hasMethod( 'find' ) ? [
144 'methods' => \WP_REST_Server::READABLE,
145 'callback' => $this->callback( $this->controller, 'find' ),
146 'permission_callback' => [ $this, 'get_item_permissions_check' ],
147 ] : [] ),
148 ( $this->hasMethod( 'edit' ) ? [
149 'methods' => \WP_REST_Server::EDITABLE,
150 'callback' => $this->callback( $this->controller, 'edit' ),
151 'permission_callback' => [ $this, 'update_item_permissions_check' ],
152 ] : [] ),
153 ( $this->hasMethod( 'delete' ) ? [
154 'methods' => \WP_REST_Server::DELETABLE,
155 'callback' => $this->callback( $this->controller, 'delete' ),
156 'permission_callback' => [ $this, 'delete_item_permissions_check' ],
157 ] : [] ),
158 // Register our schema callback.
159 'schema' => [ $this, 'get_item_schema' ],
160 ]
161 )
162 );
163 }
164 }
165
166 /**
167 * Additional routes to register for the model.
168 *
169 * @return void
170 */
171 public function registerRoutes() {
172 }
173
174 /**
175 * Get our sample schema for a post.
176 *
177 * @return array The sample schema for a post
178 */
179 public function get_item_schema() {
180 if ( $this->schema ) {
181 // Since WordPress 5.3, the schema can be cached in the $schema property.
182 return $this->schema;
183 }
184
185 $this->schema = [
186 // This tells the spec of JSON Schema we are using which is draft 4.
187 '$schema' => 'http://json-schema.org/draft-04/schema#',
188 // The title property marks the identity of the resource.
189 'title' => $this->endpoint,
190 'type' => 'object',
191 // In JSON Schema you can specify object properties in the properties attribute.
192 'properties' => [
193 'id' => [
194 'description' => esc_html__( 'Unique identifier for the object.', 'surecart' ),
195 'type' => 'string',
196 'context' => [ 'view', 'edit', 'embed' ],
197 'readonly' => true,
198 ],
199 ],
200 ];
201
202 return $this->schema;
203 }
204
205 /**
206 * Process the callback for the route.
207 *
208 * @param string $class Class name.
209 * @param string $method Class method.
210 * @return callback
211 */
212 public function callback( $class, $method ) {
213 // litespeed caching bypass.
214 do_action( 'litespeed_control_set_nocache', 'surecart api request' );
215
216 return function ( $request ) use ( $class, $method ) {
217 // check and filter context.
218 $context = ! empty( $request['context'] ) ? $request['context'] : 'view';
219
220 // should we convert currency?
221 $converts_currency = $this->converts_currency && 'edit' !== $context;
222
223 // allow override of currency conversion in a per-request basis.
224 if ( isset( $request['currency_conversion'] ) ) {
225 $converts_currency = wp_validate_boolean( $request['currency_conversion'] );
226 }
227
228 // convert currency if needed.
229 \SureCart::currency()->convert( $converts_currency );
230
231 // get and call controller with request.
232 $controller = \SureCart::closure()->method( $class, $method );
233 $model = $controller( apply_filters( "rest_{$this->endpoint}_request", $request, $method ) );
234
235 if ( is_wp_error( $model ) ) {
236 return $model;
237 }
238
239 // remove wp_created_by to prevent user ids from being leaked.
240 if ( 'edit' !== $context && ! empty( $model->metadata->wp_created_by ) ) {
241 unset( $model->metadata->wp_created_by );
242 }
243
244 $response = rest_ensure_response( $this->filter_response_by_context( is_a( $model, Model::class ) ? $model->toArray() : $model, $context ) );
245
246 if ( is_a( $model, Model::class ) && ! empty( $model->getCacheStatus() ) ) {
247 $response->header( 'X-SURECART-CACHE-STATUS', $model->getCacheStatus() );
248 }
249
250 return $response;
251 };
252 }
253
254 /**
255 * Check permissions for specific properties of the request.
256 *
257 * @param \WP_REST_Request $request Full details about the request.
258 * @param array $keys Keys to check.
259 *
260 * @return boolean
261 */
262 protected function requestOnlyHasKeys( $request, $keys ) {
263 $keys = array_merge( $keys, [ 'context', '_locale', 'rest_route', 'id', 'expand' ] );
264 foreach ( $request->get_params() as $key => $value ) {
265 if ( ! in_array( $key, $keys, true ) ) {
266 return false;
267 }
268 }
269 return true;
270 }
271
272 /**
273 * Retrieves the query params for collections.
274 *
275 * @return array
276 */
277 public function get_collection_params() {
278 return [];
279 }
280
281 /**
282 * Set these all as false by default
283 * in case parent class doesn't implement them.
284 *
285 * @param \WP_REST_Request $request Full details about the request.
286 *
287 * @return false
288 */
289 public function get_item_permissions_check( $request ) {
290 return false;
291 }
292
293 /**
294 * Set these all as false by default
295 * in case parent class doesn't implement them.
296 *
297 * @param \WP_REST_Request $request Full details about the request.
298 *
299 * @return false
300 */
301 public function get_items_permissions_check( $request ) {
302 return false;
303 }
304
305 /**
306 * Set these all as false by default
307 * in case parent class doesn't implement them.
308 *
309 * @param \WP_REST_Request $request Full details about the request.
310 *
311 * @return false
312 */
313 public function create_item_permissions_check( $request ) {
314 return false;
315 }
316
317 /**
318 * Set these all as false by default
319 * in case parent class doesn't implement them.
320 *
321 * @param \WP_REST_Request $request Full details about the request.
322 *
323 * @return false
324 */
325 public function update_item_permissions_check( $request ) {
326 return false;
327 }
328
329 /**
330 * Set these all as false by default
331 * in case parent class doesn't implement them.
332 *
333 * @param \WP_REST_Request $request Full details about the request.
334 *
335 * @return false
336 */
337 public function delete_item_permissions_check( $request ) {
338 return false;
339 }
340 }
341