PluginProbe
Subscriptions for WooCommerce with Stripe Recurring Payments / 2.3.0
Subscriptions for WooCommerce with Stripe Recurring Payments v2.3.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 +165 -0 2.0.0 → 2.3.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,
@@ -171,8 +195,20 @@
171 195 );
172 196
173 197 register_rest_route(
174 198 self::NS,
199 + '/plans/product-user-cancel/(?P<id>\d+)',
200 + array(
201 + array(
202 + 'methods' => WP_REST_Server::EDITABLE,
203 + 'callback' => array( $this, 'save_product_user_cancel' ),
204 + 'permission_callback' => $perm,
205 + ),
206 + )
207 + );
208 +
209 + register_rest_route(
210 + self::NS,
175 211 '/plans/group-products/(?P<id>\d+)',
176 212 array(
177 213 array(
178 214 'methods' => WP_REST_Server::READABLE,
@@ -364,8 +400,44 @@
364 400 return rest_ensure_response( PlanRepository::get_group_tree( $id ) );
365 401 }
366 402
367 403 /**
404 + * PUT /plans/groups/{id}/order - save the admin display order of the
405 + * group's durations and/or products (drag-and-drop on the detail page).
406 + *
407 + * Stored in the group's `data` JSON as `term_order` / `product_order`
408 + * (lists of ids), merged so the rest of `data` is left as it was.
409 + *
410 + * @param WP_REST_Request $request Request.
411 + *
412 + * @return \WP_REST_Response|WP_Error
413 + */
414 + public function update_group_order( WP_REST_Request $request ) {
415 + $id = (int) $request['id'];
416 + $group = PlanRepository::get_group( $id );
417 +
418 + if ( ! $group ) {
419 + return $this->not_found();
420 + }
421 +
422 + $params = $this->read_params( $request );
423 + $data = is_array( $group['data'] ) ? $group['data'] : array();
424 +
425 + foreach ( array(
426 + 'terms' => 'term_order',
427 + 'products' => 'product_order',
428 + ) as $param => $key ) {
429 + if ( isset( $params[ $param ] ) && is_array( $params[ $param ] ) ) {
430 + $data[ $key ] = array_values( array_unique( array_filter( array_map( 'absint', $params[ $param ] ) ) ) );
431 + }
432 + }
433 +
434 + PlanRepository::update_group( $id, array( 'data' => $data ) );
435 +
436 + return rest_ensure_response( array( 'success' => true ) );
437 + }
438 +
439 + /**
368 440 * DELETE /plans/groups/{id} - delete group + cascade.
369 441 *
370 442 * @param WP_REST_Request $request Request.
371 443 *
@@ -583,8 +655,101 @@
583 655 'deleted' => true,
584 656 'id' => $id,
585 657 )
586 658 );
659 + }
660 +
661 + /**
662 + * PUT /plans/product-user-cancel/{id} - save whether customers may cancel.
663 + *
664 + * Writes the same `_subscrpt_user_cancel` meta the product editor saves, as
665 + * an explicit "yes" / "no", which checkout copies onto each new subscription.
666 + *
667 + * Body: { enabled: bool }.
668 + *
669 + * @param WP_REST_Request $request Request.
670 + *
671 + * @return \WP_REST_Response|WP_Error
672 + */
673 + public function save_product_user_cancel( WP_REST_Request $request ) {
674 + $product = function_exists( 'wc_get_product' ) ? wc_get_product( (int) $request['id'] ) : null;
675 +
676 + if ( ! $product ) {
677 + return $this->not_found();
678 + }
679 +
680 + $params = $this->read_params( $request );
681 + $product->update_meta_data( '_subscrpt_user_cancel', empty( $params['enabled'] ) ? 'no' : 'yes' );
682 + $product->save();
683 +
684 + return rest_ensure_response( array( 'saved' => true ) );
685 + }
686 +
687 + /**
688 + * POST /plans/bulk-price - set one price on many product/duration relations.
689 + *
690 + * Upserts the regular (and optional sale) price onto the existing relations
691 + * for each selected product across each selected duration. Only relations
692 + * that already exist are touched, so bulk pricing never attaches a product to
693 + * a term it was not already on. Free is simple-only: variation targets
694 + * (vid != 0) are skipped unless Pro is active.
695 + *
696 + * Body: { plan_ids: int[], products: [{ oid, vid }], regular_price, sale_price? }.
697 + *
698 + * @param WP_REST_Request $request Request.
699 + *
700 + * @return \WP_REST_Response|WP_Error
701 + */
702 + public function bulk_price( WP_REST_Request $request ) {
703 + $params = $this->read_params( $request );
704 +
705 + $plan_ids = isset( $params['plan_ids'] ) && is_array( $params['plan_ids'] ) ? array_filter( array_map( 'absint', $params['plan_ids'] ) ) : [];
706 + $products = isset( $params['products'] ) && is_array( $params['products'] ) ? $params['products'] : [];
707 +
708 + if ( empty( $plan_ids ) ) {
709 + return new WP_Error( 'subscrpt_bulk_no_terms', __( 'Select at least one duration.', 'subscription' ), [ 'status' => 400 ] );
710 + }
711 +
712 + if ( empty( $products ) ) {
713 + return new WP_Error( 'subscrpt_bulk_no_products', __( 'Select at least one product.', 'subscription' ), [ 'status' => 400 ] );
714 + }
715 +
716 + if ( ! isset( $params['regular_price'] ) || '' === $params['regular_price'] ) {
717 + return new WP_Error( 'subscrpt_bulk_no_price', __( 'Enter a regular price.', 'subscription' ), [ 'status' => 400 ] );
718 + }
719 +
720 + $data = [
721 + 'regular_price' => (string) wc_format_decimal( $params['regular_price'] ),
722 + 'sale_price' => isset( $params['sale_price'] ) && '' !== $params['sale_price'] ? (string) wc_format_decimal( $params['sale_price'] ) : '',
723 + ];
724 +
725 + $updated = 0;
726 +
727 + foreach ( $products as $product ) {
728 + $oid = isset( $product['oid'] ) ? absint( $product['oid'] ) : 0;
729 + $vid = isset( $product['vid'] ) ? absint( $product['vid'] ) : 0;
730 +
731 + if ( ! $oid ) {
732 + continue;
733 + }
734 +
735 + if ( is_wp_error( $this->guard_simple_only( [ 'vid' => $vid ] ) ) ) {
736 + continue;
737 + }
738 +
739 + foreach ( $plan_ids as $plan_id ) {
740 + $relation_id = PlanRepository::find_relation( $plan_id, $oid, $vid );
741 +
742 + if ( ! $relation_id ) {
743 + continue;
744 + }
745 +
746 + PlanRepository::update_relation( $relation_id, [ 'data' => $data ] );
747 + ++$updated;
748 + }
749 + }
750 +
751 + return rest_ensure_response( [ 'updated' => $updated ] );
587 752 }
588 753
589 754 /**
590 755 * PUT /plans/product-onetime/{id} - save a product's one-time purchase.