PluginProbe ʕ •ᴥ•ʔ
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments / 4.5.0
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments v4.5.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 / BatchesRestServiceProvider.php
surecart / app / src / Rest Last commit date
AbandonedCheckoutProtocolRestServiceProvider.php 3 years ago AbandonedCheckoutRestServiceProvider.php 2 years ago AccountRestServiceProvider.php 3 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 4 days ago BlockPatternsRestServiceProvider.php 3 years ago BrandRestServiceProvider.php 4 months ago BumpRestServiceProvider.php 1 year ago CancellationActRestServiceProvider.php 1 year ago CancellationReasonRestServiceProvider.php 1 year ago ChargesRestServiceProvider.php 3 years ago CheckEmailRestServiceProvider.php 3 years ago CheckoutRestServiceProvider.php 1 year ago ClicksRestServiceProvider.php 2 years ago CouponRestServiceProvider.php 3 years ago CustomerNotificationProtocolRestServiceProvider.php 3 years ago CustomerPortalProtocolRestServiceProvider.php 1 year ago CustomerRestServiceProvider.php 1 month ago DisplayCurrencyRestServiceProvider.php 1 year ago DisputesRestServiceProvider.php 9 months ago DownloadRestServiceProvider.php 2 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 3 years ago IntegrationsCatalogRestServiceProvider.php 1 year ago IntegrationsRestServiceProvider.php 3 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 3 months ago PaymentIntentsRestServiceProvider.php 3 years ago PaymentMethodsRestServiceProvider.php 2 years ago PayoutGroupsRestServiceProvider.php 2 years ago PayoutsRestServiceProvider.php 4 months ago PeriodRestServiceProvider.php 3 years ago PluginInstallerRestServiceProvider.php 4 days ago PriceRestServiceProvider.php 1 year ago ProcessorRestServiceProvider.php 3 years ago ProductCollectionsRestServiceProvider.php 4 days ago ProductGroupsRestServiceProvider.php 3 years ago ProductMediaRestServiceProvider.php 1 year ago ProductsRestServiceProvider.php 4 days ago PromotionRestServiceProvider.php 3 years ago ProvisionalAccountRestServiceProvider.php 3 years ago PurchasesRestServiceProvider.php 3 years ago ReferralItemsRestServiceProvider.php 2 years ago ReferralsRestServiceProvider.php 2 years ago RefundsRestServiceProvider.php 3 years ago RegisteredWebhookRestServiceProvider.php 2 years ago RestServiceInterface.php 3 years ago RestServiceProvider.php 1 year ago ReturnItemsRestServiceProvider.php 2 years ago ReturnReasonsRestServiceProvider.php 2 years ago ReturnRequestsRestServiceProvider.php 2 years ago ReviewProtocolRestServiceProvider.php 4 months ago ReviewsRestServiceProvider.php 4 days 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 3 years ago UpsellFunnelRestServiceProvider.php 1 year ago UpsellRestServiceProvider.php 1 year ago VariantOptionsRestServiceProvider.php 2 years ago VariantValuesRestServiceProvider.php 2 years ago VariantsRestServiceProvider.php 2 years ago VerificationCodeRestServiceProvider.php 3 years ago WebhooksRestServiceProvider.php 3 years ago
BatchesRestServiceProvider.php
226 lines
1 <?php
2
3 namespace SureCart\Rest;
4
5 use SureCart\Rest\RestServiceInterface;
6 use SureCart\Controllers\Rest\BatchesController;
7
8 /**
9 * Batches REST service provider.
10 */
11 class BatchesRestServiceProvider extends RestServiceProvider implements RestServiceInterface {
12 /**
13 * Endpoint.
14 *
15 * @var string
16 */
17 protected $endpoint = 'batches';
18
19 /**
20 * Rest Controller.
21 *
22 * @var string
23 */
24 protected $controller = BatchesController::class;
25
26 /**
27 * Batches are append-only — submit, then poll for status.
28 *
29 * @var array
30 */
31 protected $methods = [ 'index', 'create', 'find' ];
32
33 /**
34 * Schema callback.
35 *
36 * @return array
37 */
38 public function get_item_schema() {
39 if ( $this->schema ) {
40 return $this->schema;
41 }
42
43 $this->schema = [
44 '$schema' => 'http://json-schema.org/draft-04/schema#',
45 'title' => $this->endpoint,
46 'type' => 'object',
47 'properties' => [
48 'id' => [
49 'description' => __( 'UUID of the batch.', 'surecart' ),
50 'type' => 'string',
51 'context' => [ 'view', 'edit', 'embed' ],
52 'readonly' => true,
53 ],
54 'status' => [
55 'description' => __( 'pending | in_progress | completed', 'surecart' ),
56 'type' => 'string',
57 'readonly' => true,
58 ],
59 'batch_operations_count' => [
60 'description' => __( 'Total operations in this batch.', 'surecart' ),
61 'type' => 'integer',
62 'readonly' => true,
63 ],
64 'finished_batch_operations_count' => [
65 'description' => __( 'Operations that have finished (completed, failed, or timed out).', 'surecart' ),
66 'type' => 'integer',
67 'readonly' => true,
68 ],
69 'batch_operations' => [
70 'description' => __( 'Operations to execute as part of this batch.', 'surecart' ),
71 'type' => 'array',
72 'items' => [
73 'type' => 'object',
74 'properties' => [
75 'http_method' => [ 'type' => 'string' ],
76 'path' => [ 'type' => 'string' ],
77 'body' => [ 'type' => 'object' ],
78 ],
79 ],
80 ],
81 ],
82 ];
83
84 return $this->schema;
85 }
86
87 /**
88 * Collection params.
89 *
90 * @return array
91 */
92 public function get_collection_params() {
93 return [
94 'page' => [
95 'description' => __( 'Page of items returned.', 'surecart' ),
96 'type' => 'integer',
97 ],
98 'per_page' => [
99 'description' => __( 'Items per page (1-100).', 'surecart' ),
100 'type' => 'integer',
101 ],
102 ];
103 }
104
105 /**
106 * Resource segment → capability suffix. New resources must be listed here
107 * before they can be batched; unknown paths are rejected.
108 *
109 * @var array<string, string>
110 */
111 private const RESOURCE_CAP_SUFFIX = [
112 'products' => 'sc_products',
113 'product_collections' => 'sc_products',
114 'product_groups' => 'sc_products',
115 'prices' => 'sc_prices',
116 'reviews' => 'sc_reviews',
117 'orders' => 'sc_orders',
118 'customers' => 'sc_customers',
119 'subscriptions' => 'sc_subscriptions',
120 'invoices' => 'sc_invoices',
121 'coupons' => 'sc_coupons',
122 'promotions' => 'sc_promotions',
123 'affiliations' => 'sc_affiliates',
124 'licenses' => 'sc_licenses',
125 'webhooks' => 'sc_webhooks',
126 'medias' => 'sc_medias',
127 ];
128
129 public function get_items_permissions_check( $request ) {
130 return $this->userCanUseBatches();
131 }
132
133 public function get_item_permissions_check( $request ) {
134 return $this->userCanUseBatches();
135 }
136
137 /**
138 * Validates every operation against the cap the caller would have needed
139 * to perform it directly — otherwise a user with `edit_sc_products` could
140 * smuggle `DELETE /v1/customers/{id}` through the batch proxy.
141 */
142 public function create_item_permissions_check( $request ) {
143 if ( ! $this->userCanUseBatches() ) {
144 return new \WP_Error(
145 'rest_forbidden',
146 __( 'You are not allowed to use the batch endpoint.', 'surecart' ),
147 [ 'status' => 403 ]
148 );
149 }
150
151 $operations = $request->get_param( 'batch_operations' );
152 if ( empty( $operations ) || ! is_array( $operations ) ) {
153 return new \WP_Error(
154 'rest_invalid_param',
155 __( 'A batch must contain at least one operation.', 'surecart' ),
156 [ 'status' => 400 ]
157 );
158 }
159
160 foreach ( $operations as $op ) {
161 $cap = $this->requiredCapabilityFor(
162 $op['http_method'] ?? '',
163 $op['path'] ?? ''
164 );
165 if ( ! $cap ) {
166 return new \WP_Error(
167 'rest_forbidden',
168 __( 'Unsupported operation in batch.', 'surecart' ),
169 [ 'status' => 403 ]
170 );
171 }
172 if ( ! current_user_can( $cap ) ) {
173 return new \WP_Error(
174 'rest_forbidden',
175 __( 'You are not allowed to perform one or more operations in this batch.', 'surecart' ),
176 [ 'status' => 403 ]
177 );
178 }
179 }
180
181 return true;
182 }
183
184 /**
185 * Coarse gate for read-side endpoints; create_item enforces per-op auth.
186 *
187 * @return bool
188 */
189 private function userCanUseBatches(): bool {
190 foreach ( self::RESOURCE_CAP_SUFFIX as $suffix ) {
191 if ( current_user_can( 'edit_' . $suffix ) ) {
192 return true;
193 }
194 }
195 return false;
196 }
197
198 /**
199 * Returns null for unknown paths — callers treat null as deny.
200 *
201 * @param string $http_method GET, POST, PATCH, PUT, DELETE.
202 * @param string $path e.g. `/v1/products/abc`.
203 * @return string|null
204 */
205 private function requiredCapabilityFor( string $http_method, string $path ): ?string {
206 if ( ! preg_match( '#^/v1/([a-z_]+)#i', $path, $matches ) ) {
207 return null;
208 }
209 $resource = strtolower( $matches[1] );
210 $suffix = self::RESOURCE_CAP_SUFFIX[ $resource ] ?? null;
211 if ( ! $suffix ) {
212 return null;
213 }
214
215 $verb = strtoupper( $http_method );
216 if ( 'GET' === $verb ) {
217 return 'read_' . $suffix;
218 }
219 if ( 'DELETE' === $verb ) {
220 return 'delete_' . $suffix;
221 }
222
223 return 'edit_' . $suffix;
224 }
225 }
226