コード例 #1
0
 /**
  * Get PayPal Args for passing to PP
  *
  * Based on the HTML Variables documented here: https://developer.paypal.com/webapps/developer/docs/classic/paypal-payments-standard/integration-guide/Appx_websitestandard_htmlvariables/#id08A6HI00JQU
  *
  * @param WC_Order $order
  * @return array
  */
 public static function get_paypal_args($paypal_args, $order)
 {
     $is_payment_change = WC_Subscriptions_Change_Payment_Gateway::$is_request_to_change_payment;
     $order_contains_failed_renewal = false;
     // Payment method changes act on the subscription not the original order
     if ($is_payment_change) {
         $subscriptions = array(wcs_get_subscription($order->id));
         $subscription = array_pop($subscriptions);
         $order = $subscription->order;
         // We need the subscription's total
         remove_filter('woocommerce_order_amount_total', 'WC_Subscriptions_Change_Payment_Gateway::maybe_zero_total', 11, 2);
     } else {
         // Otherwise the order is the $order
         if ($cart_item = wcs_cart_contains_failed_renewal_order_payment() || false !== WC_Subscriptions_Renewal_Order::get_failed_order_replaced_by($order->id)) {
             $subscriptions = wcs_get_subscriptions_for_renewal_order($order);
             $order_contains_failed_renewal = true;
         } else {
             $subscriptions = wcs_get_subscriptions_for_order($order);
         }
         // Only one subscription allowed per order with PayPal
         $subscription = array_pop($subscriptions);
     }
     if ($order_contains_failed_renewal || !empty($subscription) && $subscription->get_total() > 0 && 'yes' !== get_option(WC_Subscriptions_Admin::$option_prefix . '_turn_off_automatic_payments', 'no')) {
         // It's a subscription
         $paypal_args['cmd'] = '_xclick-subscriptions';
         // Store the subscription ID in the args sent to PayPal so we can access them later
         $paypal_args['custom'] = wcs_json_encode(array('order_id' => $order->id, 'order_key' => $order->order_key, 'subscription_id' => $subscription->id, 'subscription_key' => $subscription->order_key));
         foreach ($subscription->get_items() as $item) {
             if ($item['qty'] > 1) {
                 $item_names[] = $item['qty'] . ' x ' . wcs_get_paypal_item_name($item['name']);
             } elseif ($item['qty'] > 0) {
                 $item_names[] = wcs_get_paypal_item_name($item['name']);
             }
         }
         // translators: 1$: subscription ID, 2$: order ID, 3$: names of items, comma separated
         $paypal_args['item_name'] = wcs_get_paypal_item_name(sprintf(_x('Subscription %1$s (Order %2$s) - %3$s', 'item name sent to paypal', 'woocommerce-subscriptions'), $subscription->get_order_number(), $order->get_order_number(), implode(', ', $item_names)));
         $unconverted_periods = array('billing_period' => $subscription->billing_period, 'trial_period' => $subscription->trial_period);
         $converted_periods = array();
         // Convert period strings into PayPay's format
         foreach ($unconverted_periods as $key => $period) {
             switch (strtolower($period)) {
                 case 'day':
                     $converted_periods[$key] = 'D';
                     break;
                 case 'week':
                     $converted_periods[$key] = 'W';
                     break;
                 case 'year':
                     $converted_periods[$key] = 'Y';
                     break;
                 case 'month':
                 default:
                     $converted_periods[$key] = 'M';
                     break;
             }
         }
         $price_per_period = $subscription->get_total();
         $subscription_interval = $subscription->billing_interval;
         $start_timestamp = $subscription->get_time('start');
         $trial_end_timestamp = $subscription->get_time('trial_end');
         $next_payment_timestamp = $subscription->get_time('next_payment');
         $is_synced_subscription = WC_Subscriptions_Synchroniser::subscription_contains_synced_product($subscription->id);
         if ($is_synced_subscription) {
             $length_from_timestamp = $next_payment_timestamp;
         } elseif ($trial_end_timestamp > 0) {
             $length_from_timestamp = $trial_end_timestamp;
         } else {
             $length_from_timestamp = $start_timestamp;
         }
         $subscription_length = wcs_estimate_periods_between($length_from_timestamp, $subscription->get_time('end'), $subscription->billing_period);
         $subscription_installments = $subscription_length / $subscription_interval;
         $initial_payment = $is_payment_change ? 0 : $order->get_total();
         if ($order_contains_failed_renewal || $is_payment_change) {
             if ($is_payment_change) {
                 // Add a nonce to the order ID to avoid "This invoice has already been paid" error when changing payment method to PayPal when it was previously PayPal
                 $suffix = '-wcscpm-' . wp_create_nonce();
             } else {
                 // Failed renewal order, append a descriptor and renewal order's ID
                 $suffix = '-wcsfrp-' . $order->id;
             }
             // Change the 'invoice' and the 'custom' values to be for the original order (if there is one)
             if (false === $subscription->order) {
                 // No original order so we need to use the subscriptions values instead
                 $order_number = ltrim($subscription->get_order_number(), _x('#', 'hash before the order number. Used as a character to remove from the actual order number', 'woocommerce-subscriptions')) . '-subscription';
                 $order_id_key = array('order_id' => $subscription->id, 'order_key' => $subscription->order_key);
             } else {
                 $order_number = ltrim($subscription->order->get_order_number(), _x('#', 'hash before the order number. Used as a character to remove from the actual order number', 'woocommerce-subscriptions'));
                 $order_id_key = array('order_id' => $subscription->order->id, 'order_key' => $subscription->order->order_key);
             }
             $order_details = false !== $subscription->order ? $subscription->order : $subscription;
             // Set the invoice details to the original order's invoice but also append a special string and this renewal orders ID so that we can match it up as a failed renewal order payment later
             $paypal_args['invoice'] = WCS_PayPal::get_option('invoice_prefix') . $order_number . $suffix;
             $paypal_args['custom'] = wcs_json_encode(array_merge($order_id_key, array('subscription_id' => $subscription->id, 'subscription_key' => $subscription->order_key)));
         }
         if ($order_contains_failed_renewal) {
             $subscription_trial_length = 0;
             $subscription_installments = max($subscription_installments - $subscription->get_completed_payment_count(), 0);
             // If we're changing the payment date or switching subs, we need to set the trial period to the next payment date & installments to be the number of installments left
         } elseif ($is_payment_change || $is_synced_subscription) {
             $next_payment_timestamp = $subscription->get_time('next_payment');
             // When the subscription is on hold
             if (false != $next_payment_timestamp && !empty($next_payment_timestamp)) {
                 $trial_until = wcs_calculate_paypal_trial_periods_until($next_payment_timestamp);
                 $subscription_trial_length = $trial_until['first_trial_length'];
                 $converted_periods['trial_period'] = $trial_until['first_trial_period'];
                 $second_trial_length = $trial_until['second_trial_length'];
                 $second_trial_period = $trial_until['second_trial_period'];
             } else {
                 $subscription_trial_length = 0;
             }
             // If this is a payment change, we need to account for completed payments on the number of installments owing
             if ($is_payment_change && $subscription_length > 0) {
                 $subscription_installments = max($subscription_installments - $subscription->get_completed_payment_count(), 0);
             }
         } else {
             $subscription_trial_length = wcs_estimate_periods_between($start_timestamp, $trial_end_timestamp, $subscription->trial_period);
         }
         if ($subscription_trial_length > 0) {
             // Specify a free trial period
             $paypal_args['a1'] = $initial_payment > 0 ? $initial_payment : 0;
             // Trial period length
             $paypal_args['p1'] = $subscription_trial_length;
             // Trial period
             $paypal_args['t1'] = $converted_periods['trial_period'];
             // We need to use a second trial period before we have more than 90 days until the next payment
             if (isset($second_trial_length) && $second_trial_length > 0) {
                 $paypal_args['a2'] = 0.01;
                 // Alas, although it's undocumented, PayPal appears to require a non-zero value in order to allow a second trial period
                 $paypal_args['p2'] = $second_trial_length;
                 $paypal_args['t2'] = $second_trial_period;
             }
         } elseif ($initial_payment != $price_per_period) {
             // No trial period, but initial amount includes a sign-up fee and/or other items, so charge it as a separate period
             if (1 == $subscription_installments) {
                 $param_number = 3;
             } else {
                 $param_number = 1;
             }
             $paypal_args['a' . $param_number] = $initial_payment;
             // Sign Up interval
             $paypal_args['p' . $param_number] = $subscription_interval;
             // Sign Up unit of duration
             $paypal_args['t' . $param_number] = $converted_periods['billing_period'];
         }
         // We have a recurring payment
         if (!isset($param_number) || 1 == $param_number) {
             // Subscription price
             $paypal_args['a3'] = $price_per_period;
             // Subscription duration
             $paypal_args['p3'] = $subscription_interval;
             // Subscription period
             $paypal_args['t3'] = $converted_periods['billing_period'];
         }
         // Recurring payments
         if (1 == $subscription_installments || $initial_payment != $price_per_period && 0 == $subscription_trial_length && 2 == $subscription_installments) {
             // Non-recurring payments
             $paypal_args['src'] = 0;
         } else {
             $paypal_args['src'] = 1;
             if ($subscription_installments > 0) {
                 // An initial period is being used to charge a sign-up fee
                 if ($initial_payment != $price_per_period && 0 == $subscription_trial_length) {
                     $subscription_installments--;
                 }
                 $paypal_args['srt'] = $subscription_installments;
             }
         }
         // Don't reattempt failed payments, instead let Subscriptions handle the failed payment
         $paypal_args['sra'] = 0;
         // Force return URL so that order description & instructions display
         $paypal_args['rm'] = 2;
         // Reattach the filter we removed earlier
         if ($is_payment_change) {
             add_filter('woocommerce_order_amount_total', 'WC_Subscriptions_Change_Payment_Gateway::maybe_zero_total', 11, 2);
         }
     }
     return $paypal_args;
 }
