PluginProbe ʕ •ᴥ•ʔ
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments / 4.6.1
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments v4.6.1
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 1.0.6 1.1.0 1.1.1 1.1.10 1.1.11 1.1.12 1.1.13 1.1.14 1.1.15 1.1.16 1.1.17 1.1.18 1.1.19 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 1.1.9 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.11.0 1.11.1 1.11.2 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.4.0 1.4.1 1.4.2 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.7.0 1.7.1 1.7.2 1.8.0 1.8.1 1.8.2 1.8.3 1.8.4 1.8.5 1.9.0 1.9.1 1.9.2 1.9.3 1.9.4 1.9.5 2.0.0 2.0.1 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.10.0 2.10.1 2.11.0 2.11.1 2.11.2 2.11.3 2.11.4 2.12.0 2.13.0 2.14.0 2.14.1 2.15.0 2.15.1 2.16.0 2.16.1 2.16.2 2.16.3 2.17.0 2.17.1 2.17.2 2.18.0 2.19.0 2.19.2 2.19.3 2.19.4 2.2.0 2.2.1 2.20.0 2.20.1 2.20.2 2.20.3 2.20.4 2.20.5 2.20.6 2.21.0 2.22.0 2.22.1 2.23.0 2.24.0 2.25.0 2.25.1 2.25.2 2.26.0 2.27.0 2.27.1 2.28.0 2.29.0 2.29.1 2.29.2 2.29.3 2.29.4 2.3.0 2.3.1 2.30.0 2.31.0 2.31.1 2.31.2 2.31.3 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.40.0 2.40.1 2.5.0 2.5.1 2.5.2 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.8.2 2.8.3 2.8.4 2.9.0 3.0.0 3.0.0-RC1 3.0.0-RC2 3.0.0-beta1 3.0.0-beta2 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.10.0 3.10.1 3.11.0 3.12.0 3.13.0 3.13.1 3.13.2 3.13.3 3.13.4 3.14.0 3.15.0 3.15.1 3.15.2 3.15.3 3.15.4 3.15.5 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.16.6 3.16.7 3.16.8 3.17.0 3.17.1 3.17.2 3.17.3 3.17.4 3.17.5 3.17.6 3.18.0 3.19.0 3.19.1 3.19.2 3.2.0 3.2.1 3.2.2 3.20.0 3.20.1 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.4.3 3.5.0 3.5.1 3.5.2 3.5.3 3.6.0 3.6.1 3.6.2 3.7.0 3.7.1 3.7.2 3.7.3 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.9.0 4.0.0 4.0.1 4.0.2 4.0.3 trunk 4.1.0 0.2.19.1 4.1.1 1.0.0 4.2.0 1.0.1 1.0.2
surecart / app / src / Rest / RestServiceProvider.php
surecart / app / src / Rest Last commit date
AbandonedCheckoutProtocolRestServiceProvider.php 3 years ago AbandonedCheckoutRestServiceProvider.php 2 years ago AccountRestServiceProvider.php 4 years ago ActivationRestServiceProvider.php 1 year ago AffiliationProductsRestServiceProvider.php 2 years ago AffiliationProtocolRestServiceProvider.php 2 years ago AffiliationRequestsRestServiceProvider.php 2 years ago AffiliationsRestServiceProvider.php 11 months ago AutoFeeProtocolRestServiceProvider.php 5 months ago AutoFeeRestServiceProvider.php 5 months ago BalanceTransactionRestServiceProvider.php 3 years ago BatchesRestServiceProvider.php 1 week ago BlockPatternsRestServiceProvider.php 4 years ago BrandRestServiceProvider.php 5 days ago BumpRestServiceProvider.php 5 days ago BundleItemsRestServiceProvider.php 5 days ago CancellationActRestServiceProvider.php 1 year ago CancellationReasonRestServiceProvider.php 1 year ago ChargesRestServiceProvider.php 4 years ago CheckEmailRestServiceProvider.php 3 years ago CheckoutRestServiceProvider.php 1 year ago ClicksRestServiceProvider.php 2 years ago CouponRestServiceProvider.php 4 years ago CustomerNotificationProtocolRestServiceProvider.php 4 years ago CustomerPortalProtocolRestServiceProvider.php 1 year ago CustomerRestServiceProvider.php 1 month ago DisplayCurrencyRestServiceProvider.php 1 year ago DisputesRestServiceProvider.php 9 months ago DownloadRestServiceProvider.php 3 months ago DraftCheckoutRestServiceProvider.php 1 year ago ExportsRestServiceProvider.php 2 years ago FulfillmentRestServiceProvider.php 3 years ago ImportRowsRestServiceProvider.php 2 months ago IncomingWebhooksRestServiceProvider.php 2 years ago IntegrationProvidersRestServiceProvider.php 4 years ago IntegrationsCatalogRestServiceProvider.php 1 year ago IntegrationsRestServiceProvider.php 4 years ago InvoicesRestServiceProvider.php 1 year ago LicenseRestServiceProvider.php 1 year ago LineItemsRestServiceProvider.php 1 year ago LoginRestServiceProvider.php 1 month ago ManualPaymentMethodsRestServiceProvider.php 3 years ago MediaRestServiceProvider.php 1 year ago OrderProtocolRestServiceProvider.php 1 year ago OrderRestServiceProvider.php 1 year ago ParcelTemplateRestServiceProvider.php 4 months ago PaymentIntentsRestServiceProvider.php 4 years ago PaymentMethodsRestServiceProvider.php 2 years ago PayoutGroupsRestServiceProvider.php 2 years ago PayoutsRestServiceProvider.php 5 months ago PeriodRestServiceProvider.php 3 years ago PluginInstallerRestServiceProvider.php 1 week ago PriceRestServiceProvider.php 5 days ago ProcessorRestServiceProvider.php 3 years ago ProductCollectionsRestServiceProvider.php 5 days ago ProductGroupsRestServiceProvider.php 5 days ago ProductMediaRestServiceProvider.php 5 days ago ProductsRestServiceProvider.php 5 days ago PromotionRestServiceProvider.php 4 years ago ProvisionalAccountRestServiceProvider.php 3 years ago PurchasesRestServiceProvider.php 4 years ago ReferralItemsRestServiceProvider.php 2 years ago ReferralsRestServiceProvider.php 2 years ago RefundsRestServiceProvider.php 4 years ago RegisteredWebhookRestServiceProvider.php 2 years ago RestServiceInterface.php 4 years ago RestServiceProvider.php 5 days ago ReturnItemsRestServiceProvider.php 2 years ago ReturnReasonsRestServiceProvider.php 2 years ago ReturnRequestsRestServiceProvider.php 2 years ago ReviewProtocolRestServiceProvider.php 5 months ago ReviewsRestServiceProvider.php 1 week ago RuleSchemaRestServiceProvider.php 5 months ago SettingsRestServiceProvider.php 1 year ago ShippingMethodRestServiceProvider.php 3 years ago ShippingProfileRestServiceProvider.php 3 years ago ShippingProtocolRestServiceProvider.php 1 year ago ShippingRateRestServiceProvider.php 3 years ago ShippingZoneRestServiceProvider.php 3 years ago SiteHealthRestServiceProvider.php 2 years ago StatisticRestServiceProvider.php 3 years ago SubscriptionProtocolRestServiceProvider.php 5 months ago SubscriptionRestServiceProvider.php 2 years ago SwapRestServiceProvider.php 1 year ago TaxOverrideRestServiceProvider.php 1 year ago TaxProtocolRestServiceProvider.php 1 year ago TaxRegistrationRestServiceProvider.php 1 year ago TaxZoneRestServiceProvider.php 1 year ago UploadsRestServiceProvider.php 4 years ago UpsellFunnelRestServiceProvider.php 1 year ago UpsellRestServiceProvider.php 5 days ago VariantOptionsRestServiceProvider.php 5 days ago VariantValuesRestServiceProvider.php 5 days ago VariantsRestServiceProvider.php 5 days ago VerificationCodeRestServiceProvider.php 3 years ago WebhooksRestServiceProvider.php 4 years ago
RestServiceProvider.php
401 lines
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 * Whether index responses get each item filtered by schema context.
21 *
22 * Off by default — most providers declared edit-only schema fields long
23 * before lists were ever context-filtered, so enforcing this globally
24 * would silently strip untested view-context list responses. Hardened
25 * catalog endpoints opt in.
26 *
27 * @var boolean
28 */
29 protected $filters_list_items = false;
30
31 /**
32 * Mark specific properties that need additional permissions checks
33 * before modifying. We don't want customers being able to modify these.
34 *
35 * @var array
36 */
37 protected $property_permissions = [];
38
39 /**
40 * Plugin namespace.
41 *
42 * @var string
43 */
44 protected $name = 'surecart';
45
46 /**
47 * API Version
48 *
49 * @var string
50 */
51 protected $version = '1';
52
53 /**
54 * Endpoint.
55 *
56 * @var string
57 */
58 protected $endpoint = '';
59
60 /**
61 * Controller class
62 *
63 * @var string
64 */
65 protected $controller = '';
66
67 /**
68 * Methods allowed for the model.
69 *
70 * @var array
71 */
72 protected $methods = [ 'index', 'create', 'find', 'edit', 'delete' ];
73
74 /**
75 * {@inheritDoc}
76 *
77 * @param \Pimple\Container $container Service Container.
78 */
79 public function register( $container ) {
80 // nothing to register.
81 }
82
83 /**
84 * Bootstrap routes
85 *
86 * @param \Pimple\Container $container Service Container.
87 *
88 * @return void
89 */
90 public function bootstrap( $container ) {
91 add_action( 'rest_api_init', [ $this, 'registerModelRoutes' ] );
92 }
93
94 /**
95 * Do we have the method
96 *
97 * @param string $name
98 * @return boolean
99 */
100 public function hasMethod( $name ) {
101 return in_array( $name, $this->methods, true );
102 }
103
104 /**
105 * Do we have all these methods.
106 *
107 * @param array $methods Array of method names.
108 * @return boolean
109 */
110 public function hasAnyMethods( $methods = [] ) {
111 foreach ( $methods as $method ) {
112 if ( $this->hasMethod( $method ) ) {
113 return true;
114 }
115 }
116 return false;
117 }
118
119 /**
120 * Register REST Routes
121 *
122 * @return void
123 */
124 public function registerModelRoutes() {
125 $this->registerRoutes();
126 if ( $this->hasAnyMethods( [ 'index', 'create' ] ) ) {
127 register_rest_route(
128 "$this->name/v$this->version",
129 "$this->endpoint",
130 array_filter(
131 [
132 ( $this->hasMethod( 'index' ) ? [
133 'methods' => \WP_REST_Server::READABLE,
134 'callback' => $this->callback( $this->controller, 'index' ),
135 'permission_callback' => [ $this, 'get_items_permissions_check' ],
136 'args' => $this->get_collection_params(),
137 ] : [] ),
138 ( $this->hasMethod( 'create' ) ? [
139 'methods' => \WP_REST_Server::CREATABLE,
140 'callback' => $this->callback( $this->controller, 'create' ),
141 'permission_callback' => [ $this, 'create_item_permissions_check' ],
142 ] : [] ),
143 'schema' => [ $this, 'get_item_schema' ],
144 ]
145 )
146 );
147 }
148
149 if ( $this->hasAnyMethods( [ 'find', 'edit', 'delete' ] ) ) {
150 register_rest_route(
151 "$this->name/v$this->version",
152 $this->endpoint . '/(?P<id>[^/]+)',
153 array_filter(
154 [
155 ( $this->hasMethod( 'find' ) ? [
156 'methods' => \WP_REST_Server::READABLE,
157 'callback' => $this->callback( $this->controller, 'find' ),
158 'permission_callback' => [ $this, 'get_item_permissions_check' ],
159 ] : [] ),
160 ( $this->hasMethod( 'edit' ) ? [
161 'methods' => \WP_REST_Server::EDITABLE,
162 'callback' => $this->callback( $this->controller, 'edit' ),
163 'permission_callback' => [ $this, 'update_item_permissions_check' ],
164 ] : [] ),
165 ( $this->hasMethod( 'delete' ) ? [
166 'methods' => \WP_REST_Server::DELETABLE,
167 'callback' => $this->callback( $this->controller, 'delete' ),
168 'permission_callback' => [ $this, 'delete_item_permissions_check' ],
169 ] : [] ),
170 // Register our schema callback.
171 'schema' => [ $this, 'get_item_schema' ],
172 ]
173 )
174 );
175 }
176 }
177
178 /**
179 * Additional routes to register for the model.
180 *
181 * @return void
182 */
183 public function registerRoutes() {
184 }
185
186 /**
187 * Get our sample schema for a post.
188 *
189 * @return array The sample schema for a post
190 */
191 public function get_item_schema() {
192 if ( $this->schema ) {
193 // Since WordPress 5.3, the schema can be cached in the $schema property.
194 return $this->schema;
195 }
196
197 $this->schema = [
198 // This tells the spec of JSON Schema we are using which is draft 4.
199 '$schema' => 'http://json-schema.org/draft-04/schema#',
200 // The title property marks the identity of the resource.
201 'title' => $this->endpoint,
202 'type' => 'object',
203 // In JSON Schema you can specify object properties in the properties attribute.
204 'properties' => [
205 'id' => [
206 'description' => esc_html__( 'Unique identifier for the object.', 'surecart' ),
207 'type' => 'string',
208 'context' => [ 'view', 'edit', 'embed' ],
209 'readonly' => true,
210 ],
211 ],
212 ];
213
214 return $this->schema;
215 }
216
217 /**
218 * Process the callback for the route.
219 *
220 * @param string $class Class name.
221 * @param string $method Class method.
222 * @return callback
223 */
224 public function callback( $class, $method ) {
225 // litespeed caching bypass.
226 do_action( 'litespeed_control_set_nocache', 'surecart api request' );
227
228 return function ( $request ) use ( $class, $method ) {
229 // check and filter context.
230 $context = ! empty( $request['context'] ) ? $request['context'] : 'view';
231
232 // should we convert currency?
233 $converts_currency = $this->converts_currency && 'edit' !== $context;
234
235 // allow override of currency conversion in a per-request basis.
236 if ( isset( $request['currency_conversion'] ) ) {
237 $converts_currency = wp_validate_boolean( $request['currency_conversion'] );
238 }
239
240 // convert currency if needed.
241 \SureCart::currency()->convert( $converts_currency );
242
243 // get and call controller with request.
244 $controller = \SureCart::closure()->method( $class, $method );
245 $model = $controller( apply_filters( "rest_{$this->endpoint}_request", $request, $method ) );
246
247 if ( is_wp_error( $model ) ) {
248 return $model;
249 }
250
251 // index responses wrap a list of models the schema filter can't reach — filter each item.
252 if ( $model instanceof \WP_REST_Response ) {
253 if ( $this->filters_list_items && 'edit' !== $context && is_array( $model->get_data() ) ) {
254 $model->set_data(
255 array_map(
256 function ( $item ) use ( $context ) {
257 if ( ! is_a( $item, Model::class ) ) {
258 return $item;
259 }
260 // remove wp_created_by to prevent user ids from being leaked.
261 if ( ! empty( $item->metadata->wp_created_by ) ) {
262 unset( $item->metadata->wp_created_by );
263 }
264 return $this->filter_response_by_context( $item->toArray(), $context );
265 },
266 $model->get_data()
267 )
268 );
269 }
270 return $model;
271 }
272
273 // remove wp_created_by to prevent user ids from being leaked.
274 if ( 'edit' !== $context && ! empty( $model->metadata->wp_created_by ) ) {
275 unset( $model->metadata->wp_created_by );
276 }
277
278 $response = rest_ensure_response( $this->filter_response_by_context( is_a( $model, Model::class ) ? $model->toArray() : $model, $context ) );
279
280 if ( is_a( $model, Model::class ) && ! empty( $model->getCacheStatus() ) ) {
281 $response->header( 'X-SURECART-CACHE-STATUS', $model->getCacheStatus() );
282 }
283
284 return $response;
285 };
286 }
287
288 /**
289 * Check permissions for specific properties of the request.
290 *
291 * @param \WP_REST_Request $request Full details about the request.
292 * @param array $keys Keys to check.
293 *
294 * @return boolean
295 */
296 protected function requestOnlyHasKeys( $request, $keys ) {
297 $keys = array_merge( $keys, [ 'context', '_locale', 'rest_route', 'id', 'expand' ] );
298 foreach ( $request->get_params() as $key => $value ) {
299 if ( ! in_array( $key, $keys, true ) ) {
300 return false;
301 }
302 }
303 return true;
304 }
305
306 /**
307 * Reject edit-context reads from callers without the capability.
308 *
309 * @param \WP_REST_Request $request Full details about the request.
310 * @param string|array $capability Capability that unlocks edit context. Any one of an array is enough.
311 *
312 * @return true|\WP_Error
313 */
314 protected function forbidEditContextWithout( $request, $capability ) {
315 if ( 'edit' !== $request['context'] ) {
316 return true;
317 }
318
319 foreach ( (array) $capability as $cap ) {
320 if ( current_user_can( $cap ) ) {
321 return true;
322 }
323 }
324
325 return new \WP_Error(
326 'rest_forbidden_context',
327 __( 'Sorry, you are not allowed to edit this resource.', 'surecart' ),
328 [ 'status' => rest_authorization_required_code() ]
329 );
330 }
331
332 /**
333 * Retrieves the query params for collections.
334 *
335 * @return array
336 */
337 public function get_collection_params() {
338 return [];
339 }
340
341 /**
342 * Set these all as false by default
343 * in case parent class doesn't implement them.
344 *
345 * @param \WP_REST_Request $request Full details about the request.
346 *
347 * @return false
348 */
349 public function get_item_permissions_check( $request ) {
350 return false;
351 }
352
353 /**
354 * Set these all as false by default
355 * in case parent class doesn't implement them.
356 *
357 * @param \WP_REST_Request $request Full details about the request.
358 *
359 * @return false
360 */
361 public function get_items_permissions_check( $request ) {
362 return false;
363 }
364
365 /**
366 * Set these all as false by default
367 * in case parent class doesn't implement them.
368 *
369 * @param \WP_REST_Request $request Full details about the request.
370 *
371 * @return false
372 */
373 public function create_item_permissions_check( $request ) {
374 return false;
375 }
376
377 /**
378 * Set these all as false by default
379 * in case parent class doesn't implement them.
380 *
381 * @param \WP_REST_Request $request Full details about the request.
382 *
383 * @return false
384 */
385 public function update_item_permissions_check( $request ) {
386 return false;
387 }
388
389 /**
390 * Set these all as false by default
391 * in case parent class doesn't implement them.
392 *
393 * @param \WP_REST_Request $request Full details about the request.
394 *
395 * @return false
396 */
397 public function delete_item_permissions_check( $request ) {
398 return false;
399 }
400 }
401