PluginProbe
Discount Rules for WooCommerce – Disco | Dynamic Pricing, Conditions, Bulk, Bundle, BOGO / 1.4.21
Discount Rules for WooCommerce – Disco | Dynamic Pricing, Conditions, Bulk, Bundle, BOGO v1.4.21
1.4.21 1.4.20 1.4.19 1.4.18 1.4.17 1.4.16 1.4.15 1.4.14 1.4.13 1.4.12 1.4.11 1.4.10 1.4.9 1.4.8 1.4.7 1.4.6 1.4.5 1.4.4 1.4.3 1.4.2 1.4.1 1.4.0 1.3.54 1.3.53 1.3.52 All 184 releases
disco / rest / CampaignApi.php

CampaignApi.php in Discount Rules for WooCommerce – Disco | Dynamic Pricing, Conditions, Bulk, Bundle, BOGO 1.4.21, at rest/CampaignApi.php

820 lines 23.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php //phpcs:ignore
2
3 /**
4 * Campaign API
5 *
6 * @package Disco
7 * @subpackage \Rest
8 * @since 1.0.0
9 * @category Rest
10 */
11
12 namespace Disco\Rest;
13
14 use Disco\App\Campaign;
15 use Disco\App\DropDown\DiscountDropDown;
16 use Disco\App\Utility\Config;
17 use WP_REST_Controller;
18 use WP_REST_Server;
19
20 /**
21 * Class Campaign API
22 *
23 * @package Disco
24 * @subpackage \Rest
25 * @author Ohidul Islam <[email protected]>
26 * @link https://webappick.com
27 * @license https://opensource.org/licenses/gpl-license.php GNU Public License
28 * @category Rest
29 */
30 class CampaignApi extends WP_REST_Controller {//phpcs:ignore
31
32 /**
33 * CampaignApi constructor.
34 */
35 public function __construct() {
36 $this->namespace = Api::NAMESPACE_NAME . '/' . Api::VERSION;
37 $this->rest_base = Api::CAMPAIGN_ROUTE_NAME;
38 }
39
40 /**
41 * Registers the routes for the objects of the controller.
42 *
43 * @return void
44 * @throws \Exception If route is not available.
45 */
46 public function register_routes() { //phpcs:ignore
47
48 register_rest_route(
49 Api::NAMESPACE_NAME . '/' . Api::VERSION,
50 '/' . Api::CAMPAIGN_ROUTE_NAME . '/',
51 array(
52 array(
53 'methods' => WP_REST_Server::READABLE,
54 'callback' => array( $this, 'get_items' ),
55 'permission_callback' => array( $this, 'permissions_check' ),
56 'args' => $this->get_collection_params(),
57 ),
58 array(
59 'methods' => WP_REST_Server::CREATABLE,
60 'callback' => array( $this, 'create_item' ),
61 'permission_callback' => array( $this, 'permissions_check' ),
62 'args' => $this->get_endpoint_args_for_item_schema(),
63 ),
64 'schema' => array( $this, 'get_item_schema' ),
65 )
66 );
67
68 register_rest_route(
69 Api::NAMESPACE_NAME . '/' . Api::VERSION,
70 '/' . Api::CAMPAIGN_ROUTE_NAME . '/(?P<id>[\d]+)',
71 array(
72 'args' => array(
73 'id' => array(
74 'description' => __( 'Unique identifier for the object.', 'disco' ),
75 'type' => 'integer',
76 ),
77 ),
78 array(
79 'methods' => WP_REST_Server::READABLE,
80 'callback' => array( $this, 'get_item' ),
81 'permission_callback' => array( $this, 'permissions_check' ),
82 'args' => array(
83 'context' => $this->get_context_param( array( 'default' => 'view' ) ),
84 ),
85 ),
86 array(
87 'methods' => WP_REST_Server::EDITABLE,
88 'callback' => array( $this, 'update_item' ),
89 'permission_callback' => array( $this, 'permissions_check' ),
90 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
91 ),
92 array(
93 'methods' => WP_REST_Server::DELETABLE,
94 'callback' => array( $this, 'delete_item' ),
95 'permission_callback' => array( $this, 'permissions_check' ),
96 ),
97 'schema' => array( $this, 'get_item_schema' ),
98 )
99 );
100 }
101
102 /**
103 * Checks if a given request has access to read campaigns.
104 *
105 * @param \WP_REST_Request $request Full data about the request.
106 * @return bool|\WP_Error
107 * @throws \Exception If the campaign does not exist.
108 */
109 public function permissions_check( $request ) {//phpcs:ignore
110 $permission = current_user_can( 'manage_options' ) || current_user_can( 'manage_woocommerce' ); // phpcs:ignore WordPress.WP.Capabilities.Unknown
111
112 if ( ! $permission ) {
113 return new \WP_Error(
114 'rest_not_found',
115 __( 'Sorry, Permission Denied.', 'disco' ),
116 array( 'status' => 400 )
117 );
118 }
119
120 if ( isset( $request['id'] ) ) {
121 $campaign = $this->get_campaign( absint( $request['id'] ) );
122
123 if ( is_wp_error( $campaign ) ) {
124 return $campaign;
125 }
126 }
127
128 return $permission;
129 }
130
131 /**
132 * Retrieves a list of campaign items.
133 *
134 * @param \WP_REST_Request $request Full data about the request.
135 * @return \WP_REST_Response|\WP_Error
136 * @throws \Exception If the campaign does not exist.
137 */
138 public function get_items( $request ) {
139 $params = $this->get_collection_params();
140 $args = array_intersect_key( $request->get_params(), $params );
141
142 // unset others.
143 unset( $args['per_page'], $args['page'] );
144
145 $data = array();
146 $campaigns = ( new Campaign )->get_campaigns();
147
148 if ( empty( $campaigns ) ) {
149 return new \WP_Error(
150 'rest_campaign_not_available',
151 __( 'No campaign available. Create a campaign first', 'disco' ),
152 array( 'status' => 404 )
153 );
154 }
155
156 /**
157 * Newest first.
158 *
159 * Campaign::get_campaigns() returns rows in insertion order, so the list showed the
160 * oldest campaign at the top. Sorted by id here rather than in the query
161 * or in Campaign::get_rows(): that order is also the order the intents
162 * are evaluated in, and it decides which campaign is credited when two
163 * produce the same discount, so reversing it there would quietly change
164 * attribution on the storefront.
165 */
166 krsort( $campaigns, SORT_NUMERIC );
167
168 foreach ( $campaigns as $campaign ) {
169 $response = $this->prepare_item_for_response( $campaign, $request );
170 $data[] = $this->prepare_response_for_collection( $response );
171 }
172
173 $total = count( $campaigns );
174 $response = rest_ensure_response( $data );
175
176 $response->header( 'X-WP-Total', (int) $total );
177 $response->header( 'X-WP-TotalPages', (int) $total );
178
179 return $response;
180 }
181
182 /**
183 * Retrieves one item from the collection.
184 *
185 * @param \WP_REST_Request $request Full data about the request.
186 * @return \WP_Error|\WP_REST_Response
187 */
188 public function get_item( $request ) {
189 $campaign = $this->get_campaign( absint( $request['id'] ) );
190
191 if ( is_wp_error( $campaign ) ) {
192 return $campaign;
193 }
194
195 $response = $this->prepare_item_for_response( $campaign, $request );
196
197 return rest_ensure_response( $response );
198 }
199
200 /**
201 * Creates one item from the collection.
202 *
203 * @param \WP_REST_Request $request Full data about the request.
204 * @return \WP_Error|\WP_REST_Response
205 * @throws \Exception If the campaign does not exist.
206 */
207 public function create_item( $request ) {
208 $config = (array) $this->prepare_item_for_database( $request );
209
210 if ( empty( $config ) ) {
211 return new \WP_Error(
212 'rest_not_added',
213 __( 'Sorry, the campaign could not be created with empty value.', 'disco' ),
214 array( 'status' => 400 )
215 );
216 }
217
218 $campaign = ( new Campaign )->save_campaign( $config );
219
220 if ( is_wp_error( $campaign ) ) {
221 $campaign->add_data( array( 'status' => 400 ) );
222
223 return $campaign;
224 }
225
226 $response = $this->prepare_item_for_response( $campaign, $request );
227
228 $response->set_status( 201 );
229 $campaign_id = 0;
230
231 if ( isset( $campaign->id ) ) {
232 $campaign_id = $campaign->id;
233 }
234
235 $response->header( 'Location', rest_url( sprintf( '%s/%s/%d', $this->namespace, $this->rest_base, $campaign_id ) ) );
236
237 return rest_ensure_response( $response );
238 }
239
240 /**
241 * Updates one item from the collection.
242 *
243 * @param \WP_REST_Request $request Full data about the request.
244 * @return \WP_Error|\WP_REST_Response
245 * @throws \Exception If the campaign does not exist.
246 */
247 public function update_item( $request ) {
248 $campaign = $this->get_campaign( absint( $request['id'] ) );
249
250 if ( is_wp_error( $campaign ) ) {
251 return $campaign;
252 }
253
254 $prepared = (array) $this->prepare_item_for_database( $request );
255
256 if ( $campaign instanceof Config && method_exists( $campaign, 'get_config' ) ) {
257 $config = $campaign->get_config();
258 $prepared = array_merge( $config, $prepared );
259 }
260
261 $updated = ( new Campaign )->update_campaign( absint( $request['id'] ), $prepared );
262
263 if ( ! $updated ) {
264 return new \WP_Error(
265 'rest_not_updated',
266 __( 'Sorry, the campaign could not be updated.', 'disco' ),
267 array( 'status' => 400 )
268 );
269 }
270
271 $campaign = $this->get_campaign( absint( $request['id'] ) );
272
273 $response = $this->prepare_item_for_response( $campaign, $request );
274
275 return rest_ensure_response( $response );
276 }
277
278 /**
279 * Deletes one item from the collection.
280 *
281 * @param \WP_REST_Request $request Full data about the request.
282 * @return \WP_REST_Response|\WP_Error
283 * @throws \Exception If the campaign does not exist.
284 */
285 public function delete_item( $request ) {
286 $campaign = $this->get_campaign( absint( $request['id'] ) );
287
288 if ( is_wp_error( $campaign ) ) {
289 return $campaign;
290 }
291
292 $previous = $this->prepare_item_for_response( $campaign, $request );
293
294 $deleted = ( new Campaign )->delete_campaign( absint( $request['id'] ) );
295
296 if ( ! $deleted ) {
297 return new \WP_Error(
298 'rest_not_deleted',
299 __( 'Sorry, the campaign could not be deleted.', 'disco' ),
300 array( 'status' => 400 )
301 );
302 }
303
304 $data = array(
305 'deleted' => true,
306 'previous' => $previous->get_data(),
307 );
308
309 return rest_ensure_response( $data );
310 }
311
312 /**
313 * Prepares the item for the REST response.
314 *
315 * @param object $item WordPress's representation of the item.
316 * @param \WP_REST_Request $request Full data about the request.
317 * @return \WP_Error|\WP_HTTP_Response|\WP_REST_Response
318 */
319 public function prepare_item_for_response( $item, $request ) {//phpcs:ignore
320
321 $data = array();
322 $fields = $this->get_fields_for_response( $request );
323 $data['id'] = 0;
324
325 if ( ! empty( $item->id ) && in_array( 'id', $fields, true ) ) {
326 $data['id'] = $item->id;
327 }
328
329 $data['name'] = '';
330
331 if ( ! empty( $item->name ) && in_array( 'name', $fields, true ) ) {
332 $data['name'] = $item->name;
333 }
334
335 $data['priority'] = '1';
336
337 if ( ! empty( $item->priority ) && in_array( 'priority', $fields, true ) ) {
338 $data['priority'] = $item->priority;
339 }
340
341 $data['status'] = '1';
342
343 if ( isset( $item->status ) && in_array( 'status', $fields, true ) ) {
344 $data['status'] = $item->status;
345 }
346
347 $data['discount_intent'] = '';
348
349 if ( ! empty( $item->discount_intent ) && in_array( 'discount_intent', $fields, true ) ) {
350 $data['discount_intent'] = $item->discount_intent;
351 }
352
353 $data['products'] = array();
354
355 if ( ! empty( $item->products ) && in_array( 'products', $fields, true ) ) {
356 $data['products'] = (array) $item->products;
357 }
358
359 $data['conditions'] = array();
360
361 if ( ! empty( $item->conditions ) && in_array( 'conditions', $fields, true ) ) {
362 $data['conditions'] = $item->conditions;
363 }
364
365 $data['discount_rules'] = array();
366
367 if ( ! empty( $item->discount_rules ) && in_array( 'discount_rules', $fields, true ) ) {
368 $data['discount_rules'] = $item->discount_rules;
369 }
370
371 $data['created_by'] = '';
372
373 if ( ! empty( $item->created_by ) && in_array( 'created_by', $fields, true ) ) {
374 $data['created_by'] = $item->created_by;
375 }
376
377 $data['created_date'] = '';
378
379 if ( ! empty( $item->created_date ) && in_array( 'created_date', $fields, true ) ) {
380 $created_date = gmdate( DATE_W3C, strtotime( $item->created_date ) );
381
382 $data['created_date'] = $created_date;
383 }
384
385 $data['modified_by'] = '';
386
387 if ( ! empty( $item->modified_by ) && in_array( 'modified_by', $fields, true ) ) {
388 $data['modified_by'] = $item->modified_by;
389 }
390
391 $data['modified_date'] = '';
392
393 if ( ! empty( $item->modified_date ) && in_array( 'modified_date', $fields, true ) ) {
394 $modified_date = gmdate( DATE_W3C, strtotime( $item->modified_date ) );
395
396 $data['modified_date'] = $modified_date;
397 }
398
399 $data['discount_valid_from'] = '';
400
401 if ( ! empty( $item->discount_valid_from ) && in_array( 'discount_valid_from', $fields, true ) ) {
402 $discount_valid_from = gmdate( DATE_W3C, strtotime( $item->discount_valid_from ) );
403
404 $data['discount_valid_from'] = $discount_valid_from;
405 }
406
407 $data['discount_valid_to'] = '';
408
409 if ( ! empty( $item->discount_valid_to ) && in_array( 'discount_valid_to', $fields, true ) ) {
410 $discount_valid_to = gmdate( DATE_W3C, strtotime( $item->discount_valid_to ) );
411
412 $data['discount_valid_to'] = $discount_valid_to;
413 }
414
415 $data['discount_method'] = '';
416
417 if ( ! empty( $item->discount_method ) && in_array( 'discount_method', $fields, true ) ) {
418 $data['discount_method'] = $item->discount_method;
419 }
420
421 $data['discount_coupon'] = '';
422
423 if ( ! empty( $item->discount_coupon ) && in_array( 'discount_coupon', $fields, true ) ) {
424 $data['discount_coupon'] = $item->discount_coupon;
425 }
426
427 $data['discount_label'] = '';
428
429 if ( ! empty( $item->discount_label ) && in_array( 'discount_label', $fields, true ) ) {
430 $data['discount_label'] = $item->discount_label;
431 }
432
433 $data['discount_max_user'] = '';
434
435 if ( ! empty( $item->discount_max_user ) && in_array( 'discount_max_user', $fields, true ) ) {
436 $data['discount_max_user'] = $item->discount_max_user;
437 }
438
439 $data['discount_based_on'] = '';
440
441 if ( ! empty( $item->discount_based_on ) && in_array( 'discount_based_on', $fields, true ) ) {
442 $data['discount_based_on'] = $item->discount_based_on;
443 }
444
445 $data['bogo_type'] = '';
446
447 if ( ! empty( $item->bogo_type ) && in_array( 'bogo_type', $fields, true ) ) {
448 $data['bogo_type'] = $item->bogo_type;
449 }
450
451 $data['count_quantity_as'] = 'separate';
452
453 if ( in_array( 'count_quantity_as', $fields, true ) && $item instanceof \Disco\App\Utility\Config ) {
454 $data['count_quantity_as'] = $item->get_count_quantity_as();
455 }
456
457 $data['free_item_selection'] = 'cart_order';
458
459 if ( in_array( 'free_item_selection', $fields, true ) && $item instanceof \Disco\App\Utility\Config ) {
460 $data['free_item_selection'] = $item->get_free_item_selection();
461 }
462
463 $data['ui'] = array();
464
465 if ( ! empty( $item->ui ) && in_array( 'ui', $fields, true ) ) {
466 $data['ui'] = $item->ui;
467 }
468
469 // $data['design_blocks'] = array();
470
471 if ( ! empty( $item->design_blocks ) && in_array( 'design_blocks', $fields, true ) ) {
472 $data['design_blocks'] = $item->design_blocks;
473 }
474
475 $context = ! empty( $request['context'] ) && is_string( $request['context'] ) ? $request['context'] : 'view';//phpcs:ignore
476
477 $data = $this->filter_response_by_context( $data, $context );
478
479 $response = rest_ensure_response( $data );
480 $response->add_links( $this->prepare_links( $item ) );
481
482 return $response;
483 }
484
485 /**
486 * Retrieves the campaign schema, conforming to JSON Schema.
487 *
488 * @return array
489 * @throws \Exception If the campaign does not exist.
490 */
491 public function get_item_schema() {//phpcs:ignore
492 $schema = array(
493 '$schema' => 'http://json-schema.org/draft-04/schema#',
494 'title' => 'campaign',
495 'type' => 'object',
496 'properties' => array(
497 'id' => array(
498 'description' => __( 'Unique identifier for the campaign.', 'disco' ),
499 'type' => 'integer',
500 'context' => array( 'view', 'edit' ),
501 'readonly' => true,
502 ),
503 'name' => array(
504 'description' => __( 'Name of the campaign.', 'disco' ),
505 'type' => 'string',
506 'context' => array( 'view', 'edit' ),
507 'required' => true,
508 'arg_options' => array(
509 'sanitize_callback' => 'sanitize_text_field',
510 ),
511 ),
512 'priority' => array(
513 'description' => __( 'Campaign Priority.', 'disco' ),
514 'type' => 'string',
515 'required' => true,
516 'context' => array( 'view', 'edit' ),
517 'arg_options' => array(
518 'sanitize_callback' => 'sanitize_text_field',
519 ),
520 ),
521 'status' => array(
522 'description' => __( 'Campaign Status.', 'disco' ),
523 'type' => 'string',
524 'required' => true,
525 'context' => array( 'view', 'edit' ),
526 'arg_options' => array(
527 'sanitize_callback' => 'sanitize_text_field',
528 ),
529 ),
530 'products' => array(
531 'description' => __( 'Discount applicable products.', 'disco' ),
532 'type' => 'array',
533 'required' => true,
534 'context' => array( 'view', 'edit' ),
535 'arg_options' => array(
536 'sanitize_callback' => 'rest_sanitize_array',
537 ),
538 ),
539 'conditions' => array(
540 'description' => __( 'Conditions to match before get the discount.', 'disco' ),
541 'type' => 'array',
542 'context' => array( 'view', 'edit' ),
543 'arg_options' => array(
544 'sanitize_callback' => 'rest_sanitize_array',
545 ),
546 ),
547 'discount_intent' => array(
548 'description' => __( 'Discount Intention.', 'disco' ),
549 'type' => 'string',
550 'required' => true,
551 'context' => array( 'view', 'edit' ),
552 'arg_options' => array(
553 'sanitize_callback' => 'sanitize_text_field',
554 ),
555 ),
556 'discount_rules' => array(
557 'description' => __( 'Discount Rules.', 'disco' ),
558 'type' => 'array',
559 'context' => array( 'view', 'edit' ),
560 'arg_options' => array(
561 'sanitize_callback' => 'rest_sanitize_array',
562 ),
563 ),
564 'discount_based_on' => array(
565 'description' => __( 'Discount based on', 'disco' ),
566 'type' => 'string',
567 'context' => array( 'view', 'edit' ),
568 'arg_options' => array(
569 'sanitize_callback' => 'sanitize_text_field',
570 ),
571 ),
572 'discount_max_user' => array(
573 'description' => __( 'Maximum Discount Users', 'disco' ),
574 'type' => 'string',
575 'context' => array( 'view', 'edit' ),
576 'arg_options' => array(
577 'sanitize_callback' => 'sanitize_text_field',
578 ),
579 ),
580 'bogo_type' => array(
581 'description' => __( 'BOGO Type', 'disco' ),
582 'type' => 'string',
583 'context' => array( 'view', 'edit' ),
584 'arg_options' => array(
585 'sanitize_callback' => 'sanitize_text_field',
586 ),
587 ),
588 'count_quantity_as' => array(
589 'description' => __( 'How item quantities aggregate toward the tier: separate, variations, filters.', 'disco' ),
590 'type' => 'string',
591 'context' => array( 'view', 'edit' ),
592 'arg_options' => array(
593 'sanitize_callback' => 'sanitize_text_field',
594 ),
595 ),
596 'free_item_selection' => array(
597 'description' => __( 'BOGO free item selection: cart_order, lowest, highest.', 'disco' ),
598 'type' => 'string',
599 'context' => array( 'view', 'edit' ),
600 'arg_options' => array(
601 'sanitize_callback' => 'sanitize_text_field',
602 ),
603 ),
604 'discount_valid_from' => array(
605 'description' => __( 'Discount Start Date.', 'disco' ),
606 'type' => 'date-time',
607 'context' => array( 'view', 'edit' ),
608 'arg_options' => array(
609 'sanitize_callback' => 'sanitize_text_field',
610 ),
611 ),
612 'discount_valid_to' => array(
613 'description' => __( 'Discount End Date.', 'disco' ),
614 'type' => 'date-time',
615 'context' => array( 'view', 'edit' ),
616 'arg_options' => array(
617 'sanitize_callback' => 'sanitize_text_field',
618 ),
619 ),
620 'discount_method' => array(
621 'description' => __( 'Discount Method: automated or coupon.', 'disco' ),
622 'type' => 'string',
623 'required' => true,
624 'context' => array( 'view', 'edit' ),
625 'arg_options' => array(
626 'sanitize_callback' => 'sanitize_text_field',
627 ),
628 ),
629 'discount_coupon' => array(
630 'description' => __( 'Discount coupon code.', 'disco' ),
631 'type' => 'string',
632 'context' => array( 'view', 'edit' ),
633 'arg_options' => array(
634 'sanitize_callback' => 'sanitize_text_field',
635 ),
636 ),
637 'created_by' => array(
638 'description' => __( 'Created by User ID', 'disco' ),
639 'type' => 'string',
640 'context' => array( 'view', 'edit' ),
641 'arg_options' => array(
642 'sanitize_callback' => 'sanitize_text_field',
643 ),
644 ),
645
646 'modified_by' => array(
647 'description' => __( 'Modified by User ID.', 'disco' ),
648 'type' => 'string',
649 'context' => array( 'view', 'edit' ),
650 'arg_options' => array(
651 'sanitize_callback' => 'sanitize_text_field',
652 ),
653 ),
654 'created_date' => array(
655 'description' => __( "The date the object was published, in the site's timezone.", 'disco' ),
656 'type' => 'string',
657 'format' => 'date-time',
658 'context' => array( 'view' ),
659 'readonly' => true,
660 ),
661 'modified_date' => array(
662 'description' => __( "The date the object was published, in the site's timezone.", 'disco' ),
663 'type' => 'string',
664 'format' => 'date-time',
665 'context' => array( 'view' ),
666 'readonly' => true,
667 ),
668 'ui' => array(
669 'description' => __( 'Interface Settings.', 'disco' ),
670 'type' => 'array',
671 'context' => array( 'view' ),
672 'readonly' => true,
673 ),
674 'design_blocks' => array(
675 'description' => __( 'Design Blocks.', 'disco' ),
676 'type' => 'object',
677 'context' => array( 'view', 'edit' ),
678 ),
679
680 ),
681 );
682
683 $this->schema = $schema;
684
685 return $this->add_additional_fields_schema( $this->schema );
686 }
687
688 /**
689 * Validation callback for `discount_intent` parameter.
690 *
691 * @param int|string $value Value of the my-arg parameter.
692 * @param \WP_REST_Request $request Current request object.
693 * @param string $param The name of the parameter in this case, 'my-arg'.
694 * @return \WP_Error|true True, if the data is valid, WP_Error otherwise.
695 * @throws \Exception If the campaign does not exist.
696 */
697 public function validate_schema_properties( $value, $request, $param ) {
698 $attributes = $request->get_attributes();
699
700 // This code won't execute because we have specified this argument as required.
701 // If we reused this validation callback and did not have required args then this would fire.
702 if ( ! isset( $attributes['args'][ $param ] ) ) {
703 return new \WP_Error( 'rest_invalid_param', sprintf( '%s was not registered as a request argument.', $param ), array( 'status' => 400 ) );
704 }
705
706 // Check to make sure our argument in proper type.
707 $argument = $attributes['args'][ $param ];
708
709 if ( gettype( $value ) !== $argument['type'] ) {
710 return new \WP_Error( 'rest_invalid_param', sprintf( '%1$s is not of type %2$s', $param, 'string' ), array( 'status' => 400 ) );
711 }
712
713 // Make sure required arguments are not empty.
714 if ( isset( $argument['required'] ) && true === $argument['required'] && empty( $value ) ) {
715 return new \WP_Error( 'rest_invalid_param_value', sprintf( 'Value for %1$s is required', $param ), array( 'status' => 400 ) );
716 }
717
718 $drop_down_checks = array(
719 'discount_intent' => DiscountDropDown::discount_intents(),
720 'discount_type' => DiscountDropDown::discount_types(),
721 );
722
723 if ( isset( $drop_down_checks[ $param ] ) && ! array_key_exists( $value, $drop_down_checks[ $param ] ) ) {
724 return new \WP_Error( 'rest_invalid_param_value', sprintf( 'Value for %1$s is not valid', $param ), array( 'status' => 400 ) );
725 }
726
727 return true;
728 }
729
730 /**
731 * Retrieves the query params for collections.
732 *
733 * @return array
734 */
735 public function get_collection_params() {
736 $params = parent::get_collection_params();
737 unset( $params['search'] );
738
739 return $params;
740 }
741
742 /**
743 * Get the campaign if the ID is valid.
744 *
745 * @param int $id Supplied ID.
746 * @return Object|\WP_Error
747 */
748 protected function get_campaign( $id ) {
749 return ( new Campaign )->get_campaign( $id );
750 }
751
752 /**
753 * Prepares one item for create or update operation.
754 *
755 * @param \WP_REST_Request $request Full data about the request.
756 * @return object
757 */
758 protected function prepare_item_for_database( $request ) {
759 $valid_keys = array(
760 'name',
761 'discount_intent',
762 'priority',
763 'ui',
764 'status',
765 'products',
766 'conditions',
767 'discount_rules',
768 'discount_label',
769 'discount_valid_from',
770 'discount_max_user',
771 'discount_based_on',
772 'bogo_type',
773 'count_quantity_as',
774 'free_item_selection',
775 'discount_valid_to',
776 'discount_method',
777 'discount_coupon',
778 'design_blocks',
779 );
780
781 $prepared = array();
782
783 foreach ( $valid_keys as $key ) {
784 if ( ! isset( $request[ $key ] ) ) {
785 continue;
786 }
787
788 $prepared[ $key ] = $request[ $key ];
789 }
790
791 return (object) $prepared;
792 }
793
794 /**
795 * Prepares links for the request.
796 *
797 * @param object $item Item object.
798 * @return array Links for the given post.
799 */
800 protected function prepare_links( $item ) {
801 $id = 0;
802
803 if ( isset( $item->id ) ) {
804 $id = $item->id;
805 }
806
807 $base = sprintf( '%s/%s', $this->namespace, $this->rest_base );
808
809 return array(
810 'self' => array(
811 'href' => rest_url( trailingslashit( $base ) . $id ),
812 ),
813 'collection' => array(
814 'href' => rest_url( $base ),
815 ),
816 );
817 }
818
819 }
820