|
1
|
|
|
<?php |
|
2
|
|
|
/** |
|
3
|
|
|
* REST API Discounts controller |
|
4
|
|
|
* |
|
5
|
|
|
* Handles requests to the invoices endpoint. |
|
6
|
|
|
* |
|
7
|
|
|
* @package Invoicing |
|
8
|
|
|
* @since 1.0.13 |
|
9
|
|
|
*/ |
|
10
|
|
|
|
|
11
|
|
|
if ( !defined( 'WPINC' ) ) { |
|
12
|
|
|
exit; |
|
13
|
|
|
} |
|
14
|
|
|
|
|
15
|
|
|
/** |
|
16
|
|
|
* REST API discounts controller class. |
|
17
|
|
|
* |
|
18
|
|
|
* @package Invoicing |
|
19
|
|
|
*/ |
|
20
|
|
|
class WPInv_REST_Discounts_Controller extends WP_REST_Posts_Controller { |
|
21
|
|
|
|
|
22
|
|
|
/** |
|
23
|
|
|
* Post type. |
|
24
|
|
|
* |
|
25
|
|
|
* @var string |
|
26
|
|
|
*/ |
|
27
|
|
|
protected $post_type = 'wpi_discount'; |
|
28
|
|
|
|
|
29
|
|
|
/** |
|
30
|
|
|
* Cached results of get_item_schema. |
|
31
|
|
|
* |
|
32
|
|
|
* @since 1.0.13 |
|
33
|
|
|
* @var array |
|
34
|
|
|
*/ |
|
35
|
|
|
protected $schema; |
|
36
|
|
|
|
|
37
|
|
|
/** |
|
38
|
|
|
* Constructor. |
|
39
|
|
|
* |
|
40
|
|
|
* @since 1.0.13 |
|
41
|
|
|
* |
|
42
|
|
|
* @param string $namespace Api Namespace |
|
43
|
|
|
*/ |
|
44
|
|
|
public function __construct( $namespace ) { |
|
45
|
|
|
|
|
46
|
|
|
// Set api namespace... |
|
47
|
|
|
$this->namespace = $namespace; |
|
48
|
|
|
|
|
49
|
|
|
// ... and the rest base |
|
50
|
|
|
$this->rest_base = 'discounts'; |
|
51
|
|
|
|
|
52
|
|
|
} |
|
53
|
|
|
|
|
54
|
|
|
/** |
|
55
|
|
|
* Registers the routes for the objects of the controller. |
|
56
|
|
|
* |
|
57
|
|
|
* @since 1.0.13 |
|
58
|
|
|
* |
|
59
|
|
|
* @see register_rest_route() |
|
60
|
|
|
*/ |
|
61
|
|
|
public function register_routes() { |
|
62
|
|
|
|
|
63
|
|
|
parent::register_routes(); |
|
64
|
|
|
|
|
65
|
|
|
register_rest_route( |
|
66
|
|
|
$this->namespace, |
|
67
|
|
|
'/' . $this->rest_base . '/discount-types', |
|
68
|
|
|
array( |
|
69
|
|
|
array( |
|
70
|
|
|
'methods' => WP_REST_Server::READABLE, |
|
71
|
|
|
'callback' => array( $this, 'get_discount_types' ), |
|
72
|
|
|
), |
|
73
|
|
|
) |
|
74
|
|
|
); |
|
75
|
|
|
|
|
76
|
|
|
} |
|
77
|
|
|
|
|
78
|
|
|
/** |
|
79
|
|
|
* Checks if a given request has access to read discounts. |
|
80
|
|
|
* |
|
81
|
|
|
* |
|
82
|
|
|
* @since 1.0.13 |
|
83
|
|
|
* |
|
84
|
|
|
* @param WP_REST_Request $request Full details about the request. |
|
85
|
|
|
* @return true|WP_Error True if the request has read access, WP_Error object otherwise. |
|
86
|
|
|
*/ |
|
87
|
|
|
public function get_items_permissions_check( $request ) { |
|
88
|
|
|
|
|
89
|
|
|
if ( wpinv_current_user_can_manage_invoicing() ) { |
|
90
|
|
|
return true; |
|
91
|
|
|
} |
|
92
|
|
|
|
|
93
|
|
|
return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to view invoice discounts.', 'invoicing' ), array( 'status' => rest_authorization_required_code() ) ); |
|
94
|
|
|
|
|
95
|
|
|
} |
|
96
|
|
|
|
|
97
|
|
|
/** |
|
98
|
|
|
* Retrieves a collection of discounts. |
|
99
|
|
|
* |
|
100
|
|
|
* @since 1.0.13 |
|
101
|
|
|
* |
|
102
|
|
|
* @param WP_REST_Request $request Full details about the request. |
|
103
|
|
|
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. |
|
104
|
|
|
*/ |
|
105
|
|
|
public function get_items( $request ) { |
|
106
|
|
|
|
|
107
|
|
|
// Retrieve the list of registered item query parameters. |
|
108
|
|
|
$registered = $this->get_collection_params(); |
|
109
|
|
|
|
|
110
|
|
|
$args = array(); |
|
111
|
|
|
|
|
112
|
|
|
foreach( array_keys( $registered ) as $key ) { |
|
113
|
|
|
|
|
114
|
|
|
if( isset( $request[ $key] ) ) { |
|
115
|
|
|
$args[ $key ] = $request[ $key]; |
|
116
|
|
|
} |
|
117
|
|
|
|
|
118
|
|
|
} |
|
119
|
|
|
|
|
120
|
|
|
/** |
|
121
|
|
|
* Filters the wpinv_get_all_discounts arguments for discounts rest requests. |
|
122
|
|
|
* |
|
123
|
|
|
* |
|
124
|
|
|
* @since 1.0.13 |
|
125
|
|
|
* |
|
126
|
|
|
* |
|
127
|
|
|
* @param array $args Key value array of query var to query value. |
|
128
|
|
|
* @param WP_REST_Request $request The request used. |
|
129
|
|
|
*/ |
|
130
|
|
|
$args = apply_filters( "wpinv_rest_get_discounts_arguments", $args, $request, $this ); |
|
131
|
|
|
|
|
132
|
|
|
// Special args |
|
133
|
|
|
$args[ 'return' ] = 'objects'; |
|
134
|
|
|
$args[ 'paginate' ] = true; |
|
135
|
|
|
|
|
136
|
|
|
// Run the query. |
|
137
|
|
|
$query = wpinv_get_all_discounts( $args ); |
|
138
|
|
|
|
|
139
|
|
|
// Prepare the retrieved discounts |
|
140
|
|
|
$discounts = array(); |
|
141
|
|
|
foreach( $query->discounts as $discount ) { |
|
142
|
|
|
|
|
143
|
|
|
$data = $this->prepare_item_for_response( $discount, $request ); |
|
144
|
|
|
$discounts[] = $this->prepare_response_for_collection( $data ); |
|
145
|
|
|
|
|
146
|
|
|
} |
|
147
|
|
|
|
|
148
|
|
|
// Prepare the response. |
|
149
|
|
|
$response = rest_ensure_response( $discounts ); |
|
150
|
|
|
$response->header( 'X-WP-Total', (int) $query->total ); |
|
151
|
|
|
$response->header( 'X-WP-TotalPages', (int) $query->max_num_pages ); |
|
152
|
|
|
|
|
153
|
|
|
/** |
|
154
|
|
|
* Filters the responses for discount requests. |
|
155
|
|
|
* |
|
156
|
|
|
* |
|
157
|
|
|
* @since 1.0.13 |
|
158
|
|
|
* |
|
159
|
|
|
* |
|
160
|
|
|
* @param arrWP_REST_Response $response Response object. |
|
161
|
|
|
* @param WP_REST_Request $request The request used. |
|
162
|
|
|
* @param array $args Array of args used to retrieve the discounts |
|
163
|
|
|
*/ |
|
164
|
|
|
$response = apply_filters( "wpinv_rest_discounts_response", $response, $request, $args ); |
|
165
|
|
|
|
|
166
|
|
|
return rest_ensure_response( $response ); |
|
167
|
|
|
|
|
168
|
|
|
} |
|
169
|
|
|
|
|
170
|
|
|
/** |
|
171
|
|
|
* Get the post, if the ID is valid. |
|
172
|
|
|
* |
|
173
|
|
|
* @since 1.0.13 |
|
174
|
|
|
* |
|
175
|
|
|
* @param int $discount_id Supplied ID. |
|
176
|
|
|
* @return WP_Post|WP_Error Post object if ID is valid, WP_Error otherwise. |
|
177
|
|
|
*/ |
|
178
|
|
|
protected function get_post( $discount_id ) { |
|
179
|
|
|
|
|
180
|
|
|
$error = new WP_Error( 'rest_item_invalid_id', __( 'Invalid discount ID.', 'invoicing' ), array( 'status' => 404 ) ); |
|
181
|
|
|
|
|
182
|
|
|
// Ids start from 1 |
|
183
|
|
|
if ( (int) $discount_id <= 0 ) { |
|
184
|
|
|
return $error; |
|
185
|
|
|
} |
|
186
|
|
|
|
|
187
|
|
|
$discount = wpinv_get_discount( (int) $discount_id ); |
|
188
|
|
|
if ( empty( $discount ) ) { |
|
189
|
|
|
return $error; |
|
190
|
|
|
} |
|
191
|
|
|
|
|
192
|
|
|
return $discount; |
|
193
|
|
|
|
|
194
|
|
|
} |
|
195
|
|
|
|
|
196
|
|
|
/** |
|
197
|
|
|
* Checks if a given request has access to read a discount. |
|
198
|
|
|
* |
|
199
|
|
|
* @since 1.0.13 |
|
200
|
|
|
* |
|
201
|
|
|
* @param WP_REST_Request $request Full details about the request. |
|
202
|
|
|
* @return bool|WP_Error True if the request has read access for the invoice item, WP_Error object otherwise. |
|
203
|
|
|
*/ |
|
204
|
|
|
public function get_item_permissions_check( $request ) { |
|
205
|
|
|
|
|
206
|
|
|
// Retrieve the discount object. |
|
207
|
|
|
$discount = $this->get_post( $request['id'] ); |
|
208
|
|
|
|
|
209
|
|
|
// Ensure it is valid. |
|
210
|
|
|
if ( is_wp_error( $discount ) ) { |
|
211
|
|
|
return $discount; |
|
|
|
|
|
|
212
|
|
|
} |
|
213
|
|
|
|
|
214
|
|
|
if ( ! wpinv_current_user_can_manage_invoicing() ) { |
|
215
|
|
|
return new WP_Error( |
|
216
|
|
|
'rest_cannot_view', |
|
217
|
|
|
__( 'Sorry, you are not allowed to view this discount.', 'invoicing' ), |
|
218
|
|
|
array( |
|
219
|
|
|
'status' => rest_authorization_required_code(), |
|
220
|
|
|
) |
|
221
|
|
|
); |
|
222
|
|
|
} |
|
223
|
|
|
|
|
224
|
|
|
return true; |
|
225
|
|
|
} |
|
226
|
|
|
|
|
227
|
|
|
/** |
|
228
|
|
|
* Retrieves a single invoice item. |
|
229
|
|
|
* |
|
230
|
|
|
* @since 1.0.13 |
|
231
|
|
|
* |
|
232
|
|
|
* @param WP_REST_Request $request Full details about the request. |
|
233
|
|
|
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. |
|
234
|
|
|
*/ |
|
235
|
|
|
public function get_item( $request ) { |
|
236
|
|
|
|
|
237
|
|
|
// Fetch the discount. |
|
238
|
|
|
$discount = $this->get_post( $request['id'] ); |
|
239
|
|
|
|
|
240
|
|
|
// Abort early if it does not exist |
|
241
|
|
|
if ( is_wp_error( $discount ) ) { |
|
242
|
|
|
return $discount; |
|
|
|
|
|
|
243
|
|
|
} |
|
244
|
|
|
|
|
245
|
|
|
// Prepare the response |
|
246
|
|
|
$response = $this->prepare_item_for_response( $discount, $request ); |
|
|
|
|
|
|
247
|
|
|
|
|
248
|
|
|
/** |
|
249
|
|
|
* Filters the responses for single discount requests. |
|
250
|
|
|
* |
|
251
|
|
|
* |
|
252
|
|
|
* @since 1.0.13 |
|
253
|
|
|
* @var WP_HTTP_Response |
|
254
|
|
|
* |
|
255
|
|
|
* @param WP_HTTP_Response $response Response. |
|
256
|
|
|
* @param WP_REST_Request $request The request used. |
|
257
|
|
|
*/ |
|
258
|
|
|
$response = apply_filters( "wpinv_rest_get_discount_response", $response, $request ); |
|
259
|
|
|
|
|
260
|
|
|
return rest_ensure_response( $response ); |
|
261
|
|
|
|
|
262
|
|
|
} |
|
263
|
|
|
|
|
264
|
|
|
/** |
|
265
|
|
|
* Checks if a given request has access to create an invoice item. |
|
266
|
|
|
* |
|
267
|
|
|
* @since 1.0.13 |
|
268
|
|
|
* |
|
269
|
|
|
* @param WP_REST_Request $request Full details about the request. |
|
270
|
|
|
* @return true|WP_Error True if the request has access to create items, WP_Error object otherwise. |
|
271
|
|
|
*/ |
|
272
|
|
|
public function create_item_permissions_check( $request ) { |
|
273
|
|
|
|
|
274
|
|
|
if ( ! empty( $request['id'] ) ) { |
|
275
|
|
|
return new WP_Error( 'rest_item_exists', __( 'Cannot create existing item.', 'invoicing' ), array( 'status' => 400 ) ); |
|
276
|
|
|
} |
|
277
|
|
|
|
|
278
|
|
|
if ( wpinv_current_user_can_manage_invoicing() ) { |
|
279
|
|
|
return true; |
|
280
|
|
|
} |
|
281
|
|
|
|
|
282
|
|
|
$post_type = get_post_type_object( $this->post_type ); |
|
283
|
|
|
if ( ! current_user_can( $post_type->cap->create_posts ) ) { |
|
284
|
|
|
return new WP_Error( |
|
285
|
|
|
'rest_cannot_create', |
|
286
|
|
|
__( 'Sorry, you are not allowed to create discounts as this user.', 'invoicing' ), |
|
287
|
|
|
array( |
|
288
|
|
|
'status' => rest_authorization_required_code(), |
|
289
|
|
|
) |
|
290
|
|
|
); |
|
291
|
|
|
} |
|
292
|
|
|
|
|
293
|
|
|
return true; |
|
294
|
|
|
} |
|
295
|
|
|
|
|
296
|
|
|
/** |
|
297
|
|
|
* Creates a single discount. |
|
298
|
|
|
* |
|
299
|
|
|
* @since 1.0.13 |
|
300
|
|
|
* |
|
301
|
|
|
* @param WP_REST_Request $request Full details about the request. |
|
302
|
|
|
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. |
|
303
|
|
|
*/ |
|
304
|
|
|
public function create_item( $request ) { |
|
305
|
|
|
|
|
306
|
|
|
if ( ! empty( $request['id'] ) ) { |
|
307
|
|
|
return new WP_Error( 'rest_item_exists', __( 'Cannot create existing discount.', 'invoicing' ), array( 'status' => 400 ) ); |
|
308
|
|
|
} |
|
309
|
|
|
|
|
310
|
|
|
$request->set_param( 'context', 'edit' ); |
|
311
|
|
|
|
|
312
|
|
|
// Prepare the updated data. |
|
313
|
|
|
$discount_data = $this->prepare_item_for_database( $request ); |
|
314
|
|
|
|
|
315
|
|
|
if ( is_wp_error( $discount_data ) ) { |
|
316
|
|
|
return $discount_data; |
|
|
|
|
|
|
317
|
|
|
} |
|
318
|
|
|
|
|
319
|
|
|
$discount_data['post_type'] = $this->post_type; |
|
320
|
|
|
|
|
321
|
|
|
// Try creating the discount. |
|
322
|
|
|
$discount = wp_insert_post( $discount_data, true ); |
|
|
|
|
|
|
323
|
|
|
|
|
324
|
|
|
if ( is_wp_error( $discount ) ) { |
|
325
|
|
|
return $discount; |
|
|
|
|
|
|
326
|
|
|
} |
|
327
|
|
|
|
|
328
|
|
|
// Prepare the response |
|
329
|
|
|
$response = $this->prepare_item_for_response( $discount, $request ); |
|
|
|
|
|
|
330
|
|
|
|
|
331
|
|
|
/** |
|
332
|
|
|
* Fires after a single discount is created or updated via the REST API. |
|
333
|
|
|
* |
|
334
|
|
|
* @since 1.0.13 |
|
335
|
|
|
* |
|
336
|
|
|
* @param WP_Post $discount Inserted or updated discount object. |
|
337
|
|
|
* @param WP_REST_Request $request Request object. |
|
338
|
|
|
* @param bool $creating True when creating a post, false when updating. |
|
339
|
|
|
*/ |
|
340
|
|
|
do_action( "wpinv_rest_insert_discount", $discount, $request, true ); |
|
341
|
|
|
|
|
342
|
|
|
/** |
|
343
|
|
|
* Filters the responses for creating single item requests. |
|
344
|
|
|
* |
|
345
|
|
|
* |
|
346
|
|
|
* @since 1.0.13 |
|
347
|
|
|
* |
|
348
|
|
|
* |
|
349
|
|
|
* @param array $response Invoice properties. |
|
350
|
|
|
* @param WP_REST_Request $request The request used. |
|
351
|
|
|
*/ |
|
352
|
|
|
$response = apply_filters( "wpinv_rest_create_discount_response", $response, $request ); |
|
353
|
|
|
|
|
354
|
|
|
return rest_ensure_response( $response ); |
|
355
|
|
|
} |
|
356
|
|
|
|
|
357
|
|
|
/** |
|
358
|
|
|
* Checks if a given request has access to update a discount. |
|
359
|
|
|
* |
|
360
|
|
|
* @since 1.0.13 |
|
361
|
|
|
* |
|
362
|
|
|
* @param WP_REST_Request $request Full details about the request. |
|
363
|
|
|
* @return true|WP_Error True if the request has access to update the item, WP_Error object otherwise. |
|
364
|
|
|
*/ |
|
365
|
|
|
public function update_item_permissions_check( $request ) { |
|
366
|
|
|
|
|
367
|
|
|
// Retrieve the item. |
|
368
|
|
|
$item = $this->get_post( $request['id'] ); |
|
369
|
|
|
if ( is_wp_error( $item ) ) { |
|
370
|
|
|
return $item; |
|
|
|
|
|
|
371
|
|
|
} |
|
372
|
|
|
|
|
373
|
|
|
if ( wpinv_current_user_can_manage_invoicing() ) { |
|
374
|
|
|
return true; |
|
375
|
|
|
} |
|
376
|
|
|
|
|
377
|
|
|
return new WP_Error( |
|
378
|
|
|
'rest_cannot_edit', |
|
379
|
|
|
__( 'Sorry, you are not allowed to update this discount.', 'invoicing' ), |
|
380
|
|
|
array( |
|
381
|
|
|
'status' => rest_authorization_required_code(), |
|
382
|
|
|
) |
|
383
|
|
|
); |
|
384
|
|
|
|
|
385
|
|
|
} |
|
386
|
|
|
|
|
387
|
|
|
/** |
|
388
|
|
|
* Updates a single discount. |
|
389
|
|
|
* |
|
390
|
|
|
* @since 1.0.13 |
|
391
|
|
|
* |
|
392
|
|
|
* @param WP_REST_Request $request Full details about the request. |
|
393
|
|
|
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. |
|
394
|
|
|
*/ |
|
395
|
|
|
public function update_item( $request ) { |
|
396
|
|
|
|
|
397
|
|
|
// Ensure the item exists. |
|
398
|
|
|
$valid_check = $this->get_post( $request['id'] ); |
|
399
|
|
|
|
|
400
|
|
|
// Abort early if it does not exist |
|
401
|
|
|
if ( is_wp_error( $valid_check ) ) { |
|
402
|
|
|
return $valid_check; |
|
|
|
|
|
|
403
|
|
|
} |
|
404
|
|
|
|
|
405
|
|
|
$request->set_param( 'context', 'edit' ); |
|
406
|
|
|
|
|
407
|
|
|
// Prepare the updated data. |
|
408
|
|
|
$data_to_update = $this->prepare_item_for_database( $request ); |
|
409
|
|
|
|
|
410
|
|
|
if ( is_wp_error( $data_to_update ) ) { |
|
411
|
|
|
return $data_to_update; |
|
|
|
|
|
|
412
|
|
|
} |
|
413
|
|
|
|
|
414
|
|
|
if( empty( $data_to_update['meta_input'] ) ) { |
|
415
|
|
|
unset( $data_to_update['meta_input'] ); |
|
416
|
|
|
} |
|
417
|
|
|
|
|
418
|
|
|
// Abort if no item data is provided |
|
419
|
|
|
if( empty( $data_to_update ) ) { |
|
420
|
|
|
return new WP_Error( 'missing_data', __( 'An update request cannot be empty.', 'invoicing' ) ); |
|
421
|
|
|
} |
|
422
|
|
|
|
|
423
|
|
|
// post_status |
|
424
|
|
|
if( ! empty( $data_to_update['post_status'] ) ) { |
|
425
|
|
|
wpinv_update_discount_status( $request['id'], $data_to_update['post_status'] ); |
|
426
|
|
|
unset( $data_to_update['post_status'] ); |
|
427
|
|
|
} |
|
428
|
|
|
|
|
429
|
|
|
// Update the item |
|
430
|
|
|
if( ! empty( $data_to_update ) ) { |
|
431
|
|
|
|
|
432
|
|
|
// Include the item ID |
|
433
|
|
|
$data_to_update['ID'] = $request['id']; |
|
434
|
|
|
|
|
435
|
|
|
$updated = wp_update_post( $data_to_update, true ); |
|
436
|
|
|
|
|
437
|
|
|
// Incase the update operation failed... |
|
438
|
|
|
if ( is_wp_error( $updated ) ) { |
|
439
|
|
|
return $updated; |
|
|
|
|
|
|
440
|
|
|
} |
|
441
|
|
|
|
|
442
|
|
|
} |
|
443
|
|
|
|
|
444
|
|
|
$updated_discount = get_post( $request['id'] ); |
|
445
|
|
|
|
|
446
|
|
|
// Prepare the response |
|
447
|
|
|
$response = $this->prepare_item_for_response( $updated_discount, $request ); |
|
448
|
|
|
|
|
449
|
|
|
/** This action is documented in includes/class-wpinv-rest-item-controller.php */ |
|
450
|
|
|
do_action( "wpinv_rest_insert_discount", $updated_discount, $request, false ); |
|
451
|
|
|
|
|
452
|
|
|
/** |
|
453
|
|
|
* Filters the responses for updating single discount requests. |
|
454
|
|
|
* |
|
455
|
|
|
* |
|
456
|
|
|
* @since 1.0.13 |
|
457
|
|
|
* |
|
458
|
|
|
* |
|
459
|
|
|
* @param array $data_to_update Discount properties. |
|
460
|
|
|
* @param WP_REST_Request $request The request used. |
|
461
|
|
|
*/ |
|
462
|
|
|
$response = apply_filters( "wpinv_rest_update_discount_response", $response, $data_to_update, $request ); |
|
463
|
|
|
|
|
464
|
|
|
return rest_ensure_response( $response ); |
|
465
|
|
|
} |
|
466
|
|
|
|
|
467
|
|
|
/** |
|
468
|
|
|
* Checks if a given request has access to delete a discount. |
|
469
|
|
|
* |
|
470
|
|
|
* @since 1.0.13 |
|
471
|
|
|
* |
|
472
|
|
|
* @param WP_REST_Request $request Full details about the request. |
|
473
|
|
|
* @return true|WP_Error True if the request has access to delete the discount, WP_Error object otherwise. |
|
474
|
|
|
*/ |
|
475
|
|
|
public function delete_item_permissions_check( $request ) { |
|
476
|
|
|
|
|
477
|
|
|
// Retrieve the discount. |
|
478
|
|
|
$discount = $this->get_post( $request['id'] ); |
|
479
|
|
|
if ( is_wp_error( $discount ) ) { |
|
480
|
|
|
return $discount; |
|
|
|
|
|
|
481
|
|
|
} |
|
482
|
|
|
|
|
483
|
|
|
// Ensure the current user can delete the discount |
|
484
|
|
|
if (! wpinv_current_user_can_manage_invoicing() ) { |
|
485
|
|
|
return new WP_Error( |
|
486
|
|
|
'rest_cannot_delete', |
|
487
|
|
|
__( 'Sorry, you are not allowed to delete this discount.', 'invoicing' ), |
|
488
|
|
|
array( |
|
489
|
|
|
'status' => rest_authorization_required_code(), |
|
490
|
|
|
) |
|
491
|
|
|
); |
|
492
|
|
|
} |
|
493
|
|
|
|
|
494
|
|
|
return true; |
|
495
|
|
|
} |
|
496
|
|
|
|
|
497
|
|
|
/** |
|
498
|
|
|
* Deletes a single discount. |
|
499
|
|
|
* |
|
500
|
|
|
* @since 1.0.13 |
|
501
|
|
|
* |
|
502
|
|
|
* @param WP_REST_Request $request Full details about the request. |
|
503
|
|
|
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. |
|
504
|
|
|
*/ |
|
505
|
|
|
public function delete_item( $request ) { |
|
506
|
|
|
|
|
507
|
|
|
// Retrieve the discount. |
|
508
|
|
|
$discount = $this->get_post( $request['id'] ); |
|
509
|
|
|
if ( is_wp_error( $discount ) ) { |
|
510
|
|
|
return $discount; |
|
|
|
|
|
|
511
|
|
|
} |
|
512
|
|
|
|
|
513
|
|
|
$request->set_param( 'context', 'edit' ); |
|
514
|
|
|
|
|
515
|
|
|
// Prepare the discount id |
|
516
|
|
|
$id = $discount->ID; |
|
|
|
|
|
|
517
|
|
|
|
|
518
|
|
|
// Prepare the response |
|
519
|
|
|
$response = $this->prepare_item_for_response( $discount, $request ); |
|
|
|
|
|
|
520
|
|
|
|
|
521
|
|
|
// Delete the discount... |
|
522
|
|
|
wpinv_remove_discount( $id ); |
|
523
|
|
|
|
|
524
|
|
|
/** |
|
525
|
|
|
* Fires immediately after a single discount is deleted via the REST API. |
|
526
|
|
|
* |
|
527
|
|
|
* |
|
528
|
|
|
* @since 1.0.13 |
|
529
|
|
|
* |
|
530
|
|
|
* @param WP_POST $discount The deleted discount. |
|
531
|
|
|
* @param WP_REST_Request $request The request sent to the API. |
|
532
|
|
|
*/ |
|
533
|
|
|
do_action( "wpinv_rest_delete_discount", $discount, $request ); |
|
534
|
|
|
|
|
535
|
|
|
return $response; |
|
536
|
|
|
|
|
537
|
|
|
} |
|
538
|
|
|
|
|
539
|
|
|
|
|
540
|
|
|
/** |
|
541
|
|
|
* Retrieves the query params for the discount collection. |
|
542
|
|
|
* |
|
543
|
|
|
* @since 1.0.13 |
|
544
|
|
|
* |
|
545
|
|
|
* @return array Collection parameters. |
|
546
|
|
|
*/ |
|
547
|
|
|
public function get_collection_params() { |
|
548
|
|
|
|
|
549
|
|
|
$query_params = array( |
|
550
|
|
|
|
|
551
|
|
|
// Discount status. |
|
552
|
|
|
'status' => array( |
|
553
|
|
|
'default' => 'publish', |
|
554
|
|
|
'description' => __( 'Limit result set to discounts assigned one or more statuses.', 'invoicing' ), |
|
555
|
|
|
'type' => 'array', |
|
556
|
|
|
'sanitize_callback' => array( $this, 'sanitize_post_statuses' ), |
|
557
|
|
|
), |
|
558
|
|
|
|
|
559
|
|
|
// Discount types |
|
560
|
|
|
'type' => array( |
|
561
|
|
|
'description' => __( 'Type of discounts to fetch.', 'invoicing' ), |
|
562
|
|
|
'type' => 'array', |
|
563
|
|
|
'default' => array_keys( wpinv_get_discount_types() ), |
|
564
|
|
|
'items' => array( |
|
565
|
|
|
'enum' => array_keys( wpinv_get_discount_types() ), |
|
566
|
|
|
'type' => 'string', |
|
567
|
|
|
), |
|
568
|
|
|
), |
|
569
|
|
|
|
|
570
|
|
|
// Number of results per page |
|
571
|
|
|
'limit' => array( |
|
572
|
|
|
'description' => __( 'Number of discounts to fetch.', 'invoicing' ), |
|
573
|
|
|
'type' => 'integer', |
|
574
|
|
|
'default' => (int) get_option( 'posts_per_page' ), |
|
575
|
|
|
), |
|
576
|
|
|
|
|
577
|
|
|
// Pagination |
|
578
|
|
|
'page' => array( |
|
579
|
|
|
'description' => __( 'Current page to fetch.', 'invoicing' ), |
|
580
|
|
|
'type' => 'integer', |
|
581
|
|
|
'default' => 1, |
|
582
|
|
|
), |
|
583
|
|
|
|
|
584
|
|
|
// Exclude certain items |
|
585
|
|
|
'exclude' => array( |
|
586
|
|
|
'description' => __( 'Ensure result set excludes specific IDs.', 'invoicing' ), |
|
587
|
|
|
'type' => 'array', |
|
588
|
|
|
'items' => array( |
|
589
|
|
|
'type' => 'integer', |
|
590
|
|
|
), |
|
591
|
|
|
'default' => array(), |
|
592
|
|
|
), |
|
593
|
|
|
|
|
594
|
|
|
// Order discounts by |
|
595
|
|
|
'orderby' => array( |
|
596
|
|
|
'description' => __( 'Sort discounts by object attribute.', 'invoicing' ), |
|
597
|
|
|
'type' => 'string', |
|
598
|
|
|
'default' => 'date', |
|
599
|
|
|
'enum' => array( |
|
600
|
|
|
'author', |
|
601
|
|
|
'date', |
|
602
|
|
|
'ID', |
|
603
|
|
|
'modified', |
|
604
|
|
|
'title', |
|
605
|
|
|
'relevance', |
|
606
|
|
|
'rand' |
|
607
|
|
|
), |
|
608
|
|
|
), |
|
609
|
|
|
|
|
610
|
|
|
// How to order |
|
611
|
|
|
'order' => array( |
|
612
|
|
|
'description' => __( 'Order sort attribute ascending or descending.', 'invoicing' ), |
|
613
|
|
|
'type' => 'string', |
|
614
|
|
|
'default' => 'DESC', |
|
615
|
|
|
'enum' => array( 'ASC', 'DESC' ), |
|
616
|
|
|
), |
|
617
|
|
|
|
|
618
|
|
|
// Search term |
|
619
|
|
|
'search' => array( |
|
620
|
|
|
'description' => __( 'Return discounts that match the search term.', 'invoicing' ), |
|
621
|
|
|
'type' => 'string', |
|
622
|
|
|
), |
|
623
|
|
|
); |
|
624
|
|
|
|
|
625
|
|
|
/** |
|
626
|
|
|
* Filter collection parameters for the discounts controller. |
|
627
|
|
|
* |
|
628
|
|
|
* |
|
629
|
|
|
* @since 1.0.13 |
|
630
|
|
|
* |
|
631
|
|
|
* @param array $query_params JSON Schema-formatted collection parameters. |
|
632
|
|
|
*/ |
|
633
|
|
|
return apply_filters( "wpinv_rest_discounts_collection_params", $query_params ); |
|
634
|
|
|
} |
|
635
|
|
|
|
|
636
|
|
|
/** |
|
637
|
|
|
* Checks if a given post type can be viewed or managed. |
|
638
|
|
|
* |
|
639
|
|
|
* @since 1.0.13 |
|
640
|
|
|
* |
|
641
|
|
|
* @param object|string $post_type Post type name or object. |
|
642
|
|
|
* @return bool Whether the post type is allowed in REST. |
|
643
|
|
|
*/ |
|
644
|
|
|
protected function check_is_post_type_allowed( $post_type ) { |
|
645
|
|
|
return true; |
|
646
|
|
|
} |
|
647
|
|
|
|
|
648
|
|
|
/** |
|
649
|
|
|
* Prepares a single item for create or update. |
|
650
|
|
|
* |
|
651
|
|
|
* @since 1.0.13 |
|
652
|
|
|
* |
|
653
|
|
|
* @param WP_REST_Request $request Request object. |
|
654
|
|
|
* @return array|WP_Error Discount Properties or WP_Error. |
|
655
|
|
|
*/ |
|
656
|
|
|
protected function prepare_item_for_database( $request ) { |
|
657
|
|
|
$prepared_item = new stdClass(); |
|
658
|
|
|
$prepared_item->meta_input = array(); |
|
659
|
|
|
|
|
660
|
|
|
// Post ID. |
|
661
|
|
|
if ( isset( $request['id'] ) ) { |
|
662
|
|
|
$existing_item = $this->get_post( $request['id'] ); |
|
663
|
|
|
if ( is_wp_error( $existing_item ) ) { |
|
664
|
|
|
return $existing_item; |
|
|
|
|
|
|
665
|
|
|
} |
|
666
|
|
|
|
|
667
|
|
|
$prepared_item->ID = $existing_item->ID; |
|
|
|
|
|
|
668
|
|
|
} |
|
669
|
|
|
|
|
670
|
|
|
$schema = $this->get_item_schema(); |
|
671
|
|
|
|
|
672
|
|
|
// item title. |
|
673
|
|
|
if ( ! empty( $schema['properties']['title'] ) && isset( $request['title'] ) ) { |
|
674
|
|
|
$prepared_item->post_title = sanitize_text_field( $request['title'] ); |
|
675
|
|
|
} |
|
676
|
|
|
|
|
677
|
|
|
// item status. |
|
678
|
|
|
if ( ! empty( $schema['properties']['status'] ) && isset( $request['status'] ) && in_array( $request['status'], array_keys( get_post_stati( array( 'internal' => false ) ) ) ) ) { |
|
679
|
|
|
$prepared_item->post_status = sanitize_text_field( $request['status'] ); |
|
680
|
|
|
} |
|
681
|
|
|
|
|
682
|
|
|
// Code. |
|
683
|
|
|
if ( ! empty( $schema['properties']['code'] ) && isset( $request['code'] ) ) { |
|
684
|
|
|
$prepared_item->meta_input['_wpi_discount_code'] = trim( $request['code'] ); |
|
685
|
|
|
} |
|
686
|
|
|
|
|
687
|
|
|
// Type. |
|
688
|
|
|
if ( ! empty( $schema['properties']['type'] ) && isset( $request['type'] ) && in_array( $request['type'], array_keys( wpinv_get_discount_types() ) ) ) { |
|
689
|
|
|
$prepared_item->meta_input['_wpi_discount_type'] = trim( $request['type'] ); |
|
690
|
|
|
} |
|
691
|
|
|
|
|
692
|
|
|
// Amount. |
|
693
|
|
|
if ( ! empty( $schema['properties']['amount'] ) && isset( $request['amount'] ) ) { |
|
694
|
|
|
$prepared_item->meta_input['_wpi_discount_amount'] = floatval( $request['amount'] ); |
|
695
|
|
|
} |
|
696
|
|
|
|
|
697
|
|
|
// Items. |
|
698
|
|
|
if ( ! empty( $schema['properties']['items'] ) && isset( $request['items'] ) ) { |
|
699
|
|
|
$prepared_item->meta_input['_wpi_discount_items'] = wpinv_parse_list( $request['items'] ); |
|
700
|
|
|
} |
|
701
|
|
|
|
|
702
|
|
|
// Excluded Items. |
|
703
|
|
|
if ( ! empty( $schema['properties']['exclude_items'] ) && isset( $request['exclude_items'] ) ) { |
|
704
|
|
|
$prepared_item->meta_input['_wpi_discount_excluded_items'] = wpinv_parse_list( $request['exclude_items'] ); |
|
705
|
|
|
} |
|
706
|
|
|
|
|
707
|
|
|
// Start date. |
|
708
|
|
|
if ( ! empty( $schema['properties']['start_date'] ) && isset( $request['start_date'] ) ) { |
|
709
|
|
|
$prepared_item->meta_input['_wpi_discount_start'] = trim( $request['start_date'] ); |
|
710
|
|
|
} |
|
711
|
|
|
|
|
712
|
|
|
// End date. |
|
713
|
|
|
if ( ! empty( $schema['properties']['end_date'] ) && isset( $request['end_date'] ) ) { |
|
714
|
|
|
$prepared_item->meta_input['_wpi_discount_expiration'] = trim( $request['end_date'] ); |
|
715
|
|
|
} |
|
716
|
|
|
|
|
717
|
|
|
// Minimum amount. |
|
718
|
|
|
if ( ! empty( $schema['properties']['minimum_amount'] ) && isset( $request['minimum_amount'] ) ) { |
|
719
|
|
|
$prepared_item->meta_input['_wpi_discount_min_total'] = floatval( $request['minimum_amount'] ); |
|
720
|
|
|
} |
|
721
|
|
|
|
|
722
|
|
|
// Maximum amount. |
|
723
|
|
|
if ( ! empty( $schema['properties']['maximum_amount'] ) && isset( $request['maximum_amount'] ) ) { |
|
724
|
|
|
$prepared_item->meta_input['_wpi_discount_max_total'] = floatval( $request['maximum_amount'] ); |
|
725
|
|
|
} |
|
726
|
|
|
|
|
727
|
|
|
// Recurring. |
|
728
|
|
|
if ( ! empty( $schema['properties']['recurring'] ) && isset( $request['recurring'] ) ) { |
|
729
|
|
|
$prepared_item->meta_input['_wpi_discount_is_recurring'] = empty( (int) $request['recurring'] ) ? 0 : 1; |
|
730
|
|
|
} |
|
731
|
|
|
|
|
732
|
|
|
// Maximum uses. |
|
733
|
|
|
if ( ! empty( $schema['properties']['max_uses'] ) && isset( $request['max_uses'] ) ) { |
|
734
|
|
|
$prepared_item->meta_input['_wpi_discount_max_uses'] = intval( $request['max_uses'] ); |
|
735
|
|
|
} |
|
736
|
|
|
|
|
737
|
|
|
// Single use. |
|
738
|
|
|
if ( ! empty( $schema['properties']['single_use'] ) && isset( $request['single_use'] ) ) { |
|
739
|
|
|
$prepared_item->meta_input['_wpi_discount_is_single_use'] = empty( (int) $request['single_use'] ) ? 0 : 1; |
|
740
|
|
|
} |
|
741
|
|
|
|
|
742
|
|
|
$discount_data = (array) wp_unslash( $prepared_item ); |
|
|
|
|
|
|
743
|
|
|
|
|
744
|
|
|
/** |
|
745
|
|
|
* Filters an item before it is inserted via the REST API. |
|
746
|
|
|
* |
|
747
|
|
|
* @since 1.0.13 |
|
748
|
|
|
* |
|
749
|
|
|
* @param array $discount_data An array of discount data |
|
750
|
|
|
* @param WP_REST_Request $request Request object. |
|
751
|
|
|
*/ |
|
752
|
|
|
return apply_filters( "wpinv_rest_pre_insert_discount", $discount_data, $request ); |
|
753
|
|
|
|
|
754
|
|
|
} |
|
755
|
|
|
|
|
756
|
|
|
/** |
|
757
|
|
|
* Prepares a single discount output for response. |
|
758
|
|
|
* |
|
759
|
|
|
* @since 1.0.13 |
|
760
|
|
|
* |
|
761
|
|
|
* @param WP_Post $discount WP_Post object. |
|
762
|
|
|
* @param WP_REST_Request $request Request object. |
|
763
|
|
|
* @return WP_REST_Response Response object. |
|
764
|
|
|
*/ |
|
765
|
|
|
public function prepare_item_for_response( $discount, $request ) { |
|
766
|
|
|
|
|
767
|
|
|
$GLOBALS['post'] = get_post( $discount->ID ); |
|
768
|
|
|
|
|
769
|
|
|
setup_postdata( $discount->ID ); |
|
770
|
|
|
|
|
771
|
|
|
// Fetch the fields to include in this response. |
|
772
|
|
|
$fields = $this->get_fields_for_response( $request ); |
|
773
|
|
|
|
|
774
|
|
|
// Base fields for every discount. |
|
775
|
|
|
$data = array(); |
|
776
|
|
|
|
|
777
|
|
|
// Set up ID. |
|
778
|
|
|
if ( rest_is_field_included( 'id', $fields ) ) { |
|
779
|
|
|
$data['id'] = $discount->ID; |
|
780
|
|
|
} |
|
781
|
|
|
|
|
782
|
|
|
// Title. |
|
783
|
|
|
if ( rest_is_field_included( 'title', $fields ) ) { |
|
784
|
|
|
$data['title'] = get_the_title( $discount->ID ); |
|
785
|
|
|
} |
|
786
|
|
|
|
|
787
|
|
|
// Code. |
|
788
|
|
|
if ( rest_is_field_included( 'code', $fields ) ) { |
|
789
|
|
|
$data['code'] = wpinv_get_discount_code( $discount->ID ); |
|
790
|
|
|
} |
|
791
|
|
|
|
|
792
|
|
|
// Type. |
|
793
|
|
|
if ( rest_is_field_included( 'type', $fields ) ) { |
|
794
|
|
|
$data['type'] = wpinv_get_discount_type( $discount->ID ); |
|
795
|
|
|
} |
|
796
|
|
|
|
|
797
|
|
|
// Amount. |
|
798
|
|
|
if ( rest_is_field_included( 'amount', $fields ) ) { |
|
799
|
|
|
$data['amount'] = wpinv_get_discount_amount( $discount->ID ); |
|
800
|
|
|
} |
|
801
|
|
|
|
|
802
|
|
|
// Status. |
|
803
|
|
|
if ( rest_is_field_included( 'status', $fields ) ) { |
|
804
|
|
|
$data['status'] = get_post_status( $discount->ID ); |
|
805
|
|
|
} |
|
806
|
|
|
|
|
807
|
|
|
// Items. |
|
808
|
|
|
if ( rest_is_field_included( 'items', $fields ) ) { |
|
809
|
|
|
$data['items'] = wpinv_get_discount_item_reqs( $discount->ID ); |
|
810
|
|
|
} |
|
811
|
|
|
|
|
812
|
|
|
// Excluded Items. |
|
813
|
|
|
if ( rest_is_field_included( 'exclude_items', $fields ) ) { |
|
814
|
|
|
$data['exclude_items'] = wpinv_get_discount_excluded_items( $discount->ID ); |
|
815
|
|
|
} |
|
816
|
|
|
|
|
817
|
|
|
// Start date. |
|
818
|
|
|
if ( rest_is_field_included( 'start_date', $fields ) ) { |
|
819
|
|
|
$data['start_date'] = wpinv_get_discount_start_date( $discount->ID ); |
|
820
|
|
|
} |
|
821
|
|
|
|
|
822
|
|
|
// End date. |
|
823
|
|
|
if ( rest_is_field_included( 'end_date', $fields ) ) { |
|
824
|
|
|
$data['end_date'] = wpinv_get_discount_expiration( $discount->ID ); |
|
825
|
|
|
} |
|
826
|
|
|
|
|
827
|
|
|
// Minimum amount. |
|
828
|
|
|
if ( rest_is_field_included( 'minimum_amount', $fields ) ) { |
|
829
|
|
|
$data['minimum_amount'] = wpinv_get_discount_min_total( $discount->ID ); |
|
830
|
|
|
} |
|
831
|
|
|
|
|
832
|
|
|
// Maximum amount. |
|
833
|
|
|
if ( rest_is_field_included( 'maximum_amount', $fields ) ) { |
|
834
|
|
|
$data['maximum_amount'] = wpinv_get_discount_max_total( $discount->ID ); |
|
835
|
|
|
} |
|
836
|
|
|
|
|
837
|
|
|
// Recurring. |
|
838
|
|
|
if ( rest_is_field_included( 'recurring', $fields ) ) { |
|
839
|
|
|
$data['recurring'] = wpinv_discount_is_recurring( $discount->ID ); |
|
840
|
|
|
} |
|
841
|
|
|
|
|
842
|
|
|
// Maximum uses. |
|
843
|
|
|
if ( rest_is_field_included( 'max_uses', $fields ) ) { |
|
844
|
|
|
$data['max_uses'] = wpinv_get_discount_max_uses( $discount->ID ); |
|
845
|
|
|
} |
|
846
|
|
|
|
|
847
|
|
|
// Single use. |
|
848
|
|
|
if ( rest_is_field_included( 'single_use', $fields ) ) { |
|
849
|
|
|
$data['single_use'] = wpinv_discount_is_single_use( $discount->ID ); |
|
850
|
|
|
} |
|
851
|
|
|
|
|
852
|
|
|
$context = ! empty( $request['context'] ) ? $request['context'] : 'view'; |
|
853
|
|
|
$data = $this->add_additional_fields_to_object( $data, $request ); |
|
854
|
|
|
$data = $this->filter_response_by_context( $data, $context ); |
|
855
|
|
|
|
|
856
|
|
|
// Wrap the data in a response object. |
|
857
|
|
|
$response = rest_ensure_response( $data ); |
|
858
|
|
|
|
|
859
|
|
|
$links = $this->prepare_links( $discount ); |
|
860
|
|
|
$response->add_links( $links ); |
|
861
|
|
|
|
|
862
|
|
|
if ( ! empty( $links['self']['href'] ) ) { |
|
863
|
|
|
$actions = $this->get_available_actions( $discount, $request ); |
|
864
|
|
|
|
|
865
|
|
|
$self = $links['self']['href']; |
|
866
|
|
|
|
|
867
|
|
|
foreach ( $actions as $rel ) { |
|
868
|
|
|
$response->add_link( $rel, $self ); |
|
869
|
|
|
} |
|
870
|
|
|
} |
|
871
|
|
|
|
|
872
|
|
|
/** |
|
873
|
|
|
* Filters the discount data for a response. |
|
874
|
|
|
* |
|
875
|
|
|
* @since 1.0.13 |
|
876
|
|
|
* |
|
877
|
|
|
* @param WP_REST_Response $response The response object. |
|
878
|
|
|
* @param WP_Post $discount The discount post object. |
|
879
|
|
|
* @param WP_REST_Request $request Request object. |
|
880
|
|
|
*/ |
|
881
|
|
|
return apply_filters( "wpinv_rest_prepare_discount", $response, $discount, $request ); |
|
|
|
|
|
|
882
|
|
|
} |
|
883
|
|
|
|
|
884
|
|
|
/** |
|
885
|
|
|
* Gets an array of fields to be included on the response. |
|
886
|
|
|
* |
|
887
|
|
|
* Included fields are based on item schema and `_fields=` request argument. |
|
888
|
|
|
* |
|
889
|
|
|
* @since 1.0.13 |
|
890
|
|
|
* |
|
891
|
|
|
* @param WP_REST_Request $request Full details about the request. |
|
892
|
|
|
* @return array Fields to be included in the response. |
|
893
|
|
|
*/ |
|
894
|
|
|
public function get_fields_for_response( $request ) { |
|
895
|
|
|
$schema = $this->get_item_schema(); |
|
896
|
|
|
$properties = isset( $schema['properties'] ) ? $schema['properties'] : array(); |
|
897
|
|
|
|
|
898
|
|
|
$additional_fields = $this->get_additional_fields(); |
|
899
|
|
|
foreach ( $additional_fields as $field_name => $field_options ) { |
|
900
|
|
|
// For back-compat, include any field with an empty schema |
|
901
|
|
|
// because it won't be present in $this->get_item_schema(). |
|
902
|
|
|
if ( is_null( $field_options['schema'] ) ) { |
|
903
|
|
|
$properties[ $field_name ] = $field_options; |
|
904
|
|
|
} |
|
905
|
|
|
} |
|
906
|
|
|
|
|
907
|
|
|
// Exclude fields that specify a different context than the request context. |
|
908
|
|
|
$context = $request['context']; |
|
909
|
|
|
if ( $context ) { |
|
910
|
|
|
foreach ( $properties as $name => $options ) { |
|
911
|
|
|
if ( ! empty( $options['context'] ) && ! in_array( $context, $options['context'], true ) ) { |
|
912
|
|
|
unset( $properties[ $name ] ); |
|
913
|
|
|
} |
|
914
|
|
|
} |
|
915
|
|
|
} |
|
916
|
|
|
|
|
917
|
|
|
$fields = array_keys( $properties ); |
|
918
|
|
|
|
|
919
|
|
|
if ( ! isset( $request['_fields'] ) ) { |
|
920
|
|
|
return $fields; |
|
921
|
|
|
} |
|
922
|
|
|
$requested_fields = wpinv_parse_list( $request['_fields'] ); |
|
923
|
|
|
if ( 0 === count( $requested_fields ) ) { |
|
924
|
|
|
return $fields; |
|
925
|
|
|
} |
|
926
|
|
|
// Trim off outside whitespace from the comma delimited list. |
|
927
|
|
|
$requested_fields = array_map( 'trim', $requested_fields ); |
|
928
|
|
|
// Always persist 'id', because it can be needed for add_additional_fields_to_object(). |
|
929
|
|
|
if ( in_array( 'id', $fields, true ) ) { |
|
930
|
|
|
$requested_fields[] = 'id'; |
|
931
|
|
|
} |
|
932
|
|
|
// Return the list of all requested fields which appear in the schema. |
|
933
|
|
|
return array_reduce( |
|
934
|
|
|
$requested_fields, |
|
935
|
|
|
function( $response_fields, $field ) use ( $fields ) { |
|
936
|
|
|
if ( in_array( $field, $fields, true ) ) { |
|
937
|
|
|
$response_fields[] = $field; |
|
938
|
|
|
return $response_fields; |
|
939
|
|
|
} |
|
940
|
|
|
// Check for nested fields if $field is not a direct match. |
|
941
|
|
|
$nested_fields = explode( '.', $field ); |
|
942
|
|
|
// A nested field is included so long as its top-level property is |
|
943
|
|
|
// present in the schema. |
|
944
|
|
|
if ( in_array( $nested_fields[0], $fields, true ) ) { |
|
945
|
|
|
$response_fields[] = $field; |
|
946
|
|
|
} |
|
947
|
|
|
return $response_fields; |
|
948
|
|
|
}, |
|
949
|
|
|
array() |
|
950
|
|
|
); |
|
951
|
|
|
} |
|
952
|
|
|
|
|
953
|
|
|
/** |
|
954
|
|
|
* Retrieves the discount's schema, conforming to JSON Schema. |
|
955
|
|
|
* |
|
956
|
|
|
* @since 1.0.13 |
|
957
|
|
|
* |
|
958
|
|
|
* @return array Discount schema data. |
|
959
|
|
|
*/ |
|
960
|
|
|
public function get_item_schema() { |
|
961
|
|
|
|
|
962
|
|
|
// Maybe retrieve the schema from cache. |
|
963
|
|
|
if ( empty( $this->schema ) ) { |
|
964
|
|
|
return $this->add_additional_fields_schema( $this->schema ); |
|
965
|
|
|
} |
|
966
|
|
|
|
|
967
|
|
|
$schema = array( |
|
968
|
|
|
'$schema' => 'http://json-schema.org/draft-04/schema#', |
|
969
|
|
|
'title' => $this->post_type, |
|
970
|
|
|
'type' => 'object', |
|
971
|
|
|
|
|
972
|
|
|
// Base properties for every Item. |
|
973
|
|
|
'properties' => array( |
|
974
|
|
|
|
|
975
|
|
|
'id' => array( |
|
976
|
|
|
'description' => __( 'Unique identifier for the discount.', 'invoicing' ), |
|
977
|
|
|
'type' => 'integer', |
|
978
|
|
|
'context' => array( 'view', 'edit', 'embed' ), |
|
979
|
|
|
'readonly' => true, |
|
980
|
|
|
), |
|
981
|
|
|
|
|
982
|
|
|
'title' => array( |
|
983
|
|
|
'description' => __( 'The title for the discount.', 'invoicing' ), |
|
984
|
|
|
'type' => 'string', |
|
985
|
|
|
'context' => array( 'view', 'edit' ), |
|
986
|
|
|
), |
|
987
|
|
|
|
|
988
|
|
|
'code' => array( |
|
989
|
|
|
'description' => __( 'The discount code.', 'invoicing' ), |
|
990
|
|
|
'type' => 'string', |
|
991
|
|
|
'context' => array( 'view', 'edit', 'embed' ), |
|
992
|
|
|
'required' => true, |
|
993
|
|
|
), |
|
994
|
|
|
|
|
995
|
|
|
'type' => array( |
|
996
|
|
|
'description' => __( 'The type of discount.', 'invoicing' ), |
|
997
|
|
|
'type' => 'string', |
|
998
|
|
|
'enum' => array_keys( wpinv_get_discount_types() ), |
|
999
|
|
|
'context' => array( 'view', 'edit', 'embed' ), |
|
1000
|
|
|
'default' => 'percentage', |
|
1001
|
|
|
), |
|
1002
|
|
|
|
|
1003
|
|
|
'amount' => array( |
|
1004
|
|
|
'description' => __( 'The discount value.', 'invoicing' ), |
|
1005
|
|
|
'type' => 'number', |
|
1006
|
|
|
'context' => array( 'view', 'edit', 'embed' ), |
|
1007
|
|
|
'required' => true, |
|
1008
|
|
|
), |
|
1009
|
|
|
|
|
1010
|
|
|
'status' => array( |
|
1011
|
|
|
'description' => __( 'A named status for the discount.', 'invoicing' ), |
|
1012
|
|
|
'type' => 'string', |
|
1013
|
|
|
'enum' => array_keys( get_post_stati( array( 'internal' => false ) ) ), |
|
1014
|
|
|
'context' => array( 'view', 'edit' ), |
|
1015
|
|
|
), |
|
1016
|
|
|
|
|
1017
|
|
|
'items' => array( |
|
1018
|
|
|
'description' => __( 'Items which need to be in the cart to use this discount or, for "Item Discounts", which items are discounted. If left blank, this discount will be used on any item.', 'invoicing' ), |
|
1019
|
|
|
'type' => 'array', |
|
1020
|
|
|
'context' => array( 'view', 'edit' ), |
|
1021
|
|
|
), |
|
1022
|
|
|
|
|
1023
|
|
|
'exclude_items' => array( |
|
1024
|
|
|
'description' => __( 'Items which are NOT allowed to use this discount.', 'invoicing' ), |
|
1025
|
|
|
'type' => 'array', |
|
1026
|
|
|
'context' => array( 'view', 'edit' ), |
|
1027
|
|
|
), |
|
1028
|
|
|
|
|
1029
|
|
|
'start_date' => array( |
|
1030
|
|
|
'description' => __( 'The start date for the discount in the format of yyyy-mm-dd hh:mm:ss . If provided, the discount can only be used after or on this date.', 'invoicing' ), |
|
1031
|
|
|
'type' => 'string', |
|
1032
|
|
|
'context' => array( 'view', 'edit' ), |
|
1033
|
|
|
), |
|
1034
|
|
|
|
|
1035
|
|
|
'end_date' => array( |
|
1036
|
|
|
'description' => __( 'The expiration date for the discount.', 'invoicing' ), |
|
1037
|
|
|
'type' => 'string', |
|
1038
|
|
|
'context' => array( 'view', 'edit', 'embed' ), |
|
1039
|
|
|
), |
|
1040
|
|
|
|
|
1041
|
|
|
'minimum_amount' => array( |
|
1042
|
|
|
'description' => __( 'Minimum amount needed to use this invoice.', 'invoicing' ), |
|
1043
|
|
|
'type' => 'number', |
|
1044
|
|
|
'context' => array( 'view', 'edit', 'embed' ), |
|
1045
|
|
|
), |
|
1046
|
|
|
|
|
1047
|
|
|
'maximum_amount' => array( |
|
1048
|
|
|
'description' => __( 'Maximum amount needed to use this invoice.', 'invoicing' ), |
|
1049
|
|
|
'type' => 'number', |
|
1050
|
|
|
'context' => array( 'view', 'edit', 'embed' ), |
|
1051
|
|
|
), |
|
1052
|
|
|
|
|
1053
|
|
|
'recurring' => array( |
|
1054
|
|
|
'description' => __( 'Whether the discount is applied to all recurring payments or only the first recurring payment.', 'invoicing' ), |
|
1055
|
|
|
'type' => 'integer', |
|
1056
|
|
|
'context' => array( 'view', 'edit', 'embed' ), |
|
1057
|
|
|
), |
|
1058
|
|
|
|
|
1059
|
|
|
'max_uses' => array( |
|
1060
|
|
|
'description' => __( 'The maximum number of times this discount code can be used.', 'invoicing' ), |
|
1061
|
|
|
'type' => 'number', |
|
1062
|
|
|
'context' => array( 'view', 'edit', 'embed' ), |
|
1063
|
|
|
), |
|
1064
|
|
|
|
|
1065
|
|
|
'single_use' => array( |
|
1066
|
|
|
'description' => __( 'Whether or not this discount can only be used once per user.', 'invoicing' ), |
|
1067
|
|
|
'type' => 'integer', |
|
1068
|
|
|
'context' => array( 'view', 'edit', 'embed' ), |
|
1069
|
|
|
) |
|
1070
|
|
|
|
|
1071
|
|
|
), |
|
1072
|
|
|
); |
|
1073
|
|
|
|
|
1074
|
|
|
// Add helpful links to the discount schem. |
|
1075
|
|
|
$schema['links'] = $this->get_schema_links(); |
|
1076
|
|
|
|
|
1077
|
|
|
/** |
|
1078
|
|
|
* Filters the discount schema for the REST API. |
|
1079
|
|
|
* |
|
1080
|
|
|
* Enables adding extra properties to discounts. |
|
1081
|
|
|
* |
|
1082
|
|
|
* @since 1.0.13 |
|
1083
|
|
|
* |
|
1084
|
|
|
* @param array $schema The discount schema. |
|
1085
|
|
|
*/ |
|
1086
|
|
|
$schema = apply_filters( "wpinv_rest_discount_schema", $schema ); |
|
1087
|
|
|
|
|
1088
|
|
|
// Cache the discount schema. |
|
1089
|
|
|
$this->schema = $schema; |
|
1090
|
|
|
|
|
1091
|
|
|
return $this->add_additional_fields_schema( $this->schema ); |
|
1092
|
|
|
} |
|
1093
|
|
|
|
|
1094
|
|
|
/** |
|
1095
|
|
|
* Retrieve Link Description Objects that should be added to the Schema for the discounts collection. |
|
1096
|
|
|
* |
|
1097
|
|
|
* @since 1.0.13 |
|
1098
|
|
|
* |
|
1099
|
|
|
* @return array |
|
1100
|
|
|
*/ |
|
1101
|
|
|
protected function get_schema_links() { |
|
1102
|
|
|
|
|
1103
|
|
|
$href = rest_url( "{$this->namespace}/{$this->rest_base}/{id}" ); |
|
1104
|
|
|
|
|
1105
|
|
|
$links = array(); |
|
1106
|
|
|
|
|
1107
|
|
|
$links[] = array( |
|
1108
|
|
|
'rel' => 'https://api.w.org/action-publish', |
|
1109
|
|
|
'title' => __( 'The current user can publish this discount.', 'invoicing' ), |
|
1110
|
|
|
'href' => $href, |
|
1111
|
|
|
'targetSchema' => array( |
|
1112
|
|
|
'type' => 'object', |
|
1113
|
|
|
'properties' => array( |
|
1114
|
|
|
'status' => array( |
|
1115
|
|
|
'type' => 'string', |
|
1116
|
|
|
'enum' => array( 'publish', 'future' ), |
|
1117
|
|
|
), |
|
1118
|
|
|
), |
|
1119
|
|
|
), |
|
1120
|
|
|
); |
|
1121
|
|
|
|
|
1122
|
|
|
return $links; |
|
1123
|
|
|
} |
|
1124
|
|
|
|
|
1125
|
|
|
/** |
|
1126
|
|
|
* Prepares links for the request. |
|
1127
|
|
|
* |
|
1128
|
|
|
* @since 1.0.13 |
|
1129
|
|
|
* |
|
1130
|
|
|
* @param WP_Post $discount Post Object. |
|
1131
|
|
|
* @return array Links for the given discount. |
|
1132
|
|
|
*/ |
|
1133
|
|
|
protected function prepare_links( $discount ) { |
|
1134
|
|
|
|
|
1135
|
|
|
// Prepare the base REST API endpoint for discounts. |
|
1136
|
|
|
$base = sprintf( '%s/%s', $this->namespace, $this->rest_base ); |
|
1137
|
|
|
|
|
1138
|
|
|
// Entity meta. |
|
1139
|
|
|
$links = array( |
|
1140
|
|
|
'self' => array( |
|
1141
|
|
|
'href' => rest_url( trailingslashit( $base ) . $discount->ID ), |
|
1142
|
|
|
), |
|
1143
|
|
|
'collection' => array( |
|
1144
|
|
|
'href' => rest_url( $base ), |
|
1145
|
|
|
), |
|
1146
|
|
|
); |
|
1147
|
|
|
|
|
1148
|
|
|
/** |
|
1149
|
|
|
* Filters the returned discount links for the REST API. |
|
1150
|
|
|
* |
|
1151
|
|
|
* Enables adding extra links to discount API responses. |
|
1152
|
|
|
* |
|
1153
|
|
|
* @since 1.0.13 |
|
1154
|
|
|
* |
|
1155
|
|
|
* @param array $links Rest links. |
|
1156
|
|
|
*/ |
|
1157
|
|
|
return apply_filters( "wpinv_rest_discount_links", $links ); |
|
1158
|
|
|
|
|
1159
|
|
|
} |
|
1160
|
|
|
|
|
1161
|
|
|
/** |
|
1162
|
|
|
* Get the link relations available for the post and current user. |
|
1163
|
|
|
* |
|
1164
|
|
|
* @since 1.0.13 |
|
1165
|
|
|
* |
|
1166
|
|
|
* @param WP_Post $discount WP_Post object. |
|
1167
|
|
|
* @param WP_REST_Request $request Request object. |
|
1168
|
|
|
* @return array List of link relations. |
|
1169
|
|
|
*/ |
|
1170
|
|
|
protected function get_available_actions( $discount, $request ) { |
|
1171
|
|
|
|
|
1172
|
|
|
if ( 'edit' !== $request['context'] ) { |
|
1173
|
|
|
return array(); |
|
1174
|
|
|
} |
|
1175
|
|
|
|
|
1176
|
|
|
$rels = array(); |
|
1177
|
|
|
|
|
1178
|
|
|
// Retrieve the post type object. |
|
1179
|
|
|
$post_type = get_post_type_object( $discount->post_type ); |
|
1180
|
|
|
|
|
1181
|
|
|
// Mark discount as published. |
|
1182
|
|
|
if ( current_user_can( $post_type->cap->publish_posts ) ) { |
|
1183
|
|
|
$rels[] = 'https://api.w.org/action-publish'; |
|
1184
|
|
|
} |
|
1185
|
|
|
|
|
1186
|
|
|
/** |
|
1187
|
|
|
* Filters the available discount link relations for the REST API. |
|
1188
|
|
|
* |
|
1189
|
|
|
* Enables adding extra link relation for the current user and request to discount responses. |
|
1190
|
|
|
* |
|
1191
|
|
|
* @since 1.0.13 |
|
1192
|
|
|
* |
|
1193
|
|
|
* @param array $rels Available link relations. |
|
1194
|
|
|
*/ |
|
1195
|
|
|
return apply_filters( "wpinv_rest_discount_link_relations", $rels ); |
|
1196
|
|
|
} |
|
1197
|
|
|
|
|
1198
|
|
|
/** |
|
1199
|
|
|
* Handles rest requests for discount types. |
|
1200
|
|
|
* |
|
1201
|
|
|
* @since 1.0.13 |
|
1202
|
|
|
* |
|
1203
|
|
|
* |
|
1204
|
|
|
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. |
|
1205
|
|
|
*/ |
|
1206
|
|
|
public function get_discount_types() { |
|
1207
|
|
|
return rest_ensure_response( wpinv_get_discount_types() ); |
|
|
|
|
|
|
1208
|
|
|
} |
|
1209
|
|
|
|
|
1210
|
|
|
} |