PluginProbe
Subscriptions for WooCommerce with Stripe Recurring Payments / 2.4.0
Subscriptions for WooCommerce with Stripe Recurring Payments v2.4.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/Illuminate/Helper.php +63 -11 1.11.0 → 2.4.0 View file →
@@ -1,5 +1,10 @@
1 1 <?php
2 +/**
3 + * Subscription helper utilities.
4 + *
5 + * @package SpringDevs\Subscription\Illuminate
6 + */
2 7
3 8 namespace SpringDevs\Subscription\Illuminate;
4 9
5 10 use SpringDevs\Subscription\Illuminate\Gateways\Stripe\Stripe;
@@ -59,15 +64,18 @@
59 64 * Get verbose status from status slug.
60 65 *
61 66 * @param string $status Status.
62 67 * @param bool $return_all Whether to return all statuses or a single status.
68 + *
69 + * @return string|array Verbose status label, or the full status map when $return_all is true.
63 70 */
64 - public static function get_verbose_status( $status, $return_all = false ): string|array {
71 + public static function get_verbose_status( $status, $return_all = false ) {
65 72 $statuses = array(
66 73 'pending' => __( 'Pending', 'subscription' ),
67 74 'active' => __( 'Active', 'subscription' ),
68 75 'on-hold' => __( 'On Hold', 'subscription' ),
69 76 'expired' => __( 'Expired', 'subscription' ),
77 + 'completed' => __( 'Completed', 'subscription' ),
70 78 'pe_cancelled' => __( 'Pending Cancellation', 'subscription' ),
71 79 'cancelled' => __( 'Cancelled', 'subscription' ),
72 80 'draft' => __( 'Draft', 'subscription' ),
73 81 'trash' => __( 'Trash', 'subscription' ),
@@ -81,8 +89,22 @@
81 89 return isset( $statuses[ $status ] ) ? $statuses[ $status ] : '';
82 90 }
83 91
84 92 /**
93 + * Whether a subscription in this status still has a payment ahead.
94 + *
95 + * Cancelling or expiring keeps `_subscrpt_next_date` (the cancellation sweep
96 + * and reactivation read it), so views check the status before showing it.
97 + *
98 + * @param string $status Status.
99 + *
100 + * @return bool
101 + */
102 + public static function has_next_payment( $status ) {
103 + return ! in_array( $status, array( 'cancelled', 'expired' ), true );
104 + }
105 +
106 + /**
85 107 * Generate start date
86 108 *
87 109 * @param null|string $trial Trial.
88 110 *
@@ -495,12 +517,16 @@
495 517
496 518 // Allow modification of split payment arguments
497 519 $split_payment_args = apply_filters( 'subscrpt_split_payment_args', $split_payment_args, $order_item, $product );
498 520
521 + // Own the subscription from the order's customer, not the current user.
522 + $parent_order = wc_get_order( $order_item->get_order_id() );
523 +
499 524 $args = array(
500 525 'post_title' => 'Subscription',
501 526 'post_type' => 'subscrpt_order',
502 527 'post_status' => $split_payment_args['post_status'],
528 + 'post_author' => $parent_order ? (int) $parent_order->get_customer_id() : get_current_user_id(),
503 529 );
504 530 $subscription_id = wp_insert_post( $args );
505 531 wp_update_post(
506 532 array(
@@ -508,9 +534,10 @@
508 534 'post_title' => "Subscription #{$subscription_id}",
509 535 )
510 536 );
511 537 // Check if this is a split payment subscription
512 - $payment_type = $product->get_meta( '_subscrpt_payment_type' ) ?: 'recurring';
538 + $payment_type = $product->get_meta( '_subscrpt_payment_type' );
539 + $payment_type = $payment_type ? $payment_type : 'recurring';
513 540 $max_payments = $product->get_meta( '_subscrpt_max_no_payment' );
514 541
515 542 $comment_content = '';
516 543 $activity_type = '';
@@ -973,10 +1000,13 @@
973 1000 foreach ( $cart_items as $key => $cart_item ) {
974 1001 $product = $cart_item['data'];
975 1002 if ( $product->is_type( 'simple' ) && isset( $cart_item['subscription'] ) ) {
976 1003 $cart_subscription = $cart_item['subscription'];
977 - $type = ucfirst( $cart_subscription['type'] );
978 - $price_data = self::build_cart_recurring_price_data( $cart_item, $key, $type );
1004 + // Cadence word must respect the frequency (plan items store the raw
1005 + // plural interval, e.g. "months"): singular for 1, plural + count above.
1006 + $sub_time = max( 1, (int) ( $cart_subscription['time'] ?? 1 ) );
1007 + $type = ( 1 === $sub_time ? '' : $sub_time . ' ' ) . ucfirst( self::get_typos( $sub_time, $cart_subscription['type'] ) );
1008 + $price_data = self::build_cart_recurring_price_data( $cart_item, $key, $type );
979 1009
980 1010 $recurrs[ $key ] = array_merge(
981 1011 $price_data,
982 1012 array(
@@ -982,10 +1012,15 @@
982 1012 array(
983 1013 'trial_status' => ! is_null( $cart_subscription['trial'] ),
984 1014 'start_date' => self::start_date( $cart_subscription['trial'] ),
985 1015 'next_date' => self::next_date( ( $cart_subscription['time'] ?? 1 ) . ' ' . $cart_subscription['type'], $cart_subscription['trial'] ),
986 - 'can_user_cancel' => $cart_item['data']->get_meta( '_subscrpt_user_cancel' ),
987 - 'max_no_payment' => $cart_item['data']->get_meta( '_subscrpt_max_no_payment' ),
1016 + 'can_user_cancel' => self::can_user_cancel( $cart_item['data']->get_meta( '_subscrpt_user_cancel' ) ) ? 'yes' : 'no',
1017 + 'max_no_payment' => ! empty( $cart_item['subscrpt_max_no_payment'] )
1018 + ? (int) $cart_item['subscrpt_max_no_payment']
1019 + : $cart_item['data']->get_meta( '_subscrpt_max_no_payment' ),
1020 + // Exact plan total for split items (the entered price the split is
1021 + // divided from); null for classic split items which have no plan total.
1022 + 'split_total' => isset( $cart_item['subscrpt_split_total'] ) ? (float) $cart_item['subscrpt_split_total'] : null,
988 1023 'quantity' => (int) $cart_item['quantity'],
989 1024 )
990 1025 );
991 1026 }
@@ -1102,11 +1137,13 @@
1102 1137 $new_order->calculate_totals();
1103 1138 $new_order->save();
1104 1139
1105 1140 if ( ! is_admin() && function_exists( 'wc_add_notice' ) && WC()->session ) {
1106 - $message = 'Renewal Order(#' . $new_order->get_id() . ') Created.';
1141 + /* translators: %d: renewal order ID. */
1142 + $message = sprintf( __( 'Renewal order #%d created.', 'subscription' ), $new_order->get_id() );
1107 1143 if ( $new_order->has_status( 'pending' ) ) {
1108 - $message .= 'Please <a href="' . $new_order->get_checkout_payment_url() . '">Pay now</a>';
1144 + /* translators: %s: URL of the order payment page. */
1145 + $message .= ' ' . sprintf( __( 'Please <a href="%s">pay now</a>.', 'subscription' ), esc_url( $new_order->get_checkout_payment_url() ) );
1109 1146 }
1110 1147 wc_add_notice( $message, 'success' );
1111 1148 }
1112 1149
@@ -1358,9 +1395,9 @@
1358 1395
1359 1396 $comment_id = wp_insert_comment(
1360 1397 array(
1361 1398 'comment_author' => 'Subscription for WooCommerce',
1362 - 'comment_content' => sprintf( 'Subscription Renewal order successfully created. order is %s', $new_order_id ),
1399 + 'comment_content' => sprintf( 'Subscription Renewal order successfully created. Order #%s', $new_order_id ),
1363 1400 'comment_post_ID' => $subscription_id,
1364 1401 'comment_type' => 'order_note',
1365 1402 )
1366 1403 );
@@ -1368,8 +1405,22 @@
1368 1405 update_comment_meta( $comment_id, '_subscrpt_activity_type', 'renewal_order' );
1369 1406 }
1370 1407
1371 1408 /**
1409 + * Whether a stored `_subscrpt_user_cancel` value lets the customer cancel.
1410 + *
1411 + * Only an explicit "no" forbids it. An empty value means the option was never
1412 + * saved - plan-connected products never store it - and the product form shows
1413 + * "Yes" for that case, so the answer here has to be yes too.
1414 + *
1415 + * @param mixed $value Stored meta value.
1416 + * @return bool
1417 + */
1418 + public static function can_user_cancel( $value ): bool {
1419 + return 'no' !== $value;
1420 + }
1421 +
1422 + /**
1372 1423 * Get a subscription data.
1373 1424 *
1374 1425 * @param int $subscription_id Subscription ID.
1375 1426 * @return array|null
@@ -1398,9 +1449,9 @@
1398 1449
1399 1450 $order_id = get_post_meta( $subscription_id, '_subscrpt_order_id', true );
1400 1451 $order_item_id = get_post_meta( $subscription_id, '_subscrpt_order_item_id', true );
1401 1452
1402 - $can_user_cancel = in_array( get_post_meta( $subscription_id, '_subscrpt_user_cancel', true ), array( 1, '1', 'true', 'yes' ), true );
1453 + $can_user_cancel = self::can_user_cancel( get_post_meta( $subscription_id, '_subscrpt_user_cancel', true ) );
1403 1454
1404 1455 $start_datetime = (int) get_post_meta( $subscription_id, '_subscrpt_start_date', true );
1405 1456 $start_date = ! empty( $start_datetime ) ? gmdate( DATE_RFC2822, $start_datetime ) : null;
1406 1457
@@ -1459,9 +1510,10 @@
1459 1510 );
1460 1511 }
1461 1512
1462 1513 if (
1463 - ! in_array( strtolower( $status ), array( 'cancelled', 'pending' ), true )
1514 + ! in_array( strtolower( $status ), array( 'cancelled', 'pending', 'completed' ), true )
1515 + && ! empty( $next_date )
1464 1516 && $next_datetime - time() <= 0
1465 1517 && (int) $default_grace_period > 0
1466 1518 ) {
1467 1519 $subscription_data['grace_period'] = array(