コード例 #2
0
 /**
  * Records the initial payment against a subscription.
  *
  * This function is called when an orders status is changed to completed or processing
  * for those gateways which never call @see WC_Order::payment_complete(), like the core
  * WooCommerce Cheque and Bank Transfer gateways.
  *
  * It will also set the start date on the subscription to the time the payment is completed.
  *
  * @param $order_id int|WC_Order
  * @param $old_order_status
  * @param $new_order_status
  * @since 2.0
  */
 public static function maybe_record_subscription_payment($order_id, $old_order_status, $new_order_status)
 {
     if (wcs_order_contains_subscription($order_id)) {
         $subscriptions = wcs_get_subscriptions_for_order($order_id);
         $was_activated = false;
         $order_completed = in_array($new_order_status, array(apply_filters('woocommerce_payment_complete_order_status', 'processing', $order_id), 'processing', 'completed')) && in_array($old_order_status, apply_filters('woocommerce_valid_order_statuses_for_payment', array('pending', 'on-hold', 'failed')));
         foreach ($subscriptions as $subscription) {
             // Do we need to activate a subscription?
             if ($order_completed && !$subscription->has_status(wcs_get_subscription_ended_statuses()) && !$subscription->has_status('active')) {
                 $new_start_date_offset = current_time('timestamp', true) - $subscription->get_time('start');
                 $dates = array('start' => current_time('mysql', true));
                 if (0 != $subscription->get_time('trial_end')) {
                     $dates['trial_end'] = gmdate('Y-m-d H:i:s', $subscription->get_time('trial_end') + $new_start_date_offset);
                 }
                 if (0 != $subscription->get_time('next_payment')) {
                     if (WC_Subscriptions_Synchroniser::subscription_contains_synced_product($subscription)) {
                         $prior_date = isset($dates['trial_end']) ? $dates['trial_end'] : $dates['start'];
                         if ($subscription->get_time('next_payment') < strtotime($prior_date)) {
                             foreach ($subscription->get_items() as $item) {
                                 $product_id = wcs_get_canonical_product_id($item);
                                 if (WC_Subscriptions_Synchroniser::is_product_synced($product_id)) {
                                     $dates['next_payment'] = WC_Subscriptions_Synchroniser::calculate_first_payment_date($product_id);
                                     break;
                                 }
                             }
                         }
                     } else {
                         $dates['next_payment'] = gmdate('Y-m-d H:i:s', $subscription->get_time('next_payment') + $new_start_date_offset);
                     }
                 }
                 if (0 != $subscription->get_time('end')) {
                     $dates['end'] = gmdate('Y-m-d H:i:s', $subscription->get_time('end') + $new_start_date_offset);
                 }
                 $subscription->update_dates($dates);
                 $subscription->payment_complete();
                 $was_activated = true;
             } elseif ('failed' == $new_order_status) {
                 $subscription->payment_failed();
             }
         }
         if ($was_activated) {
             do_action('subscriptions_activated_for_order', $order_id);
         }
     }
 }
 /**
  * Return an i18n'ified associative array of all possible subscription periods.
  *
  * @since 1.5
  */
 public static function get_billing_period_ranges($billing_period = '')
 {
     global $wp_locale;
     if (empty(self::$billing_period_ranges)) {
         foreach (array('week', 'month', 'year') as $key) {
             self::$billing_period_ranges[$key][0] = __('Do not synchronise', 'woocommerce-subscriptions');
         }
         // Week
         $weekdays = array_merge($wp_locale->weekday, array($wp_locale->weekday[0]));
         unset($weekdays[0]);
         foreach ($weekdays as $i => $weekly_billing_period) {
             self::$billing_period_ranges['week'][$i] = sprintf(__('%s each week', 'woocommerce-subscriptions'), $weekly_billing_period);
         }
         // Month
         foreach (range(1, 27) as $i) {
             self::$billing_period_ranges['month'][$i] = sprintf(__('%s day of the month', 'woocommerce-subscriptions'), WC_Subscriptions::append_numeral_suffix($i));
         }
         self::$billing_period_ranges['month'][28] = __('Last day of the month', 'woocommerce-subscriptions');
         self::$billing_period_ranges = apply_filters('woocommerce_subscription_billing_period_ranges', self::$billing_period_ranges);
     }
     if (empty($billing_period)) {
         return self::$billing_period_ranges;
     } elseif (isset(self::$billing_period_ranges[$billing_period])) {
         return self::$billing_period_ranges[$billing_period];
     } else {
         return array();
     }
 }
コード例 #4
0
 /**
  * Set the subscription prices to be used in calculating totals by @see WC_Subscriptions_Cart::calculate_subscription_totals()
  *
  * @since 2.0
  */
 public static function calculate_prorated_totals($cart)
 {
     if (false === self::cart_contains_switches()) {
         return;
     }
     // Maybe charge an initial amount to account for upgrading from a cheaper subscription
     $apportion_recurring_price = get_option(WC_Subscriptions_Admin::$option_prefix . '_apportion_recurring_price', 'no');
     $apportion_sign_up_fee = get_option(WC_Subscriptions_Admin::$option_prefix . '_apportion_sign_up_fee', 'no');
     $apportion_length = get_option(WC_Subscriptions_Admin::$option_prefix . '_apportion_length', 'no');
     foreach (WC()->cart->get_cart() as $cart_item_key => $cart_item) {
         if (!isset($cart_item['subscription_switch']['subscription_id'])) {
             continue;
         }
         $subscription = wcs_get_subscription($cart_item['subscription_switch']['subscription_id']);
         $existing_item = wcs_get_order_item($cart_item['subscription_switch']['item_id'], $subscription);
         if (empty($existing_item)) {
             WC()->cart->remove_cart_item($cart_item_key);
             continue;
         }
         $item_data = $cart_item['data'];
         $product_id = wcs_get_canonical_product_id($cart_item);
         $product = wc_get_product($product_id);
         $is_virtual_product = $product->is_virtual();
         // Set when the first payment and end date for the new subscription should occur
         WC()->cart->cart_contents[$cart_item_key]['subscription_switch']['first_payment_timestamp'] = $cart_item['subscription_switch']['next_payment_timestamp'];
         WC()->cart->cart_contents[$cart_item_key]['subscription_switch']['end_timestamp'] = $end_timestamp = strtotime(WC_Subscriptions_Product::get_expiration_date($product_id, $subscription->get_date('last_payment')));
         // Add any extra sign up fees required to switch to the new subscription
         if ('yes' == $apportion_sign_up_fee) {
             // Because product add-ons etc. don't apply to sign-up fees, it's safe to use the product's sign-up fee value rather than the cart item's
             $sign_up_fee_due = $product->subscription_sign_up_fee;
             $sign_up_fee_paid = $subscription->get_items_sign_up_fee($existing_item, 'inclusive_of_tax');
             // Make sure total prorated sign-up fee is prorated across total amount of sign-up fee so that customer doesn't get extra discounts
             if ($cart_item['quantity'] > $existing_item['qty']) {
                 $sign_up_fee_paid = $sign_up_fee_paid * $existing_item['qty'] / $cart_item['quantity'];
             }
             WC()->cart->cart_contents[$cart_item_key]['data']->subscription_sign_up_fee = max($sign_up_fee_due - $sign_up_fee_paid, 0);
             WC()->cart->cart_contents[$cart_item_key]['data']->subscription_sign_up_fee_prorated = WC()->cart->cart_contents[$cart_item_key]['data']->subscription_sign_up_fee;
         } elseif ('no' == $apportion_sign_up_fee) {
             // $0 the initial sign-up fee
             WC()->cart->cart_contents[$cart_item_key]['data']->subscription_sign_up_fee = 0;
         }
         // Get the current subscription's last payment date
         $last_payment_timestamp = $subscription->get_time('last_payment');
         $days_since_last_payment = floor((gmdate('U') - $last_payment_timestamp) / (60 * 60 * 24));
         // Get the current subscription's next payment date
         $next_payment_timestamp = $cart_item['subscription_switch']['next_payment_timestamp'];
         $days_until_next_payment = ceil(($next_payment_timestamp - gmdate('U')) / (60 * 60 * 24));
         // If the subscription contains a synced product and the next payment is actually the first payment, determine the days in the "old" cycle from the subscription object
         if (WC_Subscriptions_Synchroniser::subscription_contains_synced_product($subscription->id) && WC_Subscriptions_Synchroniser::calculate_first_payment_date($product, 'timestamp', $subscription->get_date('start')) == $next_payment_timestamp) {
             $days_in_old_cycle = wcs_get_days_in_cycle($subscription->billing_period, $subscription->billing_interval);
         } else {
             // Find the number of days between the two
             $days_in_old_cycle = $days_until_next_payment + $days_since_last_payment;
         }
         // Find the actual recurring amount charged for the old subscription (we need to use the '_recurring_line_total' meta here rather than '_subscription_recurring_amount' because we want the recurring amount to include extra from extensions, like Product Add-ons etc.)
         $old_recurring_total = $existing_item['line_total'];
         if ('yes' == $subscription->prices_include_tax || true === $subscription->prices_include_tax) {
             // WC_Abstract_Order::$prices_include_tax can be set to true in __construct() or to 'yes' in populate()
             $old_recurring_total += $existing_item['line_tax'];
         }
         // Find the $price per day for the old subscription's recurring total
         $old_price_per_day = $old_recurring_total / $days_in_old_cycle;
         // Find the price per day for the new subscription's recurring total
         // If the subscription uses the same billing interval & cycle as the old subscription,
         if ($item_data->subscription_period == $subscription->billing_period && $item_data->subscription_period_interval == $subscription->billing_interval) {
             $days_in_new_cycle = $days_in_old_cycle;
             // Use $days_in_old_cycle to make sure they're consistent
         } else {
             // We need to figure out the price per day for the new subscription based on its billing schedule
             $days_in_new_cycle = wcs_get_days_in_cycle($item_data->subscription_period, $item_data->subscription_period_interval);
         }
         // We need to use the cart items price to ensure we include extras added by extensions like Product Add-ons
         $new_price_per_day = $item_data->price * $cart_item['quantity'] / $days_in_new_cycle;
         if ($old_price_per_day < $new_price_per_day) {
             WC()->cart->cart_contents[$cart_item_key]['subscription_switch']['upgraded_or_downgraded'] = 'upgraded';
         } elseif ($old_price_per_day > $new_price_per_day && $new_price_per_day >= 0) {
             WC()->cart->cart_contents[$cart_item_key]['subscription_switch']['upgraded_or_downgraded'] = 'downgraded';
         }
         // Now lets see if we should add a prorated amount to the sign-up fee (for upgrades) or extend the next payment date (for downgrades)
         if (in_array($apportion_recurring_price, array('yes', 'yes-upgrade')) || in_array($apportion_recurring_price, array('virtual', 'virtual-upgrade')) && $is_virtual_product) {
             // If the customer is upgrading, we may need to add a gap payment to the sign-up fee or to reduce the pre-paid period (or both)
             if ($old_price_per_day < $new_price_per_day) {
                 // The new subscription may be more expensive, but it's also on a shorter billing cycle, so reduce the next pre-paid term
                 if ($days_in_old_cycle > $days_in_new_cycle) {
                     // Find out how many days at the new price per day the customer would receive for the total amount already paid
                     // (e.g. if the customer paid $10 / month previously, and was switching to a $5 / week subscription, she has pre-paid 14 days at the new price)
                     $pre_paid_days = 0;
                     do {
                         $pre_paid_days++;
                         $new_total_paid = $pre_paid_days * $new_price_per_day;
                     } while ($new_total_paid < $old_recurring_total);
                     // If the total amount the customer has paid entitles her to more days at the new price than she has received, there is no gap payment, just shorten the pre-paid term the appropriate number of days
                     if ($days_since_last_payment < $pre_paid_days) {
                         WC()->cart->cart_contents[$cart_item_key]['subscription_switch']['first_payment_timestamp'] = $last_payment_timestamp + $pre_paid_days * 60 * 60 * 24;
                         // If the total amount the customer has paid entitles her to the same or less days at the new price then start the new subscription from today
                     } else {
                         WC()->cart->cart_contents[$cart_item_key]['subscription_switch']['first_payment_timestamp'] = 0;
                     }
                 } else {
                     $extra_to_pay = $days_until_next_payment * ($new_price_per_day - $old_price_per_day);
                     // when calculating a subscription with one length (no more next payment date and the end date may have been pushed back) we need to pay for those extra days at the new price per day between the old next payment date and new end date
                     if (1 == $item_data->subscription_length) {
                         $days_to_new_end = floor(($end_timestamp - $next_payment_timestamp) / (60 * 60 * 24));
                         if ($days_to_new_end > 0) {
                             $extra_to_pay += $days_to_new_end * $new_price_per_day;
                         }
                     }
                     // We need to find the per item extra to pay so we can set it as the sign-up fee (WC will then multiply it by the quantity)
                     $extra_to_pay = $extra_to_pay / $cart_item['quantity'];
                     // Keep a record of the two separate amounts so we store these and calculate future switch amounts correctly
                     WC()->cart->cart_contents[$cart_item_key]['data']->subscription_sign_up_fee_prorated = WC()->cart->cart_contents[$cart_item_key]['data']->subscription_sign_up_fee;
                     WC()->cart->cart_contents[$cart_item_key]['data']->subscription_price_prorated = round($extra_to_pay, 2);
                     WC()->cart->cart_contents[$cart_item_key]['data']->subscription_sign_up_fee += round($extra_to_pay, 2);
                 }
                 // If the customer is downgrading, set the next payment date and maybe extend it if downgrades are prorated
             } elseif ($old_price_per_day > $new_price_per_day && $new_price_per_day > 0) {
                 $old_total_paid = $old_price_per_day * $days_until_next_payment;
                 $new_total_paid = $new_price_per_day;
                 // if downgrades are apportioned, extend the next payment date for n more days
                 if (in_array($apportion_recurring_price, array('virtual', 'yes'))) {
                     // Find how many more days at the new lower price it takes to exceed the amount already paid
                     for ($days_to_add = 0; $new_total_paid <= $old_total_paid; $days_to_add++) {
                         $new_total_paid = $days_to_add * $new_price_per_day;
                     }
                     $days_to_add -= $days_until_next_payment;
                 } else {
                     $days_to_add = 0;
                 }
                 WC()->cart->cart_contents[$cart_item_key]['subscription_switch']['first_payment_timestamp'] = $next_payment_timestamp + $days_to_add * 60 * 60 * 24;
             }
             // The old price per day == the new price per day, no need to change anything
             if (WC()->cart->cart_contents[$cart_item_key]['subscription_switch']['first_payment_timestamp'] != $cart_item['subscription_switch']['next_payment_timestamp']) {
                 WC()->cart->cart_contents[$cart_item_key]['subscription_switch']['recurring_payment_prorated'] = true;
             }
         }
         // Finally, if we need to make sure the initial total doesn't include any recurring amount, we can by spoofing a free trial
         if (0 != WC()->cart->cart_contents[$cart_item_key]['subscription_switch']['first_payment_timestamp']) {
             WC()->cart->cart_contents[$cart_item_key]['data']->subscription_trial_length = 1;
         }
         if ('yes' == $apportion_length || 'virtual' == $apportion_length && $is_virtual_product) {
             $base_length = WC_Subscriptions_Product::get_length($product_id);
             $completed_payments = $subscription->get_completed_payment_count();
             $length_remaining = $base_length - $completed_payments;
             // Default to the base length if more payments have already been made than this subscription requires
             if ($length_remaining <= 0) {
                 $length_remaining = $base_length;
             }
             WC()->cart->cart_contents[$cart_item_key]['data']->subscription_length = $length_remaining;
         }
     }
 }
