PluginProbe
Subscriptions for WooCommerce with Stripe Recurring Payments / 2.2.0
Subscriptions for WooCommerce with Stripe Recurring Payments v2.2.0
2.4.0 2.3.0 2.2.0 2.1.0 2.0.0 1.11.2 1.11.1 1.11.0 1.10.9 1.10.8 1.10.7 1.10.6 1.10.5 1.10.4 1.10.3 1.10.2 1.10.1 1.10.0 1.9.6 1.9.5 trunk 1.3.0 1.3.1 1.3.2 1.4.0 All 65 releases
← All changes | includes/Api/PlanController.php +127 -0 2.0.0 → 2.2.0 View file →
@@ -84,8 +84,20 @@
84 84 );
85 85
86 86 register_rest_route(
87 87 self::NS,
88 + '/plans/groups/(?P<id>\d+)/order',
89 + array(
90 + array(
91 + 'methods' => WP_REST_Server::EDITABLE,
92 + 'callback' => array( $this, 'update_group_order' ),
93 + 'permission_callback' => $perm,
94 + ),
95 + )
96 + );
97 +
98 + register_rest_route(
99 + self::NS,
88 100 '/plans/terms',
89 101 array(
90 102 array(
91 103 'methods' => WP_REST_Server::CREATABLE,
@@ -147,8 +159,20 @@
147 159 );
148 160
149 161 register_rest_route(
150 162 self::NS,
163 + '/plans/bulk-price',
164 + [
165 + [
166 + 'methods' => WP_REST_Server::CREATABLE,
167 + 'callback' => [ $this, 'bulk_price' ],
168 + 'permission_callback' => $perm,
169 + ],
170 + ]
171 + );
172 +
173 + register_rest_route(
174 + self::NS,
151 175 '/plans/products',
152 176 array(
153 177 array(
154 178 'methods' => WP_REST_Server::READABLE,
@@ -364,8 +388,44 @@
364 388 return rest_ensure_response( PlanRepository::get_group_tree( $id ) );
365 389 }
366 390
367 391 /**
392 + * PUT /plans/groups/{id}/order - save the admin display order of the
393 + * group's durations and/or products (drag-and-drop on the detail page).
394 + *
395 + * Stored in the group's `data` JSON as `term_order` / `product_order`
396 + * (lists of ids), merged so the rest of `data` is left as it was.
397 + *
398 + * @param WP_REST_Request $request Request.
399 + *
400 + * @return \WP_REST_Response|WP_Error
401 + */
402 + public function update_group_order( WP_REST_Request $request ) {
403 + $id = (int) $request['id'];
404 + $group = PlanRepository::get_group( $id );
405 +
406 + if ( ! $group ) {
407 + return $this->not_found();
408 + }
409 +
410 + $params = $this->read_params( $request );
411 + $data = is_array( $group['data'] ) ? $group['data'] : array();
412 +
413 + foreach ( array(
414 + 'terms' => 'term_order',
415 + 'products' => 'product_order',
416 + ) as $param => $key ) {
417 + if ( isset( $params[ $param ] ) && is_array( $params[ $param ] ) ) {
418 + $data[ $key ] = array_values( array_unique( array_filter( array_map( 'absint', $params[ $param ] ) ) ) );
419 + }
420 + }
421 +
422 + PlanRepository::update_group( $id, array( 'data' => $data ) );
423 +
424 + return rest_ensure_response( array( 'success' => true ) );
425 + }
426 +
427 + /**
368 428 * DELETE /plans/groups/{id} - delete group + cascade.
369 429 *
370 430 * @param WP_REST_Request $request Request.
371 431 *
@@ -583,8 +643,75 @@
583 643 'deleted' => true,
584 644 'id' => $id,
585 645 )
586 646 );
647 + }
648 +
649 + /**
650 + * POST /plans/bulk-price - set one price on many product/duration relations.
651 + *
652 + * Upserts the regular (and optional sale) price onto the existing relations
653 + * for each selected product across each selected duration. Only relations
654 + * that already exist are touched, so bulk pricing never attaches a product to
655 + * a term it was not already on. Free is simple-only: variation targets
656 + * (vid != 0) are skipped unless Pro is active.
657 + *
658 + * Body: { plan_ids: int[], products: [{ oid, vid }], regular_price, sale_price? }.
659 + *
660 + * @param WP_REST_Request $request Request.
661 + *
662 + * @return \WP_REST_Response|WP_Error
663 + */
664 + public function bulk_price( WP_REST_Request $request ) {
665 + $params = $this->read_params( $request );
666 +
667 + $plan_ids = isset( $params['plan_ids'] ) && is_array( $params['plan_ids'] ) ? array_filter( array_map( 'absint', $params['plan_ids'] ) ) : [];
668 + $products = isset( $params['products'] ) && is_array( $params['products'] ) ? $params['products'] : [];
669 +
670 + if ( empty( $plan_ids ) ) {
671 + return new WP_Error( 'subscrpt_bulk_no_terms', __( 'Select at least one duration.', 'subscription' ), [ 'status' => 400 ] );
672 + }
673 +
674 + if ( empty( $products ) ) {
675 + return new WP_Error( 'subscrpt_bulk_no_products', __( 'Select at least one product.', 'subscription' ), [ 'status' => 400 ] );
676 + }
677 +
678 + if ( ! isset( $params['regular_price'] ) || '' === $params['regular_price'] ) {
679 + return new WP_Error( 'subscrpt_bulk_no_price', __( 'Enter a regular price.', 'subscription' ), [ 'status' => 400 ] );
680 + }
681 +
682 + $data = [
683 + 'regular_price' => (string) wc_format_decimal( $params['regular_price'] ),
684 + 'sale_price' => isset( $params['sale_price'] ) && '' !== $params['sale_price'] ? (string) wc_format_decimal( $params['sale_price'] ) : '',
685 + ];
686 +
687 + $updated = 0;
688 +
689 + foreach ( $products as $product ) {
690 + $oid = isset( $product['oid'] ) ? absint( $product['oid'] ) : 0;
691 + $vid = isset( $product['vid'] ) ? absint( $product['vid'] ) : 0;
692 +
693 + if ( ! $oid ) {
694 + continue;
695 + }
696 +
697 + if ( is_wp_error( $this->guard_simple_only( [ 'vid' => $vid ] ) ) ) {
698 + continue;
699 + }
700 +
701 + foreach ( $plan_ids as $plan_id ) {
702 + $relation_id = PlanRepository::find_relation( $plan_id, $oid, $vid );
703 +
704 + if ( ! $relation_id ) {
705 + continue;
706 + }
707 +
708 + PlanRepository::update_relation( $relation_id, [ 'data' => $data ] );
709 + ++$updated;
710 + }
711 + }
712 +
713 + return rest_ensure_response( [ 'updated' => $updated ] );
587 714 }
588 715
589 716 /**
590 717 * PUT /plans/product-onetime/{id} - save a product's one-time purchase.