/**
  * 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;
 }
 /**
  * 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;
 }
 /**
  * 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;
 }