?>
<tr class="variable_subscription_sync show_if_variable-subscription">
	<td colspan="1" class="subscription_sync_week_month"<?php 
echo $display_week_month_select;
?>
>
		<?php 
if (WC_Subscriptions::is_woocommerce_pre_2_3()) {
    ?>
		<label><?php 
    _e('Synchronise Renewals', 'woocommerce-subscriptions');
    ?>
</label>
		<?php 
}
woocommerce_wp_select(array('id' => 'variable' . WC_Subscriptions_Synchroniser::$post_meta_key . '[' . $loop . ']', 'class' => 'wc_input_subscription_payment_sync', 'wrapper_class' => '_subscription_payment_sync_field', 'label' => WC_Subscriptions_Synchroniser::$sync_field_label, 'options' => WC_Subscriptions_Synchroniser::get_billing_period_ranges($subscription_period), 'description' => WC_Subscriptions_Synchroniser::$sync_description, 'desc_tip' => true, 'value' => $payment_day));
?>
	</td>
	<td colspan="1" class="subscription_sync_annual"<?php 
echo $display_annual_select;
?>
>
		<label><?php 
_e('Synchronise Renewals', 'woocommerce-subscriptions');
?>
</label>
<?php 
woocommerce_wp_text_input(array('id' => 'variable' . WC_Subscriptions_Synchroniser::$post_meta_key_day . '[' . $loop . ']', 'class' => 'wc_input_subscription_payment_sync', 'wrapper_class' => '_subscription_payment_sync_field', 'label' => WC_Subscriptions_Synchroniser::$sync_field_label, 'placeholder' => __('Day', 'woocommerce-subscriptions'), 'value' => $payment_day, 'type' => 'number', 'custom_attributes' => array('step' => '1', 'min' => '0', 'max' => '31')));
woocommerce_wp_select(array('id' => 'variable' . WC_Subscriptions_Synchroniser::$post_meta_key_month . '[' . $loop . ']', 'class' => 'wc_input_subscription_payment_sync', 'wrapper_class' => '_subscription_payment_sync_field', 'label' => '', 'options' => $wp_locale->month, 'description' => WC_Subscriptions_Synchroniser::$sync_description_year, 'desc_tip' => true, 'value' => $payment_month));
?>
	</td>
コード例 #6
0
 /**
  * Get prorated sub price.
  *
  * @param  double     $recurring_price
  * @param  WC_Product $product
  * @return double
  */
 public function get_prorated_price_for_subscription($recurring_price, $product = false)
 {
     if (!$product) {
         $product = $this->product;
     }
     $price = 0;
     if (WC_Subscriptions_Product::is_subscription($product)) {
         if (0 == WC_Subscriptions_Product::get_trial_length($product)) {
             if (WC_Subscriptions_Synchroniser::is_product_prorated($product)) {
                 $next_payment_date = WC_Subscriptions_Synchroniser::calculate_first_payment_date($product, 'timestamp');
                 if (WC_Subscriptions_Synchroniser::is_today($next_payment_date)) {
                     return $recurring_price;
                 }
                 switch ($product->subscription_period) {
                     case 'week':
                         $days_in_cycle = 7 * $product->subscription_period_interval;
                         break;
                     case 'month':
                         $days_in_cycle = date('t') * $product->subscription_period_interval;
                         break;
                     case 'year':
                         $days_in_cycle = (365 + date('L')) * $product->subscription_period_interval;
                         break;
                 }
                 $days_until_next_payment = ceil(($next_payment_date - gmdate('U')) / (60 * 60 * 24));
                 $price = $days_until_next_payment * ($recurring_price / $days_in_cycle);
             } else {
                 $price = $recurring_price;
             }
         }
     }
     return $price;
 }
コード例 #7
0
 /**
  * Creates a string representation of the subscription period/term for each item in the cart
  *
  * @param string $initial_amount The initial amount to be displayed for the subscription as passed through the @see woocommerce_price() function.
  * @param float $recurring_amount The price to display in the subscription.
  * @param array $args (optional) Flags to customise  to display the trial and length of the subscription. Default to false - don't display.
  * @since 1.0
  * @deprecated 2.0
  */
 public static function get_cart_subscription_string($initial_amount, $recurring_amount, $args = array())
 {
     _deprecated_function(__METHOD__, '2.0', 'values from WC()->cart->recurring_carts');
     if (!is_array($args)) {
         _deprecated_argument(__CLASS__ . '::' . __FUNCTION__, '1.4', 'Third parameter is now an array of name => value pairs. Use array( "include_lengths" => true ) instead.');
         $args = array('include_lengths' => $args);
     }
     $args = wp_parse_args($args, array('include_lengths' => false, 'include_trial' => true));
     $subscription_details = array('initial_amount' => $initial_amount, 'initial_description' => __('now', 'woocommerce-subscriptions'), 'recurring_amount' => $recurring_amount, 'subscription_interval' => self::get_cart_subscription_interval(), 'subscription_period' => self::get_cart_subscription_period(), 'trial_length' => self::get_cart_subscription_trial_length(), 'trial_period' => self::get_cart_subscription_trial_period());
     $is_one_payment = self::get_cart_subscription_length() > 0 && self::get_cart_subscription_length() == self::get_cart_subscription_interval() ? true : false;
     // Override defaults when subscription is for one billing period
     if ($is_one_payment) {
         $subscription_details['subscription_length'] = self::get_cart_subscription_length();
     } else {
         if (true === $args['include_lengths']) {
             $subscription_details['subscription_length'] = self::get_cart_subscription_length();
         }
         if (false === $args['include_trial']) {
             $subscription_details['trial_length'] = 0;
         }
     }
     $initial_amount_string = is_numeric($subscription_details['initial_amount']) ? woocommerce_price($subscription_details['initial_amount']) : $subscription_details['initial_amount'];
     $recurring_amount_string = is_numeric($subscription_details['recurring_amount']) ? woocommerce_price($subscription_details['recurring_amount']) : $subscription_details['recurring_amount'];
     // Don't show up front fees when there is no trial period and no sign up fee and they are the same as the recurring amount
     if (self::get_cart_subscription_trial_length() == 0 && self::get_cart_subscription_sign_up_fee() == 0 && $initial_amount_string == $recurring_amount_string) {
         $subscription_details['initial_amount'] = '';
     } elseif (wc_price(0) == $initial_amount_string && false === $is_one_payment && self::get_cart_subscription_trial_length() > 0) {
         // don't show $0.00 initial amount (i.e. a free trial with no non-subscription products in the cart) unless the recurring period is the same as the billing period
         $subscription_details['initial_amount'] = '';
     }
     // Include details of a synced subscription in the cart
     if ($synchronised_cart_item = WC_Subscriptions_Synchroniser::cart_contains_synced_subscription()) {
         $subscription_details += array('is_synced' => true, 'synchronised_payment_day' => WC_Subscriptions_Synchroniser::get_products_payment_day($synchronised_cart_item['data']));
     }
     $subscription_details = apply_filters('woocommerce_cart_subscription_string_details', $subscription_details, $args);
     $subscription_string = wcs_price_string($subscription_details);
     return $subscription_string;
 }
 /**
  * Override the default PayPal standard args in WooCommerce for subscription purchases when
  * automatic payments are enabled and when the recurring order totals is over $0.00 (because
  * PayPal doesn't support subscriptions with a $0 recurring total, we need to circumvent it and
  * manage it entirely ourselves.)
  *
  * Based on the HTML Variables documented here: https://developer.paypal.com/webapps/developer/docs/classic/paypal-payments-standard/integration-guide/Appx_websitestandard_htmlvariables/#id08A6HI00JQU
  *
  * @since 1.0
  */
 public static function paypal_standard_subscription_args($paypal_args)
 {
     extract(self::get_order_id_and_key($paypal_args));
     $order = new WC_Order($order_id);
     if ($cart_item = WC_Subscriptions_Cart::cart_contains_failed_renewal_order_payment() || false !== WC_Subscriptions_Renewal_Order::get_failed_order_replaced_by($order_id)) {
         $renewal_order = $order;
         $order = WC_Subscriptions_Renewal_Order::get_parent_order($renewal_order);
         $order_contains_failed_renewal = true;
     } else {
         $order_contains_failed_renewal = false;
     }
     if ($order_contains_failed_renewal || WC_Subscriptions_Order::order_contains_subscription($order) && WC_Subscriptions_Order::get_recurring_total($order) > 0 && 'yes' !== get_option(WC_Subscriptions_Admin::$option_prefix . '_turn_off_automatic_payments', 'no')) {
         // Only one subscription allowed in the cart when PayPal Standard is active
         $product = $order->get_product_from_item(array_pop(WC_Subscriptions_Order::get_recurring_items($order)));
         // It's a subscription
         $paypal_args['cmd'] = '_xclick-subscriptions';
         if (count($order->get_items()) > 1) {
             foreach ($order->get_items() as $item) {
                 if ($item['qty'] > 1) {
                     $item_names[] = $item['qty'] . ' x ' . self::paypal_item_name($item['name']);
                 } elseif ($item['qty'] > 0) {
                     $item_names[] = self::paypal_item_name($item['name']);
                 }
             }
             $paypal_args['item_name'] = self::paypal_item_name(sprintf(__('Order %s', 'woocommerce-subscriptions'), $order->get_order_number() . " - " . implode(', ', $item_names)));
         } else {
             $paypal_args['item_name'] = self::paypal_item_name($product->get_title());
         }
         $unconverted_periods = array('billing_period' => WC_Subscriptions_Order::get_subscription_period($order), 'trial_period' => WC_Subscriptions_Order::get_subscription_trial_period($order));
         $converted_periods = array();
         // Convert period strings into PayPay's format
         foreach ($unconverted_periods as $key => $period) {
             switch (strtolower($period)) {
                 case 'day':
                     $converted_periods[$key] = 'D';
                     break;
                 case 'week':
                     $converted_periods[$key] = 'W';
                     break;
                 case 'year':
                     $converted_periods[$key] = 'Y';
                     break;
                 case 'month':
                 default:
                     $converted_periods[$key] = 'M';
                     break;
             }
         }
         $price_per_period = WC_Subscriptions_Order::get_recurring_total($order);
         $subscription_interval = WC_Subscriptions_Order::get_subscription_interval($order);
         $subscription_length = WC_Subscriptions_Order::get_subscription_length($order);
         $subscription_installments = $subscription_length / $subscription_interval;
         $is_payment_change = WC_Subscriptions_Change_Payment_Gateway::$is_request_to_change_payment;
         $is_switch_order = WC_Subscriptions_Switcher::order_contains_subscription_switch($order->id);
         $is_synced_subscription = WC_Subscriptions_Synchroniser::order_contains_synced_subscription($order->id);
         $sign_up_fee = $is_payment_change ? 0 : WC_Subscriptions_Order::get_sign_up_fee($order);
         $initial_payment = $is_payment_change ? 0 : WC_Subscriptions_Order::get_total_initial_payment($order);
         if ($is_payment_change) {
             // Add a nonce to the order ID to avoid "This invoice has already been paid" error when changing payment method to PayPal when it was previously PayPal
             $paypal_args['invoice'] = $paypal_args['invoice'] . '-wcscpm-' . wp_create_nonce();
         } elseif ($order_contains_failed_renewal) {
             // Set the invoice details to the original order's invoice but also append a special string and this renewal orders ID so that we can match it up as a failed renewal order payment later
             $paypal_args['invoice'] = self::$invoice_prefix . ltrim($order->get_order_number(), '#') . '-wcsfrp-' . $renewal_order->id;
             $paypal_args['custom'] = serialize(array($order->id, $order->order_key));
         }
         if ($order_contains_failed_renewal) {
             $sign_up_fee = 0;
             $initial_payment = $renewal_order->get_total();
             // Initial payment can be left in case the customer is purchased other products with the payment
             $subscription_trial_length = 0;
             $subscription_installments = max($subscription_installments - WC_Subscriptions_Manager::get_subscriptions_completed_payment_count(WC_Subscriptions_Manager::get_subscription_key($order_id, $product->id)), 0);
             // If we're changing the payment date or switching subs, we need to set the trial period to the next payment date & installments to be the number of installments left
         } elseif ($is_payment_change || $is_switch_order || $is_synced_subscription) {
             $subscription_key = WC_Subscriptions_Manager::get_subscription_key($order_id, $product->id);
             // Give a free trial until the next payment date
             if ($is_switch_order) {
                 $next_payment_timestamp = get_post_meta($order->id, '_switched_subscription_first_payment_timestamp', true);
             } elseif ($is_synced_subscription) {
                 $next_payment_timestamp = WC_Subscriptions_Synchroniser::calculate_first_payment_date($product, 'timestamp');
             } else {
                 $next_payment_timestamp = WC_Subscriptions_Manager::get_next_payment_date($subscription_key, $order->user_id, 'timestamp');
             }
             // When the subscription is on hold
             if ($next_payment_timestamp != false && !empty($next_payment_timestamp)) {
                 $trial_until = self::calculate_trial_periods_until($next_payment_timestamp);
                 $subscription_trial_length = $trial_until['first_trial_length'];
                 $converted_periods['trial_period'] = $trial_until['first_trial_period'];
                 $second_trial_length = $trial_until['second_trial_length'];
                 $second_trial_period = $trial_until['second_trial_period'];
             } else {
                 $subscription_trial_length = 0;
             }
             // If is a payment change, we need to account for completed payments on the number of installments owing
             if ($is_payment_change && $subscription_length > 0) {
                 $subscription_installments -= WC_Subscriptions_Manager::get_subscriptions_completed_payment_count($subscription_key);
             }
         } else {
             $subscription_trial_length = WC_Subscriptions_Order::get_subscription_trial_length($order);
         }
         if ($subscription_trial_length > 0) {
             // Specify a free trial period
             if ($is_switch_order || $is_synced_subscription || $initial_payment != $sign_up_fee) {
                 $paypal_args['a1'] = $initial_payment > 0 ? $initial_payment : 0;
             } else {
                 $paypal_args['a1'] = $sign_up_fee > 0 ? $sign_up_fee : 0;
                 // Maybe add the sign up fee to the free trial period
             }
             // Trial period length
             $paypal_args['p1'] = $subscription_trial_length;
             // Trial period
             $paypal_args['t1'] = $converted_periods['trial_period'];
             // We need to use a second trial period before we have more than 90 days until the next payment
             if (isset($second_trial_length) && $second_trial_length > 0) {
                 $paypal_args['a2'] = 0.01;
                 // Alas, although it's undocumented, PayPal appears to require a non-zero value in order to allow a second trial period
                 $paypal_args['p2'] = $second_trial_length;
                 $paypal_args['t2'] = $second_trial_period;
             }
         } elseif ($sign_up_fee > 0 || $initial_payment != $price_per_period) {
             // No trial period, so charge sign up fee and per period price for the first period
             if ($subscription_installments == 1) {
                 $param_number = 3;
             } else {
                 $param_number = 1;
             }
             $paypal_args['a' . $param_number] = $initial_payment;
             // Sign Up interval
             $paypal_args['p' . $param_number] = $subscription_interval;
             // Sign Up unit of duration
             $paypal_args['t' . $param_number] = $converted_periods['billing_period'];
         }
         // We have a recurring payment
         if (!isset($param_number) || $param_number == 1) {
             // Subscription price
             $paypal_args['a3'] = $price_per_period;
             // Subscription duration
             $paypal_args['p3'] = $subscription_interval;
             // Subscription period
             $paypal_args['t3'] = $converted_periods['billing_period'];
         }
         // Recurring payments
         if ($subscription_installments == 1 || $sign_up_fee > 0 && $subscription_trial_length == 0 && $subscription_installments == 2) {
             // Non-recurring payments
             $paypal_args['src'] = 0;
         } else {
             $paypal_args['src'] = 1;
             if ($subscription_installments > 0) {
                 if ($sign_up_fee > 0 && $subscription_trial_length == 0) {
                     // An initial period is being used to charge a sign-up fee
                     $subscription_installments--;
                 }
                 $paypal_args['srt'] = $subscription_installments;
             }
         }
         // Don't reattempt failed payments, instead let Subscriptions handle the failed payment
         $paypal_args['sra'] = 0;
         // Force return URL so that order description & instructions display
         $paypal_args['rm'] = 2;
     }
     return $paypal_args;
 }
コード例 #9
0
?>
]">
				<?php 
echo esc_html(WC_Subscriptions_Synchroniser::$sync_field_label);
?>
: <a class="tips" data-tip="<?php 
echo esc_attr(WC_Subscriptions_Synchroniser::$sync_description);
?>
" href="#">[?]</a>
			</label>
			<select name="variable_subscription_payment_sync_date[<?php 
echo esc_attr($loop);
?>
]" class="wc_input_subscription_payment_sync">
			<?php 
foreach (WC_Subscriptions_Synchroniser::get_billing_period_ranges($subscription_period) as $key => $value) {
    ?>
				<option value="<?php 
    echo esc_attr($key);
    ?>
" <?php 
    selected($key, $payment_day);
    ?>
><?php 
    echo esc_html($value);
    ?>
</option>
			<?php 
}
?>
			</select>
コード例 #10
0
 /**
  *  Determine if the subscription is for one payment only.
  *
  * @return bool whether the subscription is for only one payment
  * @since 2.0.17
  */
 public function is_one_payment()
 {
     $is_one_payment = false;
     if (0 != ($end_time = $this->get_time('end'))) {
         $from_timestamp = $this->get_time('start');
         if (0 != $this->get_time('trial_end') || WC_Subscriptions_Synchroniser::subscription_contains_synced_product($this)) {
             $subscription_order_count = count($this->get_related_orders());
             // when we have a sync'd subscription before its 1st payment, we need to base the calculations for the next payment on the first/next payment timestamp.
             if ($subscription_order_count < 2 && 0 != ($next_payment_timestamp = $this->get_time('next_payment'))) {
                 $from_timestamp = $next_payment_timestamp;
                 // when we have a sync'd subscription after its 1st payment, we need to base the calculations for the next payment on the last payment timestamp.
             } else {
                 if (!($subscription_order_count > 2) && 0 != ($last_payment_timestamp = $this->get_time('last_payment'))) {
                     $from_timestamp = $last_payment_timestamp;
                 }
             }
         }
         $next_payment_timestamp = wcs_add_time($this->billing_interval, $this->billing_period, $from_timestamp);
         if ($next_payment_timestamp + DAY_IN_SECONDS - 1 > $end_time) {
             $is_one_payment = true;
         }
     }
     return apply_filters('woocommerce_subscription_is_one_payment', $is_one_payment, $this);
 }
コード例 #11
0
 /**
  * Check whether the cart needs payment even if the order total is $0
  *
  * @param bool $needs_payment The existing flag for whether the cart needs payment or not.
  * @param WC_Cart $cart The WooCommerce cart object.
  * @return bool
  */
 public static function cart_needs_payment($needs_payment, $cart)
 {
     if (false === $needs_payment && self::cart_contains_subscription() && $cart->total == 0 && $cart->recurring_total > 0 && 'yes' !== get_option(WC_Subscriptions_Admin::$option_prefix . '_turn_off_automatic_payments', 'no')) {
         $is_one_period = self::get_cart_subscription_length() > 0 && self::get_cart_subscription_length() == self::get_cart_subscription_interval() ? true : false;
         $has_trial = self::get_cart_subscription_trial_length() > 0 ? true : false;
         $is_syncd = WC_Subscriptions_Synchroniser::cart_contains_synced_subscription();
         if (false === $is_one_period || true === $has_trial || false !== $is_syncd && false == WC_Subscriptions_Synchroniser::is_today(WC_Subscriptions_Synchroniser::calculate_first_payment_date($is_syncd['data'], 'timestamp'))) {
             $needs_payment = true;
         }
     }
     return $needs_payment;
 }
コード例 #12
0
 /**
  * Processes an AJAX request to check if a product has a variation which is either sync'd or has a trial.
  * Once at least one variation with a trial or sync date is found, this will terminate and return true, otherwise false.
  *
  * @since 2.0.18
  */
 public static function check_product_variations_for_syncd_or_trial()
 {
     check_admin_referer('one_time_shipping', 'nonce');
     $product = wc_get_product($_POST['product_id']);
     $is_synced_or_has_trial = false;
     if (WC_Subscriptions_Product::is_subscription($product)) {
         foreach ($product->get_children() as $variation_id) {
             if (isset($_POST['variations_checked']) && in_array($variation_id, $_POST['variations_checked'])) {
                 continue;
             }
             $variable_product = wc_get_product($variation_id);
             if ($variable_product->subscription_trial_length > 0) {
                 $is_synced_or_has_trial = true;
                 break;
             }
             if (WC_Subscriptions_Synchroniser::is_syncing_enabled() && (!is_array($variable_product->subscription_payment_sync_date) && $variable_product->subscription_payment_sync_date > 0 || is_array($variable_product->subscription_payment_sync_date) && $variable_product->subscription_payment_sync_date['day'] > 0)) {
                 $is_synced_or_has_trial = true;
                 break;
             }
         }
     }
     wp_send_json(array('is_synced_or_has_trial' => $is_synced_or_has_trial));
 }
コード例 #13
0
 /**
  * Records the initial payment against a subscription.
  *
  * This function is called when an orders status is changed to completed or processing
  * for those gateways which never call @see WC_Order::payment_complete(), like the core
  * WooCommerce Cheque and Bank Transfer gateways.
  *
  * It will also set the start date on the subscription to the time the payment is completed.
  *
  * @param $order_id int|WC_Order
  * @param $old_order_status
  * @param $new_order_status
  * @since 2.0
  */
 public static function maybe_record_subscription_payment($order_id, $old_order_status, $new_order_status)
 {
     if (wcs_order_contains_subscription($order_id)) {
         $subscriptions = wcs_get_subscriptions_for_order($order_id);
         $was_activated = false;
         $order_completed = in_array($new_order_status, array(apply_filters('woocommerce_payment_complete_order_status', 'processing', $order_id), 'processing', 'completed')) && in_array($old_order_status, apply_filters('woocommerce_valid_order_statuses_for_payment', array('pending', 'on-hold', 'failed')));
         foreach ($subscriptions as $subscription) {
             // Do we need to activate a subscription?
             if ($order_completed && !$subscription->has_status(wcs_get_subscription_ended_statuses()) && !$subscription->has_status('active')) {
                 $new_start_date_offset = current_time('timestamp', true) - $subscription->get_time('start');
                 // if the payment has been processed more than an hour after the order was first created, let's update the dates on the subscription to account for that, because it may have even been processed days after it was first placed
                 if ($new_start_date_offset > HOUR_IN_SECONDS) {
                     $dates = array('start' => current_time('mysql', true));
                     if (WC_Subscriptions_Synchroniser::subscription_contains_synced_product($subscription)) {
                         $trial_end = $subscription->get_time('trial_end');
                         $next_payment = $subscription->get_time('next_payment');
                         // if either there is a free trial date or a next payment date that falls before now, we need to recalculate all the sync'd dates
                         if ($trial_end > 0 && $trial_end < strtotime($dates['start']) || $next_payment > 0 && $next_payment < strtotime($dates['start'])) {
                             foreach ($subscription->get_items() as $item) {
                                 $product_id = wcs_get_canonical_product_id($item);
                                 if (WC_Subscriptions_Synchroniser::is_product_synced($product_id)) {
                                     $dates['trial_end'] = WC_Subscriptions_Product::get_trial_expiration_date($product_id, $dates['start']);
                                     $dates['next_payment'] = WC_Subscriptions_Synchroniser::calculate_first_payment_date($product_id, 'mysql', $dates['start']);
                                     $dates['end'] = WC_Subscriptions_Product::get_expiration_date($product_id, $dates['start']);
                                     break;
                                 }
                             }
                         }
                     } else {
                         // No sync'ing to mess about with, just add the offset to the existing dates
                         foreach (array('trial_end', 'next_payment', 'end') as $date_type) {
                             if (0 != $subscription->get_time($date_type)) {
                                 $dates[$date_type] = gmdate('Y-m-d H:i:s', $subscription->get_time($date_type) + $new_start_date_offset);
                             }
                         }
                     }
                     $subscription->update_dates($dates);
                 }
                 $subscription->payment_complete();
                 $was_activated = true;
             } elseif ('failed' == $new_order_status) {
                 $subscription->payment_failed();
             }
         }
         if ($was_activated) {
             do_action('subscriptions_activated_for_order', $order_id);
         }
     }
 }
コード例 #14
0
 /**
  * Check is a subscription coupon is valid before applying
  *
  * @since 1.2
  */
 public static function validate_subscription_coupon($valid, $coupon)
 {
     self::$coupon_error = '';
     // ignore non-subscription coupons
     if (!in_array($coupon->type, array('recurring_fee', 'sign_up_fee', 'recurring_percent', 'sign_up_fee_percent'))) {
         // make sure there are no other products in the cart which the coupon could be applied to - WC()->cart->get_cart_contents_count() returns the quantity of items in the cart, not the total number of unique items, we need to use WC()->cart->cart_contents for that.
         if (1 == count(WC()->cart->cart_contents) && 0 == WC_Subscriptions_Cart::get_cart_subscription_sign_up_fee()) {
             $error_message = __('Sorry, this coupon is only valid for an initial payment and the subscription does not have an initial payment.', 'woocommerce-subscriptions');
             // now make sure there is actually something for the coupon to be applied to (i.e. not a free trial or sync'd subscription without any prorated initial amount)
             if (WC_Subscriptions_Cart::cart_contains_free_trial()) {
                 self::$coupon_error = $error_message;
             } elseif (WC_Subscriptions_Synchroniser::cart_contains_synced_subscription() && !WC_Subscriptions_Synchroniser::cart_contains_prorated_subscription()) {
                 self::$coupon_error = $error_message;
             }
         }
     } else {
         // prevent subscription coupons from being applied to renewal payments
         if (WC_Subscriptions_Cart::cart_contains_subscription_renewal('child')) {
             self::$coupon_error = __('Sorry, this coupon is only valid for new subscriptions.', 'woocommerce-subscriptions');
         }
         // prevent subscription coupons from being applied to non-subscription products
         if (!WC_Subscriptions_Cart::cart_contains_subscription_renewal() && !WC_Subscriptions_Cart::cart_contains_subscription()) {
             self::$coupon_error = __('Sorry, this coupon is only valid for subscription products.', 'woocommerce-subscriptions');
         }
         // prevent sign up fee coupons from being applied to subscriptions without a sign up fee
         if (0 == WC_Subscriptions_Cart::get_cart_subscription_sign_up_fee() && in_array($coupon->type, array('sign_up_fee', 'sign_up_fee_percent'))) {
             self::$coupon_error = __('Sorry, this coupon is only valid for subscription products with a sign-up fee.', 'woocommerce-subscriptions');
         }
     }
     if (!empty(self::$coupon_error)) {
         $valid = false;
         add_filter('woocommerce_coupon_error', __CLASS__ . '::add_coupon_error', 10);
     }
     return $valid;
 }
コード例 #15
0
/**
 * Creates a subscription price string from an array of subscription details. For example, "$5 / month for 12 months".
 *
 * @param array $subscription_details A set of name => value pairs for the subscription details to include in the string. Available keys:
 *		'initial_amount': The upfront payment for the subscription, including sign up fees, as a string from the @see wc_price(). Default empty string (no initial payment)
 *		'initial_description': The word after the initial payment amount to describe the amount. Examples include "now" or "initial payment". Defaults to "up front".
 *		'recurring_amount': The amount charged per period. Default 0 (no recurring payment).
 *		'subscription_interval': How regularly the subscription payments are charged. Default 1, meaning each period e.g. per month.
 *		'subscription_period': The temporal period of the subscription. Should be one of {day|week|month|year} as used by @see wcs_get_subscription_period_strings()
 *		'subscription_length': The total number of periods the subscription should continue for. Default 0, meaning continue indefinitely.
 *		'trial_length': The total number of periods the subscription trial period should continue for.  Default 0, meaning no trial period.
 *		'trial_period': The temporal period for the subscription's trial period. Should be one of {day|week|month|year} as used by @see wcs_get_subscription_period_strings()
 * @since 2.0
 * @return string The price string with translated and billing periods included
 */
function wcs_price_string($subscription_details)
{
    global $wp_locale;
    $subscription_details = wp_parse_args($subscription_details, array('currency' => '', 'initial_amount' => '', 'initial_description' => _x('up front', 'initial payment on a subscription', 'woocommerce-subscriptions'), 'recurring_amount' => '', 'subscription_interval' => 1, 'subscription_period' => '', 'subscription_length' => 0, 'trial_length' => 0, 'trial_period' => '', 'is_synced' => false, 'synchronised_payment_day' => 0, 'display_excluding_tax_label' => false));
    $subscription_details['subscription_period'] = strtolower($subscription_details['subscription_period']);
    // Make sure prices have been through wc_price()
    if (is_numeric($subscription_details['initial_amount'])) {
        $initial_amount_string = wc_price($subscription_details['initial_amount'], array('currency' => $subscription_details['currency'], 'ex_tax_label' => $subscription_details['display_excluding_tax_label']));
    } else {
        $initial_amount_string = $subscription_details['initial_amount'];
    }
    if (is_numeric($subscription_details['recurring_amount'])) {
        $recurring_amount_string = wc_price($subscription_details['recurring_amount'], array('currency' => $subscription_details['currency'], 'ex_tax_label' => $subscription_details['display_excluding_tax_label']));
    } else {
        $recurring_amount_string = $subscription_details['recurring_amount'];
    }
    $subscription_period_string = wcs_get_subscription_period_strings($subscription_details['subscription_interval'], $subscription_details['subscription_period']);
    $subscription_ranges = wcs_get_subscription_ranges();
    if ($subscription_details['subscription_length'] > 0 && $subscription_details['subscription_length'] == $subscription_details['subscription_interval']) {
        if (!empty($subscription_details['initial_amount'])) {
            if ($subscription_details['subscription_interval'] == $subscription_details['subscription_length'] && 0 == $subscription_details['trial_length']) {
                $subscription_string = $initial_amount_string;
            } else {
                // translators: 1$: initial amount, 2$: initial description (e.g. "up front"), 3$: recurring amount string (e.g. "£10 / month" )
                $subscription_string = sprintf(__('%1$s %2$s then %3$s', 'woocommerce-subscriptions'), $initial_amount_string, $subscription_details['initial_description'], $recurring_amount_string);
            }
        } else {
            $subscription_string = $recurring_amount_string;
        }
    } elseif (true === $subscription_details['is_synced'] && in_array($subscription_details['subscription_period'], array('week', 'month', 'year'))) {
        // Verbosity is important here to enable translation
        $payment_day = $subscription_details['synchronised_payment_day'];
        switch ($subscription_details['subscription_period']) {
            case 'week':
                $payment_day_of_week = WC_Subscriptions_Synchroniser::get_weekday($payment_day);
                if (1 == $subscription_details['subscription_interval']) {
                    if (!empty($subscription_details['initial_amount'])) {
                        // translators: 1$: initial amount, 2$: initial description (e.g. "up front"), 3$: recurring amount string, 4$: payment day of the week (e.g. "$15 up front, then $10 every Wednesday")
                        $subscription_string = sprintf(__('%1$s %2$s then %3$s every %4$s', 'woocommerce-subscriptions'), $initial_amount_string, $subscription_details['initial_description'], $recurring_amount_string, $payment_day_of_week);
                    } else {
                        // translators: 1$: recurring amount string, 2$: day of the week (e.g. "$10 every Wednesday")
                        $subscription_string = sprintf(__('%1$s every %2$s', 'woocommerce-subscriptions'), $recurring_amount_string, $payment_day_of_week);
                    }
                } else {
                    // e.g. $5 every 2 weeks on Wednesday
                    if (!empty($subscription_details['initial_amount'])) {
                        // translators: 1$: initial amount, 2$: initial description (e.g. "up front" ), 3$: recurring amount, 4$: interval (e.g. "2nd week"), 5$: day of the week (e.g. "Thursday"); (e.g. "$10 up front, then $20 every 2nd week on Wednesday")
                        $subscription_string = sprintf(__('%1$s %2$s then %3$s every %4%s on %5$s', 'woocommerce-subscriptions'), $initial_amount_string, $subscription_details['initial_description'], $recurring_amount_string, wcs_get_subscription_period_strings($subscription_details['subscription_interval'], $subscription_details['subscription_period']), $payment_day_of_week);
                    } else {
                        // translators: 1$: recurring amount string, 2$: interval (e.g. "2nd week"), 3$: day of the week (e.g. "Thursday"); (e.g. "$10 every 2nd week on Wednesday")
                        $subscription_string = sprintf(__('%1$s every %2$s on %3$s', 'woocommerce-subscriptions'), $recurring_amount_string, wcs_get_subscription_period_strings($subscription_details['subscription_interval'], $subscription_details['subscription_period']), $payment_day_of_week);
                    }
                }
                break;
            case 'month':
                if (1 == $subscription_details['subscription_interval']) {
                    // e.g. $15 on the 15th of each month
                    if (!empty($subscription_details['initial_amount'])) {
                        if ($payment_day > 27) {
                            // translators: 1$: initial amount, 2$: initial description (e.g. "up front"), 3$: recurring amount; (e.g. "$10 up front then $30 on the last day of each month")
                            $subscription_string = sprintf(__('%1$s %2$s then %3$s on the last day of each month', 'woocommerce-subscriptions'), $initial_amount_string, $subscription_details['initial_description'], $recurring_amount_string);
                        } else {
                            // translators: 1$: initial amount, 2$: initial description (e.g. "up front"), 3$: recurring amount, 4$: day of the month (e.g. "23rd"); (e.g. "$10 up front then $40 on the 23rd of each month")
                            $subscription_string = sprintf(__('%1$s %2$s then %3$s on the %4$s of each month', 'woocommerce-subscriptions'), $initial_amount_string, $subscription_details['initial_description'], $recurring_amount_string, WC_Subscriptions::append_numeral_suffix($payment_day));
                        }
                    } else {
                        if ($payment_day > 27) {
                            // translators: placeholder is recurring amount
                            $subscription_string = sprintf(__('%s on the last day of each month', 'woocommerce-subscriptions'), $recurring_amount_string);
                        } else {
                            // translators: 1$: recurring amount, 2$: day of the month (e.g. "23rd")
                            $subscription_string = sprintf(__('%1$s on the %2$s of each month', 'woocommerce-subscriptions'), $recurring_amount_string, WC_Subscriptions::append_numeral_suffix($payment_day));
                        }
                    }
                } else {
                    // e.g. $15 on the 15th of every 3rd month
                    if (!empty($subscription_details['initial_amount'])) {
                        if ($payment_day > 27) {
                            // translators: 1$: initial amount, 2$: initial description (e.g. "up front"), 3$: recurring amount, 4$: interval (e.g. "3rd")
                            $subscription_string = sprintf(__('%1$s %2$s then %3$s on the last day of every %4$s month', 'woocommerce-subscriptions'), $initial_amount_string, $subscription_details['initial_description'], $recurring_amount_string, WC_Subscriptions::append_numeral_suffix($subscription_details['subscription_interval']));
                        } else {
                            // translators: 1$: initial amount, 2$: initial description (e.g. "up front"), 3$: recurring amount, 4$: day of the month (e.g. "23rd"), 5$: interval (e.g. "3rd")
                            $subscription_string = sprintf(__('%1$s %2$s then %3$s on the %4$s day of every %5$s month', 'woocommerce-subscriptions'), $initial_amount_string, $subscription_details['initial_description'], $recurring_amount_string, WC_Subscriptions::append_numeral_suffix($payment_day), WC_Subscriptions::append_numeral_suffix($subscription_details['subscription_interval']));
                        }
                    } else {
                        if ($payment_day > 27) {
                            // translators: 1$: recurring amount, 2$: interval (e.g. "3rd")
                            $subscription_string = sprintf(__('%1$s on the last day of every %2$s month', 'woocommerce-subscriptions'), $recurring_amount_string, WC_Subscriptions::append_numeral_suffix($subscription_details['subscription_interval']));
                        } else {
                            // translators: 1$: recurring amount, 2$: day in month (e.g. "23rd"), 3$: interval (e.g. "3rd")
                            $subscription_string = sprintf(__('%1$s on the %2$s day of every %3$s month', 'woocommerce-subscriptions'), $recurring_amount_string, WC_Subscriptions::append_numeral_suffix($payment_day), WC_Subscriptions::append_numeral_suffix($subscription_details['subscription_interval']));
                        }
                    }
                }
                break;
            case 'year':
                if (1 == $subscription_details['subscription_interval']) {
                    // e.g. $15 on March 15th each year
                    if (!empty($subscription_details['initial_amount'])) {
                        // translators: 1$: initial amount, 2$: intial description (e.g. "up front"), 3$: recurring amount, 4$: month of year (e.g. "March"), 5$: day of the month (e.g. "23rd")
                        $subscription_string = sprintf(__('%1$s %2$s then %3$s on %4$s %5$s each year', 'woocommerce-subscriptions'), $initial_amount_string, $subscription_details['initial_description'], $recurring_amount_string, $wp_locale->month[$payment_day['month']], WC_Subscriptions::append_numeral_suffix($payment_day['day']));
                    } else {
                        // translators: 1$: recurring amount, 2$: month (e.g. "March"), 3$: day of the month (e.g. "23rd")
                        $subscription_string = sprintf(__('%1$s on %2$s %3$s each year', 'woocommerce-subscriptions'), $recurring_amount_string, $wp_locale->month[$payment_day['month']], WC_Subscriptions::append_numeral_suffix($payment_day['day']));
                    }
                } else {
                    // e.g. $15 on March 15th every 3rd year
                    if (!empty($subscription_details['initial_amount'])) {
                        // translators: 1$: initial amount, 2$: initial description (e.g. "up front"), 3$: recurring amount, 4$: month (e.g. "March"), 5$: day of the month (e.g. "23rd"), 6$: interval (e.g. "3rd")
                        $subscription_string = sprintf(__('%1$s %2$s then %3$s on %4$s %5$s every %6$s year', 'woocommerce-subscriptions'), $initial_amount_string, $subscription_details['initial_description'], $recurring_amount_string, $wp_locale->month[$payment_day['month']], WC_Subscriptions::append_numeral_suffix($payment_day['day']), WC_Subscriptions::append_numeral_suffix($subscription_details['subscription_interval']));
                    } else {
                        // translators: 1$: recurring amount, 2$: month (e.g. "March"), 3$: day of month (e.g. "23rd"), 4$: interval (e.g. "3rd")
                        $subscription_string = sprintf(__('%1$s on %2$s %3$s every %4$s year', 'woocommerce-subscriptions'), $recurring_amount_string, $wp_locale->month[$payment_day['month']], WC_Subscriptions::append_numeral_suffix($payment_day['day']), WC_Subscriptions::append_numeral_suffix($subscription_details['subscription_interval']));
                    }
                }
                break;
        }
    } elseif (!empty($subscription_details['initial_amount'])) {
        // translators: 1$: initial amount, 2$: initial description (e.g. "up front"), 3$: recurring amount, 4$: subscription period (e.g. "month" or "3 months")
        $subscription_string = sprintf(_n('%1$s %2$s then %3$s / %4$s', '%1$s %2$s then %3$s every %4$s', $subscription_details['subscription_interval'], 'woocommerce-subscriptions'), $initial_amount_string, $subscription_details['initial_description'], $recurring_amount_string, $subscription_period_string);
    } elseif (!empty($subscription_details['recurring_amount']) || intval($subscription_details['recurring_amount']) === 0) {
        // translators: 1$: recurring amount, 2$: subscription period (e.g. "month" or "3 months")
        $subscription_string = sprintf(_n('%1$s / %2$s', ' %1$s every %2$s', $subscription_details['subscription_interval'], 'woocommerce-subscriptions'), $recurring_amount_string, $subscription_period_string);
    } else {
        $subscription_string = '';
    }
    if ($subscription_details['subscription_length'] > 0) {
        // translators: 1$: subscription string (e.g. "$10 up front then $5 on March 23rd every 3rd year"), 2$: length (e.g. "4 years")
        $subscription_string = sprintf(__('%1$s for %2$s', 'woocommerce-subscriptions'), $subscription_string, $subscription_ranges[$subscription_details['subscription_period']][$subscription_details['subscription_length']]);
    }
    if ($subscription_details['trial_length'] > 0) {
        $trial_length = wcs_get_subscription_trial_period_strings($subscription_details['trial_length'], $subscription_details['trial_period']);
        if (!empty($subscription_details['initial_amount'])) {
            // translators: 1$: subscription string (e.g. "$10 up front then $5 on March 23rd every 3rd year"), 2$: trial length (e.g. "3 weeks")
            $subscription_string = sprintf(__('%1$s after %2$s free trial', 'woocommerce-subscriptions'), $subscription_string, $trial_length);
        } else {
            // translators: 1$: trial length (e.g. "3 weeks"), 2$: subscription string (e.g. "$10 up front then $5 on March 23rd every 3rd year")
            $subscription_string = sprintf(__('%1$s free trial then %2$s', 'woocommerce-subscriptions'), ucfirst($trial_length), $subscription_string);
        }
    }
    if ($subscription_details['display_excluding_tax_label'] && get_option('woocommerce_calc_taxes') == 'yes') {
        $subscription_string .= ' <small>' . WC()->countries->ex_tax_or_vat() . '</small>';
    }
    return apply_filters('woocommerce_subscription_price_string', $subscription_string, $subscription_details);
}
コード例 #16
0
 /**
  * Creates a subscription price string from an array of subscription details. For example, ""$5 / month for 12 months".
  *
  * @param array $subscription_details A set of name => value pairs for the subscription details to include in the string. Available keys:
  *		'initial_amount': The upfront payment for the subscription, including sign up fees, as a string from the @see woocommerce_price(). Default empty string (no initial payment)
  *		'initial_description': The word after the initial payment amount to describe the amount. Examples include "now" or "initial payment". Defaults to "up front".
  *		'recurring_amount': The amount charged per period. Default 0 (no recurring payment).
  *		'subscription_interval': How regularly the subscription payments are charged. Default 1, meaning each period e.g. per month.
  *		'subscription_period': The temporal period of the subscription. Should be one of {day|week|month|year} as used by @see self::get_subscription_period_strings()
  *		'subscription_length': The total number of periods the subscription should continue for. Default 0, meaning continue indefinitely.
  *		'trial_length': The total number of periods the subscription trial period should continue for.  Default 0, meaning no trial period.
  *		'trial_period': The temporal period for the subscription's trial period. Should be one of {day|week|month|year} as used by @see self::get_subscription_period_strings()
  * @since 1.2
  * @return float $proportion A proportion of the total (e.g. 0.5 is half of the total)
  */
 public static function get_subscription_price_string($subscription_details)
 {
     global $wp_locale;
     $subscription_details = wp_parse_args($subscription_details, array('currency' => '', 'initial_amount' => '', 'initial_description' => __('up front', 'woocommerce-subscriptions'), 'recurring_amount' => '', 'subscription_interval' => 1, 'subscription_period' => '', 'subscription_length' => 0, 'trial_length' => 0, 'trial_period' => '', 'is_synced' => false, 'synchronised_payment_day' => 0));
     $subscription_details['subscription_period'] = strtolower($subscription_details['subscription_period']);
     // Make sure prices have been through woocommerce_price()
     $initial_amount_string = is_numeric($subscription_details['initial_amount']) ? woocommerce_price($subscription_details['initial_amount'], array('currency' => $subscription_details['currency'])) : $subscription_details['initial_amount'];
     $recurring_amount_string = is_numeric($subscription_details['recurring_amount']) ? woocommerce_price($subscription_details['recurring_amount'], array('currency' => $subscription_details['currency'])) : $subscription_details['recurring_amount'];
     $subscription_period_string = self::get_subscription_period_strings($subscription_details['subscription_interval'], $subscription_details['subscription_period']);
     $subscription_ranges = self::get_subscription_ranges();
     if ($subscription_details['subscription_length'] > 0 && $subscription_details['subscription_length'] == $subscription_details['subscription_interval']) {
         if (!empty($subscription_details['initial_amount'])) {
             if ($subscription_details['subscription_length'] == $subscription_details['subscription_interval'] && $subscription_details['trial_length'] == 0) {
                 $subscription_string = $initial_amount_string;
             } else {
                 $subscription_string = sprintf(__('%s %s then %s', 'woocommerce-subscriptions'), $initial_amount_string, $subscription_details['initial_description'], $recurring_amount_string);
             }
         } else {
             $subscription_string = $recurring_amount_string;
         }
     } elseif (true === $subscription_details['is_synced'] && in_array($subscription_details['subscription_period'], array('week', 'month', 'year'))) {
         // Verbosity is important here to enable translation
         $payment_day = $subscription_details['synchronised_payment_day'];
         switch ($subscription_details['subscription_period']) {
             case 'week':
                 $payment_day_of_week = WC_Subscriptions_Synchroniser::get_weekday($payment_day);
                 if (1 == $subscription_details['subscription_interval']) {
                     // e.g. $5 every Wednesday
                     if (!empty($subscription_details['initial_amount'])) {
                         $subscription_string = sprintf(__('%s %s then %s every %s', 'woocommerce-subscriptions'), $initial_amount_string, $subscription_details['initial_description'], $recurring_amount_string, $payment_day_of_week);
                     } else {
                         $subscription_string = sprintf(__('%s every %s', 'woocommerce-subscriptions'), $recurring_amount_string, $payment_day_of_week);
                     }
                 } else {
                     // e.g. $5 every 2 weeks on Wednesday
                     if (!empty($subscription_details['initial_amount'])) {
                         $subscription_string = sprintf(__('%s %s then %s every %s on %s', 'woocommerce-subscriptions'), $initial_amount_string, $subscription_details['initial_description'], $recurring_amount_string, WC_Subscriptions_Manager::get_subscription_period_strings($subscription_details['subscription_interval'], $subscription_details['subscription_period']), $payment_day_of_week);
                     } else {
                         $subscription_string = sprintf(__('%s every %s on %s', 'woocommerce-subscriptions'), $recurring_amount_string, WC_Subscriptions_Manager::get_subscription_period_strings($subscription_details['subscription_interval'], $subscription_details['subscription_period']), $payment_day_of_week);
                     }
                 }
                 break;
             case 'month':
                 if (1 == $subscription_details['subscription_interval']) {
                     // e.g. $15 on the 15th of each month
                     if (!empty($subscription_details['initial_amount'])) {
                         if ($payment_day > 27) {
                             $subscription_string = sprintf(__('%s %s then %s on the last day of each month', 'woocommerce-subscriptions'), $initial_amount_string, $subscription_details['initial_description'], $recurring_amount_string);
                         } else {
                             $subscription_string = sprintf(__('%s %s then %s on the %s of each month', 'woocommerce-subscriptions'), $initial_amount_string, $subscription_details['initial_description'], $recurring_amount_string, WC_Subscriptions::append_numeral_suffix($payment_day));
                         }
                     } else {
                         if ($payment_day > 27) {
                             $subscription_string = sprintf(__('%s on the last day of each month', 'woocommerce-subscriptions'), $recurring_amount_string);
                         } else {
                             $subscription_string = sprintf(__('%s on the %s of each month', 'woocommerce-subscriptions'), $recurring_amount_string, WC_Subscriptions::append_numeral_suffix($payment_day));
                         }
                     }
                 } else {
                     // e.g. $15 on the 15th of every 3rd month
                     if (!empty($subscription_details['initial_amount'])) {
                         if ($payment_day > 27) {
                             $subscription_string = sprintf(__('%s %s then %s on the last day of every %s month', 'woocommerce-subscriptions'), $initial_amount_string, $subscription_details['initial_description'], $recurring_amount_string, WC_Subscriptions::append_numeral_suffix($subscription_details['subscription_interval']));
                         } else {
                             $subscription_string = sprintf(__('%s %s then %s on the %s day of every %s month', 'woocommerce-subscriptions'), $initial_amount_string, $subscription_details['initial_description'], $recurring_amount_string, WC_Subscriptions::append_numeral_suffix($payment_day), WC_Subscriptions::append_numeral_suffix($subscription_details['subscription_interval']));
                         }
                     } else {
                         if ($payment_day > 27) {
                             $subscription_string = sprintf(__('%s on the last day of every %s month', 'woocommerce-subscriptions'), $recurring_amount_string, WC_Subscriptions::append_numeral_suffix($subscription_details['subscription_interval']));
                         } else {
                             $subscription_string = sprintf(__('%s on the %s day of every %s month', 'woocommerce-subscriptions'), $recurring_amount_string, WC_Subscriptions::append_numeral_suffix($payment_day), WC_Subscriptions::append_numeral_suffix($subscription_details['subscription_interval']));
                         }
                     }
                 }
                 break;
             case 'year':
                 if (1 == $subscription_details['subscription_interval']) {
                     // e.g. $15 on March 15th each year
                     if (!empty($subscription_details['initial_amount'])) {
                         $subscription_string = sprintf(__('%s %s then %s on %s %s each year', 'woocommerce-subscriptions'), $initial_amount_string, $subscription_details['initial_description'], $recurring_amount_string, $wp_locale->month[$payment_day['month']], WC_Subscriptions::append_numeral_suffix($payment_day['day']));
                     } else {
                         $subscription_string = sprintf(__('%s on %s %s each year', 'woocommerce-subscriptions'), $recurring_amount_string, $wp_locale->month[$payment_day['month']], WC_Subscriptions::append_numeral_suffix($payment_day['day']));
                     }
                 } else {
                     // e.g. $15 on March 15th every 3rd year
                     if (!empty($subscription_details['initial_amount'])) {
                         $subscription_string = sprintf(__('%s %s then %s on %s %s every %s year', 'woocommerce-subscriptions'), $initial_amount_string, $subscription_details['initial_description'], $recurring_amount_string, $wp_locale->month[$payment_day['month']], WC_Subscriptions::append_numeral_suffix($payment_day['day']), WC_Subscriptions::append_numeral_suffix($subscription_details['subscription_interval']));
                     } else {
                         $subscription_string = sprintf(__('%s on %s %s every %s year', 'woocommerce-subscriptions'), $recurring_amount_string, $wp_locale->month[$payment_day['month']], WC_Subscriptions::append_numeral_suffix($payment_day['day']), WC_Subscriptions::append_numeral_suffix($subscription_details['subscription_interval']));
                     }
                 }
                 break;
         }
     } elseif (!empty($subscription_details['initial_amount'])) {
         $subscription_string = sprintf(_n('%s %s then %s / %s', '%s %s then %s every %s', $subscription_details['subscription_interval'], 'woocommerce-subscriptions'), $initial_amount_string, $subscription_details['initial_description'], $recurring_amount_string, $subscription_period_string);
     } elseif (!empty($subscription_details['recurring_amount']) || intval($subscription_details['recurring_amount']) === 0) {
         $subscription_string = sprintf(_n('%s / %s', ' %s every %s', $subscription_details['subscription_interval'], 'woocommerce-subscriptions'), $recurring_amount_string, $subscription_period_string);
     } else {
         $subscription_string = '';
     }
     if ($subscription_details['subscription_length'] > 0) {
         $subscription_string = sprintf(__('%s for %s', 'woocommerce-subscriptions'), $subscription_string, $subscription_ranges[$subscription_details['subscription_period']][$subscription_details['subscription_length']]);
     }
     if ($subscription_details['trial_length'] > 0) {
         $trial_length = self::get_subscription_trial_period_strings($subscription_details['trial_length'], $subscription_details['trial_period']);
         if (!empty($subscription_details['initial_amount'])) {
             $subscription_string = sprintf(__('%s after %s free trial', 'woocommerce-subscriptions'), $subscription_string, $trial_length);
         } else {
             $subscription_string = sprintf(__('%s free trial then %s', 'woocommerce-subscriptions'), ucfirst($trial_length), $subscription_string);
         }
     }
     return apply_filters('woocommerce_subscription_price_string', $subscription_string, $subscription_details);
 }
 /**
  * Returns a string representing the details of the subscription. 
  *
  * For example "$20 per Month for 3 Months with a $10 sign-up fee".
  *
  * @param WC_Product|int $product A WC_Product object or ID of a WC_Product.
  * @param array $inclusions An associative array of flags to indicate how to calculate the price and what to include, values:
  *			'tax_calculation'     => false to ignore tax, 'include_tax' or 'exclude_tax' To indicate that tax should be added or excluded respectively
  *			'subscription_length' => true to include subscription's length (default) or false to exclude it
  *			'sign_up_fee'         => true to include subscription's sign up fee (default) or false to exclude it
  *			'price'               => string a price to short-circuit the price calculations and use in a string for the product
  * @since 1.0
  */
 public static function get_price_string($product, $include = array())
 {
     global $wp_locale;
     if (!is_object($product)) {
         $product = WC_Subscriptions::get_product($product);
     }
     if (!self::is_subscription($product)) {
         return;
     }
     $include = wp_parse_args($include, array('tax_calculation' => get_option('woocommerce_tax_display_shop'), 'subscription_price' => true, 'subscription_period' => true, 'subscription_length' => true, 'sign_up_fee' => true, 'trial_length' => true));
     $include = apply_filters('woocommerce_subscriptions_product_price_string_inclusions', $include, $product);
     $base_price = self::get_price($product);
     if (true === $include['sign_up_fee']) {
         $sign_up_fee = self::get_sign_up_fee($product);
     } elseif (false !== $include['sign_up_fee']) {
         // Allow override of product's sign-up fee
         $sign_up_fee = $include['sign_up_fee'];
     } else {
         $sign_up_fee = 0;
     }
     if ($include['tax_calculation'] != false) {
         if (in_array($include['tax_calculation'], array('exclude_tax', 'excl'))) {
             // Subtract Tax
             if (isset($include['price'])) {
                 $price = $include['price'];
             } else {
                 $price = $product->get_price_excluding_tax(1, $include['price']);
             }
             if (true === $include['sign_up_fee']) {
                 $sign_up_fee = $product->get_sign_up_fee_excluding_tax();
             }
         } else {
             // Add Tax
             if (isset($include['price'])) {
                 $price = $include['price'];
             } else {
                 $price = $product->get_price_including_tax();
             }
             if (true === $include['sign_up_fee']) {
                 $sign_up_fee = $product->get_sign_up_fee_including_tax();
             }
         }
     } else {
         if (isset($include['price'])) {
             $price = $include['price'];
         } else {
             $price = woocommerce_price($base_price);
         }
     }
     $price .= ' <span class="subscription-details">';
     $billing_interval = self::get_interval($product);
     $billing_period = self::get_period($product);
     $subscription_length = self::get_length($product);
     $trial_length = self::get_trial_length($product);
     $trial_period = self::get_trial_period($product);
     if (is_numeric($sign_up_fee)) {
         $sign_up_fee = woocommerce_price($sign_up_fee);
     }
     if ($include['subscription_length']) {
         $ranges = WC_Subscriptions_Manager::get_subscription_ranges($billing_period);
     }
     if ($include['subscription_length'] && $subscription_length != 0) {
         $include_length = true;
     } else {
         $include_length = false;
     }
     $subscription_string = '';
     if ($include['subscription_price'] && $include['subscription_period']) {
         // Allow extensions to not show price or billing period e.g. Name Your Price
         if ($include_length && $subscription_length == $billing_interval) {
             $subscription_string = $price;
             // Only for one billing period so show "$5 for 3 months" instead of "$5 every 3 months for 3 months"
         } elseif (WC_Subscriptions_Synchroniser::is_product_synced($product) && in_array($billing_period, array('week', 'month', 'year'))) {
             $payment_day = WC_Subscriptions_Synchroniser::get_products_payment_day($product);
             switch ($billing_period) {
                 case 'week':
                     $payment_day_of_week = WC_Subscriptions_Synchroniser::get_weekday($payment_day);
                     if (1 == $billing_interval) {
                         // e.g. $5 every Wednesday
                         $subscription_string = sprintf(__('%s every %s', 'woocommerce-subscriptions'), $price, $payment_day_of_week);
                     } else {
                         // e.g. $5 every 2 weeks on Wednesday
                         $subscription_string = sprintf(__('%s every %s on %s', 'woocommerce-subscriptions'), $price, WC_Subscriptions_Manager::get_subscription_period_strings($billing_interval, $billing_period), $payment_day_of_week);
                     }
                     break;
                 case 'month':
                     if (1 == $billing_interval) {
                         // e.g. $15 on the 15th of each month
                         if ($payment_day > 27) {
                             $subscription_string = sprintf(__('%s on the last day of each month', 'woocommerce-subscriptions'), $price);
                         } else {
                             $subscription_string = sprintf(__('%s on the %s of each month', 'woocommerce-subscriptions'), $price, WC_Subscriptions::append_numeral_suffix($payment_day));
                         }
                     } else {
                         // e.g. $15 on the 15th of every 3rd month
                         if ($payment_day > 27) {
                             $subscription_string = sprintf(__('%s on the last day of every %s month', 'woocommerce-subscriptions'), $price, WC_Subscriptions::append_numeral_suffix($billing_interval));
                         } else {
                             $subscription_string = sprintf(__('%s on the %s day of every %s month', 'woocommerce-subscriptions'), $price, WC_Subscriptions::append_numeral_suffix($payment_day), WC_Subscriptions::append_numeral_suffix($billing_interval));
                         }
                     }
                     break;
                 case 'year':
                     if (1 == $billing_interval) {
                         // e.g. $15 on March 15th each year
                         $subscription_string = sprintf(__('%s on %s %s each year', 'woocommerce-subscriptions'), $price, $wp_locale->month[$payment_day['month']], WC_Subscriptions::append_numeral_suffix($payment_day['day']));
                     } else {
                         // e.g. $15 on March 15th every 3rd year
                         $subscription_string = sprintf(__('%s on %s %s every %s year', 'woocommerce-subscriptions'), $price, $wp_locale->month[$payment_day['month']], WC_Subscriptions::append_numeral_suffix($payment_day['day']), WC_Subscriptions::append_numeral_suffix($billing_interval));
                     }
                     break;
             }
         } else {
             $subscription_string = sprintf(_n('%s / %s', ' %s every %s', $billing_interval, 'woocommerce-subscriptions'), $price, WC_Subscriptions_Manager::get_subscription_period_strings($billing_interval, $billing_period));
         }
     } elseif ($include['subscription_price']) {
         $subscription_string = $price;
     } elseif ($include['subscription_period']) {
         $subscription_string = sprintf(_n('%s', 'every %s', $billing_interval, 'woocommerce-subscriptions'), WC_Subscriptions_Manager::get_subscription_period_strings($billing_interval, $billing_period));
     }
     // Add the length to the end
     if ($include_length) {
         $subscription_string = sprintf(__('%s for %s', 'woocommerce-subscriptions'), $subscription_string, $ranges[$subscription_length]);
     }
     if ($include['trial_length'] && $trial_length != 0) {
         $trial_string = WC_Subscriptions_Manager::get_subscription_trial_period_strings($trial_length, $trial_period);
         $subscription_string = sprintf(__('%s with %s free trial', 'woocommerce-subscriptions'), $subscription_string, $trial_string);
     }
     if ($include['sign_up_fee'] && self::get_sign_up_fee($product) > 0) {
         $subscription_string = sprintf(__('%s and a %s sign-up fee', 'woocommerce-subscriptions'), $subscription_string, $sign_up_fee);
     }
     $subscription_string .= '</span>';
     return apply_filters('woocommerce_subscriptions_product_price_string', $subscription_string, $product, $include);
 }
コード例 #18
0
 /**
  * Returns a string representing the details of the subscription.
  *
  * For example "$20 per Month for 3 Months with a $10 sign-up fee".
  *
  * @param WC_Product|int $product A WC_Product object or ID of a WC_Product.
  * @param array $inclusions An associative array of flags to indicate how to calculate the price and what to include, values:
  *			'tax_calculation'     => false to ignore tax, 'include_tax' or 'exclude_tax' To indicate that tax should be added or excluded respectively
  *			'subscription_length' => true to include subscription's length (default) or false to exclude it
  *			'sign_up_fee'         => true to include subscription's sign up fee (default) or false to exclude it
  *			'price'               => string a price to short-circuit the price calculations and use in a string for the product
  * @since 1.0
  */
 public static function get_price_string($product, $include = array())
 {
     global $wp_locale;
     if (!is_object($product)) {
         $product = WC_Subscriptions::get_product($product);
     }
     if (!self::is_subscription($product)) {
         return;
     }
     $include = wp_parse_args($include, array('tax_calculation' => get_option('woocommerce_tax_display_shop'), 'subscription_price' => true, 'subscription_period' => true, 'subscription_length' => true, 'sign_up_fee' => true, 'trial_length' => true));
     $include = apply_filters('woocommerce_subscriptions_product_price_string_inclusions', $include, $product);
     $base_price = self::get_price($product);
     if (true === $include['sign_up_fee']) {
         $sign_up_fee = self::get_sign_up_fee($product);
     } elseif (false !== $include['sign_up_fee']) {
         // Allow override of product's sign-up fee
         $sign_up_fee = $include['sign_up_fee'];
     } else {
         $sign_up_fee = 0;
     }
     if (false != $include['tax_calculation']) {
         if (in_array($include['tax_calculation'], array('exclude_tax', 'excl'))) {
             // Subtract Tax
             if (isset($include['price'])) {
                 $price = $include['price'];
             } else {
                 $price = $product->get_price_excluding_tax(1, $include['price']);
             }
             if (true === $include['sign_up_fee']) {
                 $sign_up_fee = self::get_sign_up_fee_excluding_tax($product);
             }
         } else {
             // Add Tax
             if (isset($include['price'])) {
                 $price = $include['price'];
             } else {
                 $price = $product->get_price_including_tax();
             }
             if (true === $include['sign_up_fee']) {
                 $sign_up_fee = self::get_sign_up_fee_including_tax($product);
             }
         }
     } else {
         if (isset($include['price'])) {
             $price = $include['price'];
         } else {
             $price = wc_price($base_price);
         }
     }
     $price .= ' <span class="subscription-details">';
     $billing_interval = self::get_interval($product);
     $billing_period = self::get_period($product);
     $subscription_length = self::get_length($product);
     $trial_length = self::get_trial_length($product);
     $trial_period = self::get_trial_period($product);
     if (is_numeric($sign_up_fee)) {
         $sign_up_fee = wc_price($sign_up_fee);
     }
     if ($include['subscription_length']) {
         $ranges = wcs_get_subscription_ranges($billing_period);
     }
     if ($include['subscription_length'] && 0 != $subscription_length) {
         $include_length = true;
     } else {
         $include_length = false;
     }
     $subscription_string = '';
     if ($include['subscription_price'] && $include['subscription_period']) {
         // Allow extensions to not show price or billing period e.g. Name Your Price
         if ($include_length && $subscription_length == $billing_interval) {
             $subscription_string = $price;
             // Only for one billing period so show "$5 for 3 months" instead of "$5 every 3 months for 3 months"
         } elseif (WC_Subscriptions_Synchroniser::is_product_synced($product) && in_array($billing_period, array('week', 'month', 'year'))) {
             $payment_day = WC_Subscriptions_Synchroniser::get_products_payment_day($product);
             switch ($billing_period) {
                 case 'week':
                     $payment_day_of_week = WC_Subscriptions_Synchroniser::get_weekday($payment_day);
                     if (1 == $billing_interval) {
                         // translators: 1$: recurring amount string, 2$: day of the week (e.g. "$10 every Wednesday")
                         $subscription_string = sprintf(__('%1$s every %2$s', 'woocommerce-subscriptions'), $price, $payment_day_of_week);
                     } else {
                         // translators: 1$: recurring amount string, 2$: period, 3$: day of the week (e.g. "$10 every 2nd week on Wednesday")
                         $subscription_string = sprintf(__('%1$s every %2$s on %3$s', 'woocommerce-subscriptions'), $price, wcs_get_subscription_period_strings($billing_interval, $billing_period), $payment_day_of_week);
                     }
                     break;
                 case 'month':
                     if (1 == $billing_interval) {
                         if ($payment_day > 27) {
                             // translators: placeholder is recurring amount
                             $subscription_string = sprintf(__('%s on the last day of each month', 'woocommerce-subscriptions'), $price);
                         } else {
                             // translators: 1$: recurring amount, 2$: day of the month (e.g. "23rd") (e.g. "$5 every 23rd of each month")
                             $subscription_string = sprintf(__('%1$s on the %2$s of each month', 'woocommerce-subscriptions'), $price, WC_Subscriptions::append_numeral_suffix($payment_day));
                         }
                     } else {
                         if ($payment_day > 27) {
                             // translators: 1$: recurring amount, 2$: interval (e.g. "3rd") (e.g. "$10 on the last day of every 3rd month")
                             $subscription_string = sprintf(__('%1$s on the last day of every %2$s month', 'woocommerce-subscriptions'), $price, WC_Subscriptions::append_numeral_suffix($billing_interval));
                         } else {
                             // translators: 1$: <price> on the, 2$: <date> day of every, 3$: <interval> month (e.g. "$10 on the 23rd day of every 2nd month")
                             $subscription_string = sprintf(__('%1$s on the %2$s day of every %3$s month', 'woocommerce-subscriptions'), $price, WC_Subscriptions::append_numeral_suffix($payment_day), WC_Subscriptions::append_numeral_suffix($billing_interval));
                         }
                     }
                     break;
                 case 'year':
                     if (1 == $billing_interval) {
                         // translators: 1$: <price> on, 2$: <date>, 3$: <month> each year (e.g. "$15 on March 15th each year")
                         $subscription_string = sprintf(__('%1$s on %2$s %3$s each year', 'woocommerce-subscriptions'), $price, $wp_locale->month[$payment_day['month']], WC_Subscriptions::append_numeral_suffix($payment_day['day']));
                     } else {
                         // translators: 1$: recurring amount, 2$: month (e.g. "March"), 3$: day of the month (e.g. "23rd") (e.g. "$15 on March 15th every 3rd year")
                         $subscription_string = sprintf(__('%1$s on %2$s %3$s every %4$s year', 'woocommerce-subscriptions'), $price, $wp_locale->month[$payment_day['month']], WC_Subscriptions::append_numeral_suffix($payment_day['day']), WC_Subscriptions::append_numeral_suffix($billing_interval));
                     }
                     break;
             }
         } else {
             // translators: 1$: recurring amount, 2$: subscription period (e.g. "month" or "3 months") (e.g. "$15 / month" or "$15 every 2nd month")
             $subscription_string = sprintf(_n('%1$s / %2$s', ' %1$s every %2$s', $billing_interval, 'woocommerce-subscriptions'), $price, wcs_get_subscription_period_strings($billing_interval, $billing_period));
         }
     } elseif ($include['subscription_price']) {
         $subscription_string = $price;
     } elseif ($include['subscription_period']) {
         // translators: billing period (e.g. "every week")
         $subscription_string = sprintf(__('every %s', 'woocommerce-subscriptions'), wcs_get_subscription_period_strings($billing_interval, $billing_period));
     }
     // Add the length to the end
     if ($include_length) {
         // translators: 1$: subscription string (e.g. "$10 up front then $5 on March 23rd every 3rd year"), 2$: length (e.g. "4 years")
         $subscription_string = sprintf(__('%1$s for %2$s', 'woocommerce-subscriptions'), $subscription_string, $ranges[$subscription_length]);
     }
     if ($include['trial_length'] && 0 != $trial_length) {
         $trial_string = wcs_get_subscription_trial_period_strings($trial_length, $trial_period);
         // translators: 1$: subscription string (e.g. "$15 on March 15th every 3 years for 6 years"), 2$: trial length (e.g.: "with 4 months free trial")
         $subscription_string = sprintf(__('%1$s with %2$s free trial', 'woocommerce-subscriptions'), $subscription_string, $trial_string);
     }
     if ($include['sign_up_fee'] && self::get_sign_up_fee($product) > 0) {
         // translators: 1$: subscription string (e.g. "$15 on March 15th every 3 years for 6 years with 2 months free trial"), 2$: signup fee price (e.g. "and a $30 sign-up fee")
         $subscription_string = sprintf(__('%1$s and a %2$s sign-up fee', 'woocommerce-subscriptions'), $subscription_string, $sign_up_fee);
     }
     $subscription_string .= '</span>';
     return apply_filters('woocommerce_subscriptions_product_price_string', $subscription_string, $product, $include);
 }