/** * process_scheduled_subscription_payment function. * * @param float $amount_to_charge The amount to charge. * @param WC_Order $order The WC_Order object of the order which the subscription was purchased in. * @param int $product_id The ID of the subscription product for which this payment relates. */ public function process_scheduled_subscription_payment($amount_to_charge, $order, $product_id) { $result = $this->process_subscription_payment($order, $amount_to_charge); if (is_wp_error($result)) { WC_Subscriptions_Manager::process_subscription_payment_failure_on_order($order, $product_id); } else { WC_Subscriptions_Manager::process_subscription_payments_on_order($order); } }
/** * scheduled_subscription_payment function. * * @param $amount_to_charge float The amount to charge. * @param $order WC_Order The WC_Order object of the order which the subscription was purchased in. * @param $product_id int The ID of the subscription product for which this payment relates. * @access public * @return void */ function scheduled_subscription_payment($amount_to_charge, $order, $product_id) { $result = $this->process_subscription_payment($order, $amount_to_charge); if (is_wp_error($result)) { $order->add_order_note(sprintf(__('eWAY subscription renewal failed - %s', 'wc-eway'), $this->response_message_lookup($result->get_error_message()))); WC_Subscriptions_Manager::process_subscription_payment_failure_on_order($order, $product_id); } else { WC_Subscriptions_Manager::process_subscription_payments_on_order($order); } }
/** * Process period_created event from webhook * @param $data array **/ private function subscription_renew($data) { $cycle = $data->bill->period->cycle; $subscription = $this->find_subscription_by_id($data->bill->subscription->code); $vindi_subscription_id = $data->bill->subscription->id; if ($this->subscription_has_order_in_cycle($vindi_subscription_id, $cycle)) { throw new Exception('Já existe o ciclo $cycle para a assinatura ' . $vindi_subscription_id . ' pedido ' . $subscription->id); } WC_Subscriptions_Manager::prepare_renewal($subscription->id); $order_id = $subscription->get_last_order(); $order = $this->find_order_by_id($order_id); add_post_meta($order->id, 'vindi_wc_cycle', $cycle); $this->container->logger->log('Novo PerÃodo criado: Pedido #' . $order->id); }
/** * Customise which actions are shown against a subscriptions order on the My Account page. * * @since 1.3 */ public static function filter_woocommerce_my_account_my_orders_actions($actions, $order) { if (WC_Subscriptions_Order::order_contains_subscription($order) || WC_Subscriptions_Renewal_Order::is_renewal($order)) { unset($actions['cancel']); if (is_numeric(get_post_meta($order->id, '_failed_order_replaced_by', true))) { unset($actions['pay']); } $original_order = WC_Subscriptions_Renewal_Order::get_parent_order($order); $order_items = WC_Subscriptions_Order::get_recurring_items($original_order); $first_order_item = reset($order_items); $product_id = WC_Subscriptions_Order::get_items_product_id($first_order_item); $subscription_key = WC_Subscriptions_Manager::get_subscription_key($original_order->id, $product_id); $subscription = WC_Subscriptions_Manager::get_users_subscription($original_order->customer_user, $subscription_key); if (empty($subscription) || !in_array($subscription['status'], array('on-hold', 'pending'))) { unset($actions['pay']); } } return $actions; }
public function add_subscription_args($args, $offer_id, $action) { if (empty($args) || $action == 'skip') { return $args; } $so_offers = new SO_Offers(); $user_details = $so_offers->get_user_details(); $user_has_bought = !empty($user_details['offer_rule_has_bought']) ? explode(',', $user_details['offer_rule_has_bought']) : array(); $subscriptions = WC_Subscriptions_Manager::get_users_subscriptions(); $preserve_keys = true; $subscriptions = array_reverse($subscriptions, $preserve_keys); foreach ($subscriptions as $subscription_key => $subscription) { if (in_array($subscription['product_id'], $user_has_bought) && 'active' == $subscription['status']) { $args['switch-subscription'] = $subscription_key; $args['auto-switch'] = 'true'; break; } } return $args; }
private function processSubscriptions() { global $wpdb; // check wether subscriptions addon is activated if (class_exists('WC_Subscriptions_Order') && WC_Subscriptions_Order::order_contains_subscription($this->order)) { $products = $this->order->get_items(); foreach ($products as $product) { if (is_array($product) && isset($product['product_id']) && intval($product['product_id']) > 0 && isset($product['subscription_period']) && $product['subscription_period'] != '') { // product is a subscription? $woo_sub_key = WC_Subscriptions_Manager::get_subscription_key($this->order_id, $product['product_id']); // required vars $amount = floatval(WC_Subscriptions_Order::get_recurring_total($this->order)) * 100; $currency = get_woocommerce_currency(); $interval = intval($product['subscription_interval']); $period = strtoupper($product['subscription_period']); $length = strtoupper($product['subscription_length']); if ($length > 0) { $periodOfValidity = $length . ' ' . $period; } else { $periodOfValidity = false; } $trial_end = strtotime(WC_Subscriptions_Product::get_trial_expiration_date($product['product_id'], get_gmt_from_date($this->order->order_date))); if ($trial_end === false) { $trial_time = 0; } else { $datediff = $trial_end - time(); $trial_time = ceil($datediff / (60 * 60 * 24)); } // md5 name $woo_sub_md5 = md5($amount . $currency . $interval . $trial_time); // get offer $name = 'woo_' . $product['product_id'] . '_' . $woo_sub_md5; $offer = $this->subscriptions->offerGetDetailByName($name); // check wether offer exists in paymill if ($offer === false) { // offer does not exist in paymill yet, create it $params = array('amount' => $amount, 'currency' => $currency, 'interval' => $interval . ' ' . $period, 'name' => $name, 'trial_period_days' => intval($trial_time)); $offer = $this->subscriptions->offerCreate($params); if ($GLOBALS['paymill_loader']->paymill_errors->status()) { $GLOBALS['paymill_loader']->paymill_errors->getErrors(); return false; } } // create user subscription $user_sub = $this->subscriptions->create($this->clientClass->getCurrentClientID(), $offer, $this->paymentClass->getPaymentID(), isset($_POST['paymill_delivery_date']) ? $_POST['paymill_delivery_date'] : false, $periodOfValidity); if ($GLOBALS['paymill_loader']->paymill_errors->status()) { //maybe offer cache is outdated, recache and try again $GLOBALS['paymill_loader']->paymill_errors->reset(); // reset error status $this->subscriptions->offerGetList(true); $params = array('amount' => $amount, 'currency' => $currency, 'interval' => $interval . ' ' . $period, 'name' => $name, 'trial_period_days' => intval($trial_time)); $offer = $this->subscriptions->offerCreate($params); if ($GLOBALS['paymill_loader']->paymill_errors->status()) { $GLOBALS['paymill_loader']->paymill_errors->getErrors(); return false; } $user_sub = $this->subscriptions->create($this->clientClass->getCurrentClientID(), $offer, $this->paymentClass->getPaymentID(), isset($_POST['paymill_delivery_date']) ? $_POST['paymill_delivery_date'] : false, $periodOfValidity); if ($GLOBALS['paymill_loader']->paymill_errors->status()) { $GLOBALS['paymill_loader']->paymill_errors->getErrors(); return false; } } $wpdb->query($wpdb->prepare('INSERT INTO ' . $wpdb->prefix . 'paymill_subscriptions (paymill_sub_id, woo_user_id, woo_offer_id) VALUES (%s, %s, %s)', array($user_sub, get_current_user_id(), $woo_sub_key))); // subscription successful do_action('paymill_woocommerce_subscription_created', array('product_id' => $product['product_id'], 'offer_id' => $offer)); return true; } } } else { return true; } }
/** * 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()) { if (!is_object($product)) { $product = WC_Subscriptions::get_product($product); } if (!self::is_subscription($product)) { return; } $include = wp_parse_args($include, array('tax_calculation' => false, '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 ($include['tax_calculation'] == 'exclude_tax') { // Subtract Tax $tax_per_period = self::calculate_tax_for_subscription($base_price, $product); if (isset($include['price'])) { $price = $include['price']; } else { $price = woocommerce_price($base_price - $tax_per_period); } if ($sign_up_fee > 0) { $sign_up_tax = self::calculate_tax_for_subscription($sign_up_fee, $product); $sign_up_fee = $sign_up_fee - $sign_up_tax; } } else { // Add Tax $tax_per_period = self::calculate_tax_for_subscription($base_price, $product, true); if (isset($include['price'])) { $price = $include['price']; } else { $price = woocommerce_price($base_price + $tax_per_period); } if ($sign_up_fee > 0) { $sign_up_tax = self::calculate_tax_for_subscription($sign_up_fee, $product, true); $sign_up_fee = $sign_up_fee - $sign_up_tax; } } } else { if (isset($include['price'])) { $price = $include['price']; } else { $price = woocommerce_price($base_price); } } $billing_interval = self::get_interval($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(self::get_period($product)); } 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" } else { $subscription_string = sprintf(_n(' %s / %s', ' %s every %s', $billing_interval, 'woocommerce-subscriptions'), $price, WC_Subscriptions_Manager::get_subscription_period_strings($billing_interval, self::get_period($product))); } } 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, self::get_period($product))); } // 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); } return apply_filters('woocommerce_subscriptions_product_price_string', $subscription_string, $product, $include); }
/** * Runs when an subscription is re-activated after suspension. * @since 1.3.3 * @access public * @param integer $user_id User ID * @param integer $subscription_key Subscription Unique Key * @return void */ public function sensei_woocommerce_reactivate_subscription($user_id, $subscription_key) { $subscription = WC_Subscriptions_Manager::get_users_subscription($user_id, $subscription_key); $order = new WC_Order($subscription['order_id']); $user = get_user_by('id', $order->user_id); $order_user = array(); $order_user['ID'] = $user->ID; $order_user['user_login'] = $user->user_login; $order_user['user_email'] = $user->user_email; $order_user['user_url'] = $user->user_url; $courses = $this->post_types->course->get_product_courses($subscription['product_id']); foreach ($courses as $course_item) { $update_course = $this->woocommerce_course_update($course_item->ID, $order_user); } // End For Loop }
/** * Add a 'new-payment-method' handler to the @see WC_Subscriptions_Manager::can_subscription_be_changed_to() function * to determine whether the recurring payment method on a subscription can be changed. * * For the recurring payment method to be changeable, the subscription must be active, have future (automatic) payments * and use a payment gateway which allows the subscription to be cancelled. * * @param bool $subscription_can_be_changed Flag of whether the subscription can be changed to * @param string $new_status_or_meta The status or meta data you want to change th subscription to. Can be 'active', 'on-hold', 'cancelled', 'expired', 'trash', 'deleted', 'failed', 'new-payment-date' or some other value attached to the 'woocommerce_can_subscription_be_changed_to' filter. * @param object $args Set of values used in @see WC_Subscriptions_Manager::can_subscription_be_changed_to() for determining if a subscription can be changes, include: * 'subscription_key' string A subscription key of the form created by @see WC_Subscriptions_Manager::get_subscription_key() * 'subscription' array Subscription of the form returned by @see WC_Subscriptions_Manager::get_subscription() * 'user_id' int The ID of the subscriber. * 'order' WC_Order The order which recorded the successful payment (to make up for the failed automatic payment). * 'payment_gateway' WC_Payment_Gateway The subscription's recurring payment gateway * 'order_uses_manual_payments' bool A boolean flag indicating whether the subscription requires manual renewal payment. * @since 1.4 */ public static function can_subscription_be_changed_to($subscription_can_be_changed, $new_status_or_meta, $args) { global $woocommerce; if ('new-payment-method' === $new_status_or_meta) { $next_payment_timestamp = WC_Subscriptions_Manager::get_next_payment_date($args->subscription_key, '', 'timestamp'); // Check if any payment gateway supports recurring payment method changes $one_gateway_supports_changes = false; foreach ($woocommerce->payment_gateways->get_available_payment_gateways() as $gateway) { if ($gateway->supports('subscription_payment_method_change')) { $one_gateway_supports_changes = true; break; } } if ($one_gateway_supports_changes && 0 !== $next_payment_timestamp && false === $args->order_uses_manual_payments && $args->payment_gateway->supports('subscription_cancellation') && 'active' == $args->subscription['status']) { $subscription_can_be_changed = true; } else { $subscription_can_be_changed = false; } } return $subscription_can_be_changed; }
/** * Hooked to the users table to display a check mark if a given user has an active subscription. * * @param string $value The string to output in the column specified with $column_name * @param string $column_name The string key for the current column in an admin table * @param int $user_id The ID of the user to which this row relates * @return string $value A check mark if the column is the active_subscriber column and the user has an active subscription. * @since 1.0 */ public static function user_column_values($value, $column_name, $user_id) { global $woocommerce; if ($column_name == 'woocommerce_active_subscriber') { $users_subscriptions = WC_Subscriptions_Manager::get_users_subscriptions($user_id); // Inactive until proven otherwise $value = '<img src="' . $woocommerce->plugin_url() . '/assets/images/success-off.png" alt="no" />'; if (!empty($users_subscriptions)) { foreach ($users_subscriptions as $subscription) { if ($subscription['status'] == 'active') { $value = '<img src="' . $woocommerce->plugin_url() . '/assets/images/success.png" alt="yes" />'; break; } } } } return $value; }
* @param string $subscription_key A subscription key of the form created by @see self::get_subscription_key() * @since 1.1.5 * @deprecated 2.0 */ public static function maybe_reschedule_subscription_payment($user_id, $subscription_key) { _deprecated_function(__METHOD__, '2.0'); $subscription = wcs_get_subscription_from_key($subscription_key); // Don't reschedule for cancelled, suspended or expired subscriptions if (!$subscription->has_status('expired', 'cancelled', 'on-hold')) { // Reschedule the 'scheduled_subscription_payment' hook if ($subscription->can_date_be_updated('next_payment')) { $subscription->update_dates(array('next_payment' => $subscription->calculate_date('next_payment'))); do_action('rescheduled_subscription_payment', $user_id, $subscription_key); } } } /** * Fires when the trial period for a subscription has completed. * * @param int $subscription_id The ID of a 'shop_subscription' post * @since 1.0 * @deprecated 2.0 */ public static function subscription_trial_end($subscription_id, $deprecated = null) { _deprecated_function(__METHOD__, '2.0'); } } WC_Subscriptions_Manager::init();
/** * Checks if the store manager has requested the current product be limited to one purchase * per customer, and if so, checks whether the customer already has an active subscription to * the product. * * @access public * @return bool */ function is_purchasable() { $purchasable = parent::is_purchasable(); if (true === $purchasable && 'yes' == $this->limit_subscriptions) { if (WC_Subscriptions_Manager::user_has_subscription(0, $this->id, 'active')) { $purchasable = false; } } return apply_filters('woocommerce_subscription_is_purchasable', $purchasable, $this); }
/** * 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) { $subscription_details = wp_parse_args($subscription_details, array('initial_amount' => '', 'initial_description' => __('up front', WC_Subscriptions::$text_domain), 'recurring_amount' => '', 'subscription_interval' => 1, 'subscription_period' => '', 'subscription_length' => 0, 'trial_length' => 0, 'trial_period' => '')); $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']) : $subscription_details['initial_amount']; $recurring_amount_string = is_numeric($subscription_details['recurring_amount']) ? woocommerce_price($subscription_details['recurring_amount']) : $subscription_details['recurring_amount']; $subscription_period_string = WC_Subscriptions_Manager::get_subscription_period_strings($subscription_details['subscription_interval'], $subscription_details['subscription_period']); $subscription_ranges = WC_Subscriptions_Manager::get_subscription_ranges(); if ($subscription_details['subscription_length'] > 0 && $subscription_details['subscription_length'] == $subscription_details['subscription_interval']) { if (!empty($subscription_details['initial_amount'])) { $subscription_string = sprintf(__('%s %s then %s', WC_Subscriptions::$text_domain), $initial_amount_string, $subscription_details['initial_description'], $recurring_amount_string); } else { $subscription_string = $recurring_amount_string; } } 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'], WC_Subscriptions::$text_domain), $initial_amount_string, $subscription_details['initial_description'], $recurring_amount_string, $subscription_period_string); } elseif (!empty($subscription_details['recurring_amount'])) { $subscription_string = sprintf(_n('%s / %s', ' %s every %s', $subscription_details['subscription_interval'], WC_Subscriptions::$text_domain), $recurring_amount_string, $subscription_period_string); } else { $subscription_string = ''; } if ($subscription_details['subscription_length'] > 0) { $subscription_string = sprintf(__('%s for %s', WC_Subscriptions::$text_domain), $subscription_string, $subscription_ranges[$subscription_details['subscription_period']][$subscription_details['subscription_length']]); } if ($subscription_details['trial_length'] > 1 || empty($subscription_details['initial_amount']) && $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 with %s free trial', WC_Subscriptions::$text_domain), $subscription_string, $trial_length); } else { $subscription_string = sprintf(__('%s free trial then %s', WC_Subscriptions::$text_domain), ucfirst($trial_length), $subscription_string); } } return apply_filters('woocommerce_subscription_price_string', $subscription_string, $subscription_details); }
/** * A general purpose function for grabbing an array of subscriptions in form of 'subscription_key' => 'subscription_details'. * * The $args param is based on the parameter of the same name used by the core WordPress @see get_posts() function. * It can be used to choose which subscriptions should be returned by the function, how many subscriptions shoudl be returned * and in what order those subscriptions should be returned. * * @param array $args A set of name value pairs to determine the return value. * 'subscriptions_per_page' The number of subscriptions to return. Set to -1 for unlimited. Default 10. * 'offset' An optional number of subscription to displace or pass over. Default 0. * 'orderby' The field which the subscriptions should be orderd by. Can be 'start_date', 'expiry_date', 'end_date', 'status', 'name' or 'order_id'. Defaults to 'start_date'. * 'order' The order of the values returned. Can be 'ASC' or 'DESC'. Defaults to 'DESC' * 'customer_id' The user ID of a customer on the site. * 'product_id' The post ID of a WC_Product_Subscription, WC_Product_Variable_Subscription or WC_Product_Subscription_Variation object * 'subscription_status' Any valid subscription status. Can be 'any', 'active', 'cancelled', 'suspended', 'expired', 'pending' or 'trash'. Defaults to 'any'. * @return array Subscription details in 'subscription_key' => 'subscription_details' form. * @since 1.4 */ public static function get_subscriptions($args = array()) { global $wpdb; $args = wp_parse_args($args, array('subscriptions_per_page' => 10, 'paged' => 1, 'offset' => 0, 'orderby' => '_subscription_start_date', 'order' => 'DESC', 'customer_id' => '', 'product_id' => '', 'variation_id' => '', 'order_id' => array(), 'subscription_status' => 'any')); // Map human friendly order_by values to internal keys switch ($args['orderby']) { case 'status': $args['orderby'] = '_subscription_status'; break; case 'start_date': $args['orderby'] = '_subscription_start_date'; break; case 'expiry_date': $args['orderby'] = '_subscription_expiry_date'; break; case 'trial_expiry_date': $args['orderby'] = '_subscription_trial_expiry_date'; break; case 'end_date': $args['orderby'] = '_subscription_end_date'; break; } $subscriptions = array(); // First see if we're paging, so the limit can be applied to subqueries if (-1 !== $args['subscriptions_per_page']) { $per_page = absint($args['subscriptions_per_page']); $page_start = ''; if (0 == $args['paged']) { $args['paged'] = 1; } if ($args['paged']) { $page_start = absint($args['paged'] - 1) * $per_page . ', '; } elseif ($args['offset']) { $page_start = absint($args['offset']) . ', '; } $limit_query = ' LIMIT ' . $page_start . $per_page; } else { $limit_query = ''; } if ('DESC' === $args['order']) { $order_query = ' DESC'; } else { $order_query = ' ASC'; } // Now start building the actual query $query = "\n\t\t\tSELECT meta.*, items.*, r.renewal_order_count, (CASE WHEN (r.renewal_order_count > 0) THEN l.last_payment_date ELSE o.order_date END) AS last_payment_date FROM `{$wpdb->prefix}woocommerce_order_itemmeta` AS meta\n\t\t\tLEFT JOIN `{$wpdb->prefix}woocommerce_order_items` AS items USING (order_item_id)"; $query .= "\n\t\t\tLEFT JOIN (\n\t\t\t\tSELECT a.order_item_id FROM `{$wpdb->prefix}woocommerce_order_itemmeta` AS a"; // To filter order items by a specific product ID, we need to do another join if (!empty($args['product_id']) || !empty($args['variation_id'])) { // Can only specify a product ID or a variation ID, no need to specify a product ID if you want a variation of that product $meta_key = !empty($args['variation_id']) ? '_variation_id' : '_product_id'; $query .= sprintf("\n\t\t\t\tLEFT JOIN (\n\t\t\t\t\tSELECT `{$wpdb->prefix}woocommerce_order_itemmeta`.order_item_id FROM `{$wpdb->prefix}woocommerce_order_itemmeta`\n\t\t\t\t\tWHERE `{$wpdb->prefix}woocommerce_order_itemmeta`.meta_key = '%s'\n\t\t\t\t\tAND `{$wpdb->prefix}woocommerce_order_itemmeta`.meta_value = %s\n\t\t\t\t) AS p\n\t\t\t\tUSING (order_item_id)", $meta_key, $args['product_id']); } // To filter order items by a specific subscription status, we need to do another join (unless we're also ordering by subscription status) if (!empty($args['subscription_status']) && 'any' !== $args['subscription_status'] && '_subscription_status' !== $args['orderby']) { if ('all' == $args['subscription_status']) { // get all but trashed subscriptions $query .= "\n\t\t\t\tLEFT JOIN (\n\t\t\t\t\tSELECT `{$wpdb->prefix}woocommerce_order_itemmeta`.order_item_id FROM `{$wpdb->prefix}woocommerce_order_itemmeta`\n\t\t\t\t\tWHERE `{$wpdb->prefix}woocommerce_order_itemmeta`.meta_key = '_subscription_status'\n\t\t\t\t\tAND `{$wpdb->prefix}woocommerce_order_itemmeta`.meta_value != 'trash'\n\t\t\t\t) AS s\n\t\t\t\tUSING (order_item_id)"; } else { $query .= sprintf("\n\t\t\t\tLEFT JOIN (\n\t\t\t\t\tSELECT `{$wpdb->prefix}woocommerce_order_itemmeta`.order_item_id FROM `{$wpdb->prefix}woocommerce_order_itemmeta`\n\t\t\t\t\tWHERE `{$wpdb->prefix}woocommerce_order_itemmeta`.meta_key = '_subscription_status'\n\t\t\t\t\tAND `{$wpdb->prefix}woocommerce_order_itemmeta`.meta_value = '%s'\n\t\t\t\t) AS s\n\t\t\t\tUSING (order_item_id)", $args['subscription_status']); } } // We need an additional join when ordering by certain attributes switch ($args['orderby']) { case '_product_id': // Because all products have a product ID, but not all products are subscriptions if (empty($args['product_id'])) { $query .= "\n\t\t\t\tLEFT JOIN (\n\t\t\t\t\tSELECT `{$wpdb->prefix}woocommerce_order_itemmeta`.order_item_id FROM `{$wpdb->prefix}woocommerce_order_itemmeta`\n\t\t\t\t\tWHERE `{$wpdb->prefix}woocommerce_order_itemmeta`.meta_key LIKE '_subscription_%s'\n\t\t\t\t\tGROUP BY `{$wpdb->prefix}woocommerce_order_itemmeta`.order_item_id\n\t\t\t\t) AS a2 USING (order_item_id)"; } break; case '_order_item_name': // Because the order item name is found in the order_items tables // Because the order item name is found in the order_items tables case 'name': if (empty($args['product_id'])) { $query .= "\n\t\t\t\tLEFT JOIN (\n\t\t\t\t\tSELECT `{$wpdb->prefix}woocommerce_order_items`.order_item_id, `{$wpdb->prefix}woocommerce_order_items`.order_item_name FROM `{$wpdb->prefix}woocommerce_order_items`\n\t\t\t\t\tWHERE `{$wpdb->prefix}woocommerce_order_items`.order_item_type = 'line_item'\n\t\t\t\t) AS names USING (order_item_id)"; } break; case 'order_id': // Because the order ID is found in the order_items tables $query .= "\n\t\t\t\tLEFT JOIN (\n\t\t\t\t\tSELECT `{$wpdb->prefix}woocommerce_order_items`.order_item_id, `{$wpdb->prefix}woocommerce_order_items`.order_id FROM `{$wpdb->prefix}woocommerce_order_items`\n\t\t\t\t\tWHERE `{$wpdb->prefix}woocommerce_order_items`.order_item_type = 'line_item'\n\t\t\t\t) AS order_ids USING (order_item_id)"; break; case 'renewal_order_count': $query .= "\n\t\t\t\tLEFT JOIN (\n\t\t\t\t\tSELECT items2.order_item_id, items2.order_id, r2.renewal_order_count FROM `{$wpdb->prefix}woocommerce_order_items` AS items2\n\t\t\t\t\tLEFT JOIN (\n\t\t\t\t\t\tSELECT posts.post_parent, COUNT(posts.ID) as renewal_order_count FROM `{$wpdb->prefix}posts` AS posts\n\t\t\t\t\t\tWHERE posts.post_parent != 0\n\t\t\t\t\t\tAND posts.post_type = 'shop_order'\n\t\t\t\t\t\tGROUP BY posts.post_parent\n\t\t\t\t\t) AS r2 ON r2.post_parent = items2.order_id\n\t\t\t\t\tWHERE items2.order_item_type = 'line_item'\n\t\t\t\t) AS renewals USING (order_item_id)"; break; case 'user_display_name': case 'user': if (empty($args['customer_id'])) { $query .= "\n\t\t\t\tLEFT JOIN (\n\t\t\t\t\tSELECT items2.order_item_id, items2.order_id, users.display_name FROM `{$wpdb->prefix}woocommerce_order_items` AS items2\n\t\t\t\t\tLEFT JOIN (\n\t\t\t\t\t\tSELECT postmeta.post_id, postmeta.meta_value, u.display_name FROM `{$wpdb->prefix}postmeta` AS postmeta\n\t\t\t\t\t\tLEFT JOIN (\n\t\t\t\t\t\t\tSELECT `{$wpdb->prefix}users`.ID, `{$wpdb->prefix}users`.display_name FROM `{$wpdb->prefix}users`\n\t\t\t\t\t\t) AS u ON u.ID = postmeta.meta_value\n\t\t\t\t\t\tWHERE postmeta.meta_key = '_customer_user'\n\t\t\t\t\t) AS users ON users.post_id = items2.order_id\n\t\t\t\t\tWHERE items2.order_item_type = 'line_item'\n\t\t\t\t) AS users_items USING (order_item_id)"; } case 'last_payment_date': // Because we need the date of the last renewal order (or maybe the original order if there are no renewal orders) $query .= "\n\t\t\t\tLEFT JOIN (\n\t\t\t\t\tSELECT items2.order_item_id, (CASE WHEN (r2.renewal_order_count > 0) THEN l.last_payment_date ELSE o.order_date END) AS last_payment_date FROM `{$wpdb->prefix}woocommerce_order_items` AS items2\n\t\t\t\t\tLEFT JOIN (\n\t\t\t\t\t\tSELECT posts.post_parent, COUNT(posts.ID) as renewal_order_count FROM `{$wpdb->prefix}posts` AS posts\n\t\t\t\t\t\tWHERE posts.post_parent != 0\n\t\t\t\t\t\tAND posts.post_type = 'shop_order'\n\t\t\t\t\t\tGROUP BY posts.post_parent\n\t\t\t\t\t) AS r2 ON r2.post_parent = items2.order_id\n\t\t\t\t\tLEFT JOIN (\n\t\t\t\t\t\tSELECT o.ID, o.post_date_gmt AS order_date FROM `{$wpdb->prefix}posts` AS o\n\t\t\t\t\t\tWHERE o.post_type = 'shop_order'\n\t\t\t\t\t\tAND o.post_parent = 0\n\t\t\t\t\t) AS o ON o.ID = items2.order_id\n\t\t\t\t\tLEFT JOIN (\n\t\t\t\t\t\tSELECT p.ID, p.post_parent, MAX(p.post_date_gmt) AS last_payment_date FROM `{$wpdb->prefix}posts` AS p\n\t\t\t\t\t\tWHERE p.post_type = 'shop_order'\n\t\t\t\t\t\tAND p.post_parent != 0\n\t\t\t\t\t\tGROUP BY p.post_parent\n\t\t\t\t\t) AS l ON l.post_parent = items2.order_id\n\t\t\t\t\tWHERE items2.order_item_type = 'line_item'\n\t\t\t\t) AS payment_dates USING (order_item_id)"; break; } // Start where query $query .= "\n\t\t\t\tWHERE 1=1"; // We only want subscriptions from within the product filter subclause if (!empty($args['product_id']) || !empty($args['variation_id'])) { $query .= "\n\t\t\t\tAND a.order_item_id = p.order_item_id"; } // We only want subscriptions from within the status filter subclause if (!empty($args['subscription_status']) && 'any' !== $args['subscription_status'] && '_subscription_status' !== $args['orderby']) { $query .= "\n\t\t\t\tAND a.order_item_id = s.order_item_id"; } // We only want items from a certain order if (!empty($args['order_id'])) { $order_ids = is_array($args['order_id']) ? implode(',', $args['order_id']) : $args['order_id']; $query .= sprintf("\n\t\t\t\tAND a.order_item_id IN (\n\t\t\t\t\tSELECT o.order_item_id FROM `{$wpdb->prefix}woocommerce_order_items` AS o\n\t\t\t\t\tWHERE o.order_id IN (%s)\n\t\t\t\t)", $order_ids); } // If we only want subscriptions for a certain customer ID, we need to make sure items are from the customer's orders if (!empty($args['customer_id'])) { $query .= sprintf("\n\t\t\t\tAND a.order_item_id IN (\n\t\t\t\t\tSELECT `{$wpdb->prefix}woocommerce_order_items`.order_item_id FROM `{$wpdb->prefix}woocommerce_order_items`\n\t\t\t\t\tWHERE `{$wpdb->prefix}woocommerce_order_items`.order_id IN (\n\t\t\t\t\t\tSELECT `{$wpdb->prefix}postmeta`.post_id FROM `{$wpdb->prefix}postmeta`\n\t\t\t\t\t\tWHERE `{$wpdb->prefix}postmeta`.meta_key = '_customer_user'\n\t\t\t\t\t\tAND `{$wpdb->prefix}postmeta`.meta_value = %s\n\t\t\t\t\t)\n\t\t\t\t)", $args['customer_id']); } // Now we need to sort the subscriptions, which may mean selecting a specific bit of meta data switch ($args['orderby']) { case '_subscription_start_date': case '_subscription_expiry_date': case '_subscription_trial_expiry_date': case '_subscription_end_date': $query .= sprintf("\n\t\t\t\tAND a.meta_key = '%s'\n\t\t\t\tORDER BY CASE WHEN CAST(a.meta_value AS DATETIME) IS NULL THEN 1 ELSE 0 END, CAST(a.meta_value AS DATETIME) %s", $args['orderby'], $order_query); break; case '_subscription_status': $query .= "\n\t\t\t\tAND a.meta_key = '_subscription_status'\n\t\t\t\tORDER BY a.meta_value" . $order_query; break; case '_product_id': if (empty($args['product_id'])) { $query .= "\n\t\t\t\tAND a2.order_item_id = a.order_item_id\n\t\t\t\tAND a.meta_key = '_product_id'\n\t\t\t\tORDER BY a.meta_value" . $order_query; } break; case '_order_item_name': case 'name': if (empty($args['product_id'])) { $query .= "\n\t\t\t\tAND a.meta_key = '_subscription_start_date'\n\t\t\t\tAND names.order_item_id = a.order_item_id\n\t\t\t\tORDER BY names.order_item_name" . $order_query . ", CASE WHEN CAST(a.meta_value AS DATETIME) IS NULL THEN 1 ELSE 0 END, CAST(a.meta_value AS DATETIME) DESC"; } break; case 'order_id': $query .= "\n\t\t\t\tAND a.meta_key = '_subscription_start_date'\n\t\t\t\tAND order_ids.order_item_id = a.order_item_id\n\t\t\t\tORDER BY order_ids.order_id" . $order_query; break; case 'renewal_order_count': $query .= "\n\t\t\t\tAND a.meta_key = '_subscription_start_date'\n\t\t\t\tAND renewals.order_item_id = a.order_item_id\n\t\t\t\tORDER BY renewals.renewal_order_count" . $order_query; break; case 'user_display_name': case 'user': if (empty($args['customer_id'])) { $query .= "\n\t\t\t\tAND a.meta_key = '_subscription_start_date'\n\t\t\t\tAND users_items.order_item_id = a.order_item_id\n\t\t\t\tORDER BY users_items.display_name" . $order_query . ", CASE WHEN CAST(a.meta_value AS DATETIME) IS NULL THEN 1 ELSE 0 END, CAST(a.meta_value AS DATETIME) DESC"; } break; case 'last_payment_date': $query .= "\n\t\t\t\tAND a.meta_key = '_subscription_start_date'\n\t\t\t\tAND payment_dates.order_item_id = a.order_item_id\n\t\t\t\tORDER BY payment_dates.last_payment_date" . $order_query; break; } // Paging if (-1 !== $args['subscriptions_per_page']) { $query .= $limit_query; } $query .= "\n\t\t\t) AS a3 USING (order_item_id)"; // Add renewal order count & last payment date (there is duplication here when ordering by renewal order count or last payment date, but it's an arbitrary performance hit) $query .= "\n\t\t\tLEFT JOIN (\n\t\t\t\tSELECT `{$wpdb->prefix}posts`.post_parent, COUNT(`{$wpdb->prefix}posts`.ID) as renewal_order_count FROM `{$wpdb->prefix}posts`\n\t\t\t\tWHERE `{$wpdb->prefix}posts`.post_parent != 0\n\t\t\t\tAND `{$wpdb->prefix}posts`.post_type = 'shop_order'\n\t\t\t\tGROUP BY `{$wpdb->prefix}posts`.post_parent\n\t\t\t) AS r ON r.post_parent = items.order_id\n\t\t\tLEFT JOIN (\n\t\t\t\tSELECT o.ID, o.post_date_gmt AS order_date FROM `{$wpdb->prefix}posts` AS o\n\t\t\t\tWHERE o.post_type = 'shop_order'\n\t\t\t\tAND o.post_parent = 0\n\t\t\t) AS o ON o.ID = items.order_id\n\t\t\tLEFT JOIN (\n\t\t\t\tSELECT p.ID, p.post_parent, MAX(p.post_date_gmt) AS last_payment_date FROM `{$wpdb->prefix}posts` AS p\n\t\t\t\tWHERE p.post_type = 'shop_order'\n\t\t\t\tAND p.post_parent != 0\n\t\t\t\tGROUP BY p.post_parent\n\t\t\t) AS l ON l.post_parent = items.order_id"; $query .= "\n\t\t\tWHERE meta.meta_key REGEXP '_subscription_(.*)|_product_id|_variation_id'\n\t\t\tAND meta.order_item_id = a3.order_item_id"; $query = apply_filters('woocommerce_get_subscriptions_query', $query, $args); $raw_subscriptions = $wpdb->get_results($query); // Create a backward compatible structure foreach ($raw_subscriptions as $raw_subscription) { if (!isset($raw_subscription->order_item_id)) { continue; } if (!array_key_exists($raw_subscription->order_item_id, $subscriptions)) { $subscriptions[$raw_subscription->order_item_id] = array('order_id' => $raw_subscription->order_id, 'name' => $raw_subscription->order_item_name, 'renewal_order_count' => empty($raw_subscription->renewal_order_count) ? 0 : $raw_subscription->renewal_order_count, 'last_payment_date' => $raw_subscription->last_payment_date); $subscriptions[$raw_subscription->order_item_id]['user_id'] = get_post_meta($raw_subscription->order_id, '_customer_user', true); } $meta_key = str_replace('_subscription', '', $raw_subscription->meta_key); $meta_key = substr($meta_key, 0, 1) == '_' ? substr($meta_key, 1) : $meta_key; if ('product_id' === $meta_key) { $subscriptions[$raw_subscription->order_item_id]['subscription_key'] = WC_Subscriptions_Manager::get_subscription_key($subscriptions[$raw_subscription->order_item_id]['order_id'], $raw_subscription->meta_value); } $subscriptions[$raw_subscription->order_item_id][$meta_key] = maybe_unserialize($raw_subscription->meta_value); } return apply_filters('woocommerce_get_subscriptions', $subscriptions, $args); }
function wc_subs_exporter_get_filtered_subscriptions($export) { global $wpdb; $subscriptions = $filtered_subscriptions = array(); $sql = "SELECT DISTINCT i.order_id, m.product_id, p.meta_value\n\t\t\t\tFROM\n\t\t\t\t(\n\t\t\t\tSELECT order_item_id,\n\t\t\t\tMAX(CASE WHEN meta_key = '_product_id' THEN meta_value END) product_id\n\t\t\t\tFROM {$wpdb->prefix}woocommerce_order_itemmeta\n\t\t\t\tWHERE meta_key LIKE '_subscription%' \n\t\t\t\t\tOR meta_key LIKE '_recurring%'\n\t\t\t\t\tOR meta_key = '_product_id'\n\t\t\t\tGROUP BY order_item_id\n\t\t\t\tHAVING MAX(meta_key LIKE '_subscription%')\n\t\t\t\t\t+ MAX(meta_key LIKE '_recurring%') > 0\n\t\t\t\t) m JOIN {$wpdb->prefix}woocommerce_order_items i \n\t\t\t\tON m.order_item_id = i.order_item_id \n\t\t\t\tLEFT JOIN {$wpdb->prefix}postmeta p \n\t\t\t\tON i.order_id = p.post_id \n\t\t\t\tAND p.meta_key = '_customer_user'\n\t\t\t\tLEFT JOIN {$wpdb->prefix}posts po \n\t\t\t\tON p.post_id = po.ID\n\t\t\t\tWHERE po.post_type = 'shop_order' AND po.post_parent = 0"; $order_ids_and_product_ids = $wpdb->get_results($sql); foreach ($order_ids_and_product_ids as $order_id_and_product_id) { if (empty($order_id_and_product_id->product_id)) { continue; } $subscription_key = $order_id_and_product_id->order_id . '_' . $order_id_and_product_id->product_id; $subscription = WC_Subscriptions_Manager::get_subscription($subscription_key); if (empty($subscription)) { continue; } // filter status if (!array_key_exists($subscription['status'], $export->status)) { continue; } // filter dates if ($export->dates_from && strtotime($subscription['start_date']) < strtotime($export->dates_from)) { continue; } elseif ($export->dates_to && strtotime($subscription['start_date']) > strtotime($export->dates_to)) { continue; } $subscriptions[$order_id_and_product_id->meta_value][$subscription_key] = $subscription; } $processed_rows = 0; foreach ($subscriptions as $user => $user_subscriptions) { if (++$processed_rows <= $export->offset) { continue; } foreach ($user_subscriptions as $key => $subscription) { $filtered_subscriptions[$user][$key] = $subscription; } if ($processed_rows == $export->limit_volume) { break; } } return $filtered_subscriptions; }
/** * Callback for the [subscriptions] shortcode that displays subscription names for a particular user. * * @param array $attributes Shortcode attributes. * @return string */ public static function do_subscriptions_shortcode($attributes) { $attributes = wp_parse_args($attributes, array('user_id' => 0, 'status' => 'active')); $status = $attributes['status']; $subscriptions = WC_Subscriptions_Manager::get_users_subscriptions($attributes['user_id']); if (empty($subscriptions)) { return '<ul class="user-subscriptions no-user-subscriptions"> <li>No subscriptions found.</li> </ul>'; } $list = '<ul class="user-subscriptions">'; foreach ($subscriptions as $subscription) { if ($subscription['status'] == $status || $status == 'all') { $list .= sprintf('<li>%s</li>', WC_Subscriptions_Order::get_item_name($subscription['order_id'], $subscription['product_id'])); } } $list .= '</ul>'; return $list; }
/** * If a product is being marked as not purchasable because it is limited and the customer has a subscription, * but the current request is to switch the subscription, then mark it as purchasable. * * @since 1.4.4 * @return bool */ public static function is_purchasable($is_purchasable, $product) { global $woocommerce; if (false === $is_purchasable && WC_Subscriptions_Product::is_subscription($product->id) && 'yes' === $product->limit_subscriptions && WC_Subscriptions_Manager::user_has_subscription(0, $product->id, 'active')) { // Adding to cart from the product page if (isset($_GET['switch-subscription'])) { $is_purchasable = true; // Validating when restring cart from session } elseif (self::cart_contains_subscription_switch()) { $is_purchasable = true; // Restoring cart from session, so need to check the cart in the session (self::cart_contains_subscription_switch() only checks the cart) } elseif (isset($woocommerce->session->cart)) { foreach ($woocommerce->session->cart as $cart_item_key => $cart_item) { if (isset($cart_item['subscription_switch'])) { $is_purchasable = true; break; } } } } return $is_purchasable; }
/** * Process the subscription payment (manually... well via wp_cron) * * @param $amount the amount for this payment * @param $order the order ID * @param $product_id the product ID */ function scheduled_subscription_payment($amount_to_charge, $order, $product_id) { $this->params = array(); $this->params["amount"] = (int) ($amount_to_charge * 100); $this->params["test"] = $test_mode; $this->params["reference"] = $order->id . "-" . date("dmY"); // Reference for order ID 123 will become 123-01022012 $token = get_post_meta($order->id, "fatzebra_card_token", true); $this->params["card_token"] = $token; $ip = get_post_meta($post_id, "Customer IP Address", true); if (empty($ip)) { $ip = "127.0.0.1"; } $this->params["customer_ip"] = $ip; $this->params["deferred"] = false; $result = $this->do_payment($this->params); if (is_wp_error($result)) { $error = ""; $txn_id = "None"; switch ($result->get_error_code()) { case 1: // Non-200 response, so failed... (e.g. 401, 403, 500 etc). $error = $result->get_error_message(); break; case 2: // Gateway error (data etc) $errors = $result->get_error_data(); $error = implode(", ", $errors); error_log("WooCommerce Fat Zebra - Gateway Error: " . print_r($errors, true)); break; case 3: // Declined - error data is array with keys: message, id $error = $this->response_data->response->message; $txn_id = $this->response_data->response->transaction_id; break; case 4: // Exception caught, something bad happened. Data is exception // Exception caught, something bad happened. Data is exception default: $error = "Unknown - Error - See error log"; error_log("WC Fat Zebra (Subscriptions) - Unknown Error (exception): " . print_r($result->get_error_data(), true)); break; } // Add the error details and return $order->add_order_note(__("Subscription Payment Failed: " . $error . ". Transaction ID: " . $txn_id)); WC_Subscriptions_Manager::process_subscription_payment_failure_on_order($order, $product_id); } else { // Success! Returned is an array with the transaction ID etc // Update the subscription and return // Add a note to the order $order->add_order_note(__("Subscription Payment Successful. Transaction ID: " . $result["transaction_id"])); WC_Subscriptions_Manager::process_subscription_payments_on_order($order); } }
function pmprowoo_cancelled_subscription($user_id, $subscription_key) { global $pmprowoo_product_levels; //don't bother if array is empty if (empty($pmprowoo_product_levels)) { return; } /* does this order contain a membership product? */ $subscription = WC_Subscriptions_Manager::get_users_subscription($user_id, $subscription_key); if (isset($subscription['product_id']) && isset($subscription['order_id'])) { $product_id = $subscription['product_id']; $order_id = $subscription['order_id']; //membership product ids $product_ids = array_keys($pmprowoo_product_levels); //get order $order = new WC_Order($order_id); //does the order have a user id and some products? if (!empty($order->customer_user) && !empty($product_id)) { //is there a membership level for this product? if (in_array($product_id, $product_ids)) { //add the user to the level pmpro_changeMembershipLevel(0, $order->customer_user); } } } }
/** * Make sure anything requesting the first payment date for a synced subscription on the front-end receives * a date which takes into account the day on which payments should be processed. * * This is necessary as the self::calculate_first_payment_date() is not called when the subscription is active * (which it isn't until the first payment is completed and the subscription is activated). * * @since 1.5 */ public static function get_first_payment_date($first_payment_date, $order, $product_id, $type) { $subscription_key = WC_Subscriptions_Manager::get_subscription_key($order->id, $product_id); if (self::order_contains_synced_subscription($order->id) && 1 >= WC_Subscriptions_Manager::get_subscriptions_completed_payment_count($subscription_key)) { $subscription = WC_Subscriptions_Manager::get_subscription($subscription_key); // Don't prematurely set the first payment date when manually adding a subscription from the admin if (defined('WOOCOMMERCE_CHECKOUT') && true === WOOCOMMERCE_CHECKOUT || !is_admin() || 'active' == $subscription['status']) { $id_for_calculation = !empty($subscription['variation_id']) ? $subscription['variation_id'] : $subscription['product_id']; $first_payment_timestamp = self::calculate_first_payment_date($id_for_calculation, 'timestamp', $order->order_date); if (0 != $first_payment_timestamp) { $first_payment_date = 'mysql' == $type ? date('Y-m-d H:i:s', $first_payment_timestamp) : $first_payment_timestamp; } } } return $first_payment_date; }
/** * Checks if the store manager has requested the current product be limited to one purchase * per customer, and if so, checks whether the customer already has an active subscription to * the product. * * @access public * @return bool */ function is_purchasable() { $purchasable = parent::is_purchasable(); if (true === $purchasable && 'no' != $this->limit_subscriptions && is_user_logged_in() && ('active' == $this->limit_subscriptions && WC_Subscriptions_Manager::user_has_subscription(0, $this->id, 'on-hold') || WC_Subscriptions_Manager::user_has_subscription(0, $this->id, $this->limit_subscriptions)) && false === strpos($_SERVER['REQUEST_URI'], 'order-received')) { // we can't use is_order_received_page() becuase get_cart_from_session() is called before the query vars are setup $purchasable = false; } return apply_filters('woocommerce_subscription_is_purchasable', $purchasable, $this); }
/** * 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 */ public static function get_cart_subscription_string($initial_amount, $recurring_amount, $args = array()) { global $woocommerce; 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.', 'woocommerce-subscriptions')); $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()); if (true === $args['include_lengths']) { $subscription_details += array('subscription_length' => self::get_cart_subscription_length()); } if (false === $args['include_trial']) { $subscription_details['trial_length'] = 0; } // Override defaults when subscription is for one billing period if (self::get_cart_subscription_length() > 0 && self::get_cart_subscription_length() == self::get_cart_subscription_interval()) { $subscription_details += array('subscription_length' => self::get_cart_subscription_length()); } $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 (self::get_cart_subscription_trial_length() > 0 && self::get_cart_subscription_sign_up_fee() == 0) { /* The order total of a subscription with a free trial is equal to the recurring amount (instead of 0), because an order won't be paid for if it has a total of 0, a patch to allow payment on orders with 0 is coming in WC 1.7 */ $subscription_details['initial_amount'] = ''; } $subscription_details = apply_filters('woocommerce_cart_subscription_string_details', $subscription_details, $args); $subscription_string = WC_Subscriptions_Manager::get_subscription_price_string($subscription_details); return $subscription_string; }
/** * 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); }
/** * If no sort order set, default to title. If no sort order, default to descending. * * @since 1.0 */ function sort_subscriptions($a, $b) { $order_by = !empty($_REQUEST['orderby']) ? $_REQUEST['orderby'] : 'start_date'; $order = !empty($_REQUEST['order']) ? $_REQUEST['order'] : 'desc'; switch ($order_by) { case 'product_name': $product_name_a = get_the_title($a['product_id']); $product_name_b = get_the_title($b['product_id']); $result = strcasecmp($product_name_a, $product_name_b); break; case 'user': $user_a = get_user_by('id', $a['user_id']); $user_b = get_user_by('id', $b['user_id']); $result = strcasecmp($user_a->display_name, $user_b->display_name); break; case 'expiry_date': if ($order == 'asc') { $result = self::sort_with_zero_at_end($a[$order_by], $b[$order_by]); } else { $result = self::sort_with_zero_at_beginning($a[$order_by], $b[$order_by]); } break; case 'end_date': $result = self::sort_with_zero_at_end($a[$order_by], $b[$order_by]); // Display subscriptions that have not ended at the end of the list break; case 'next_payment_date': $next_payment_a = WC_Subscriptions_Manager::get_next_payment_date($a['subscription_key'], $a['user_id'], 'mysql'); $next_payment_b = WC_Subscriptions_Manager::get_next_payment_date($b['subscription_key'], $b['user_id'], 'mysql'); $result = self::sort_with_zero_at_end($next_payment_a, $next_payment_b); // Display subscriptions with no future payments at the end break; case 'last_payment_date': $last_payment_a = empty($a['completed_payments']) ? 0 : strtotime(array_pop($a['completed_payments'])); $last_payment_b = empty($b['completed_payments']) ? 0 : strtotime(array_pop($b['completed_payments'])); $result = self::sort_with_zero_at_end($last_payment_a, $last_payment_b); // Display subscriptions with no compelted payments at the end break; case 'trial_expiry_date': $trial_expiration_a = WC_Subscriptions_Manager::get_trial_expiration_date($a['subscription_key'], $a['user_id'], 'mysql'); $trial_expiration_b = WC_Subscriptions_Manager::get_trial_expiration_date($b['subscription_key'], $b['user_id'], 'mysql'); $result = self::sort_with_zero_at_end($trial_expiration_a, $trial_expiration_b); break; case 'renewal_order_count': $result = strcmp(WC_Subscriptions_Renewal_Order::get_renewal_order_count($a['order_id']), WC_Subscriptions_Renewal_Order::get_renewal_order_count($b['order_id'])); break; case 'order_id': $result = strnatcmp($a[$order_by], $b[$order_by]); break; default: $result = strcmp($a[$order_by], $b[$order_by]); break; } return $order == 'asc' ? $result : -$result; // Send final sort direction to usort }
/** * Once payment is completed on an order, record the payment against the subscription automatically so that * payment gateway extension developers don't have to do this. * * @param $order_id int The id of the order to record payment against * @since 1.1.2 */ public static function record_order_payment($order_id) { WC_Subscriptions_Manager::process_subscription_payments_on_order($order_id); }
/** * Process subscription renewal * * @since 1.4 * @param float $amount_to_charge subscription amount to charge, could include * multiple renewals if they've previously failed and the admin * has enabled it * @param WC_Order $order original order containing the subscription * @param int $product_id the ID of the subscription product */ public function process_renewal_payment($amount_to_charge, $order, $product_id = null) { require_once 'class-wc-realex-api.php'; $realex_subscription_count = 0; if (is_numeric($order->realex_subscription_count) && $order->realex_subscription_count) { $realex_subscription_count = $order->realex_subscription_count; } // increment the subscription count so we don't get order number clashes $realex_subscription_count++; update_post_meta($order->id, '_realex_subscription_count', $realex_subscription_count); // set custom class member used by the realex gateway $order->payment_total = SV_WC_Helper::number_format($amount_to_charge); // zero-dollar subscription renewal. weird, but apparently it happens -- only applicable to Subs 1.5.x if (!SV_WC_Plugin_Compatibility::is_wc_subscriptions_version_gte_2_0()) { if (0 == $order->payment_total) { // add order note $order->add_order_note(sprintf(__('%s0 Subscription Renewal Approved', 'woocommerce-gateway-realex'), get_woocommerce_currency_symbol())); // update subscription WC_Subscriptions_Manager::process_subscription_payments_on_order($order, $product_id); return; } } // This order is missing a tokenized card, lets see whether there's one available for the customer if (!get_post_meta($order->id, '_realex_cardref', true)) { $credit_cards = get_user_meta($order->get_user_id(), 'woocommerce_realex_cc', true); if (is_array($credit_cards)) { $card_ref = (object) current($credit_cards); $card_ref = $card_ref->ref; update_post_meta($order->id, '_realex_cardref', $card_ref); if (SV_WC_Plugin_Compatibility::is_wc_subscriptions_version_gte_2_0()) { foreach (wcs_get_subscriptions_for_renewal_order($order) as $subscription) { update_post_meta($subscription->id, '_realex_cardref', $card_ref); } } } } // create the realex api client $realex_client = new Realex_API($this->get_endpoint_url(), $this->get_realvault_endpoint_url(), $this->get_shared_secret()); // create the customer/cc tokens, and authorize the initial payment amount, if any $response = $this->authorize($realex_client, $order); if ($response && '00' == $response->result) { // add order note $order->add_order_note(sprintf(__('Credit Card Subscription Renewal Payment Approved (Payment Reference: %s) ', 'woocommerce-gateway-realex'), $response->pasref)); // update subscription if (SV_WC_Plugin_Compatibility::is_wc_subscriptions_version_gte_2_0()) { $order->payment_complete((string) $response->pasref); } else { WC_Subscriptions_Manager::process_subscription_payments_on_order($order, $product_id); } } else { // generate the result message $message = __('Credit Card Subscription Renewal Payment Failed', 'woocommerce-gateway-realex'); /* translators: Placeholders: %1$s - result, %2$s - result message */ if ($response) { $message .= sprintf(__(' (Result: %1$s - "%2$s").', 'woocommerce-gateway-realex'), $response->result, $response->message); } $order->add_order_note($message); // update subscription if (!SV_WC_Plugin_Compatibility::is_wc_subscriptions_version_gte_2_0()) { WC_Subscriptions_Manager::process_subscription_payment_failure_on_order($order, $product_id); } } }
?> </td> <td class="subscription-status" style="text-align:left; white-space:nowrap;" data-title="<?php _e('Status', 'woocommerce-subscriptions'); ?> "> <?php echo WC_Subscriptions_Manager::get_status_to_display($subscription_details['status'], $subscription_key, $user_id); ?> </td> <td class="subscription-next-payment" data-title="<?php _e('Next Payment', 'woocommerce-subscriptions'); ?> "> <?php $next_payment_timestamp = WC_Subscriptions_Manager::get_next_payment_date($subscription_key, $user_id, 'timestamp'); ?> <?php if ($next_payment_timestamp == 0) { ?> - <?php } else { ?> <?php $time_diff = $next_payment_timestamp - gmdate('U'); ?> <?php if ($time_diff > 0 && $time_diff < 7 * 24 * 60 * 60) { ?> <?php
function woo_ce_return_count( $export_type = '', $args = array() ) { global $wpdb; $count_sql = null; $woocommerce_version = woo_get_woo_version(); switch( $export_type ) { case 'product': $post_type = array( 'product', 'product_variation' ); $args = array( 'post_type' => $post_type, 'posts_per_page' => 1, 'fields' => 'ids', 'suppress_filters' => 1 ); $count_query = new WP_Query( $args ); $count = $count_query->found_posts; break; case 'category': $term_taxonomy = 'product_cat'; if( taxonomy_exists( $term_taxonomy ) ) $count = wp_count_terms( $term_taxonomy ); break; case 'tag': $term_taxonomy = 'product_tag'; if( taxonomy_exists( $term_taxonomy ) ) $count = wp_count_terms( $term_taxonomy ); break; case 'brand': $term_taxonomy = apply_filters( 'woo_ce_brand_term_taxonomy', 'product_brand' ); if( taxonomy_exists( $term_taxonomy ) ) $count = wp_count_terms( $term_taxonomy ); break; case 'order': $post_type = 'shop_order'; // Check if this is a WooCommerce 2.2+ instance (new Post Status) if( version_compare( $woocommerce_version, '2.2' ) >= 0 ) $post_status = ( function_exists( 'wc_get_order_statuses' ) ? apply_filters( 'woo_ce_order_post_status', array_keys( wc_get_order_statuses() ) ) : 'any' ); else $post_status = apply_filters( 'woo_ce_order_post_status', woo_ce_post_statuses() ); $args = array( 'post_type' => $post_type, 'posts_per_page' => 1, 'post_status' => $post_status, 'fields' => 'ids' ); $count_query = new WP_Query( $args ); $count = $count_query->found_posts; break; case 'customer': if( $users = woo_ce_return_count( 'user' ) > 1000 ) { $count = sprintf( '~%s+', 1000 ); } else { $post_type = 'shop_order'; $args = array( 'post_type' => $post_type, 'posts_per_page' => -1, 'fields' => 'ids' ); // Check if this is a WooCommerce 2.2+ instance (new Post Status) if( version_compare( $woocommerce_version, '2.2' ) >= 0 ) { $args['post_status'] = apply_filters( 'woo_ce_customer_post_status', array( 'wc-pending', 'wc-on-hold', 'wc-processing', 'wc-completed' ) ); } else { $args['post_status'] = apply_filters( 'woo_ce_customer_post_status', woo_ce_post_statuses() ); $args['tax_query'] = array( array( 'taxonomy' => 'shop_order_status', 'field' => 'slug', 'terms' => array( 'pending', 'on-hold', 'processing', 'completed' ) ), ); } $order_ids = new WP_Query( $args ); $count = $order_ids->found_posts; if( $count > 100 ) { $count = sprintf( '~%s', $count ); } else { $customers = array(); if( $order_ids->posts ) { foreach( $order_ids->posts as $order_id ) { $email = get_post_meta( $order_id, '_billing_email', true ); if( !in_array( $email, $customers ) ) $customers[$order_id] = $email; unset( $email ); } $count = count( $customers ); } } } /* if( false ) { $orders = get_posts( $args ); if( $orders ) { $customers = array(); foreach( $orders as $order ) { $order->email = get_post_meta( $order->ID, '_billing_email', true ); if( empty( $order->email ) ) { if( $order->user_id = get_post_meta( $order->ID, '_customer_user', true ) ) { $user = get_userdata( $order->user_id ); if( $user ) $order->email = $user->user_email; unset( $user ); } else { $order->email = '-'; } } if( !in_array( $order->email, $customers ) ) { $customers[$order->ID] = $order->email; $count++; } } unset( $orders, $order ); } } */ break; case 'user': if( $users = count_users() ) $count = $users['total_users']; break; case 'coupon': $post_type = 'shop_coupon'; if( post_type_exists( $post_type ) ) $count = wp_count_posts( $post_type ); break; case 'subscription': $count = 0; // Check that WooCommerce Subscriptions exists if( class_exists( 'WC_Subscriptions' ) ) { if( method_exists( 'WC_Subscriptions', 'is_large_site' ) ) { // Does this store have roughly more than 3000 Subscriptions if( false === WC_Subscriptions::is_large_site() ) { if( class_exists( 'WC_Subscriptions_Manager' ) ) { // Check that the get_all_users_subscriptions() function exists if( method_exists( 'WC_Subscriptions_Manager', 'get_all_users_subscriptions' ) ) { if( $subscriptions = WC_Subscriptions_Manager::get_all_users_subscriptions() ) { foreach( $subscriptions as $key => $user_subscription ) { if( !empty( $user_subscription ) ) { foreach( $user_subscription as $subscription ) $count++; } } unset( $subscriptions, $subscription, $user_subscription ); } } } } else { if( method_exists( 'WC_Subscriptions', 'get_total_subscription_count' ) ) $count = WC_Subscriptions::get_total_subscription_count(); else $count = "~2500"; } } } break; case 'product_vendor': $term_taxonomy = 'shop_vendor'; if( taxonomy_exists( $term_taxonomy ) ) $count = wp_count_terms( $term_taxonomy ); break; case 'commission': $post_type = 'shop_commission'; if( post_type_exists( $post_type ) ) $count = wp_count_posts( $post_type ); break; case 'shipping_class': $term_taxonomy = 'product_shipping_class'; if( taxonomy_exists( $term_taxonomy ) ) $count = wp_count_terms( $term_taxonomy ); break; case 'attribute': $attributes = ( function_exists( 'wc_get_attribute_taxonomies' ) ? wc_get_attribute_taxonomies() : array() ); $count = count( $attributes ); break; } if( isset( $count ) || $count_sql ) { if( isset( $count ) ) { if( is_object( $count ) ) { $count = (array)$count; $count = (int)array_sum( $count ); } return $count; } else { if( $count_sql ) $count = $wpdb->get_var( $count_sql ); else $count = 0; } return $count; } else { return 0; } }
/** * Checks if the current request is by a user to change the status of their subscription, and if it is * validate the subscription cancellation request and maybe processes the cancellation. * * @since 1.0 */ public static function maybe_change_users_subscription() { global $woocommerce; if (isset($_GET['change_subscription_to']) && isset($_GET['subscription_key']) && isset($_GET['_wpnonce'])) { $user_id = get_current_user_id(); $subscription = self::get_users_subscription($user_id, $_GET['subscription_key']); if (wp_verify_nonce($_GET['_wpnonce'], $_GET['subscription_key']) === false) { $woocommerce->add_error(sprintf(__('That subscription can not be changed to %s. Please contact us if you need assistance.', WC_Subscriptions::$text_domain), $_GET['change_subscription_to'])); } elseif (empty($subscription)) { $woocommerce->add_error(__('That doesn\'t appear to be one of your subscriptions.', WC_Subscriptions::$text_domain)); } elseif (!WC_Subscriptions_Manager::can_subscription_be_changed_to($_GET['change_subscription_to'], $_GET['subscription_key'], $user_id)) { $woocommerce->add_error(sprintf(__('That subscription can not be changed to %s. Please contact us if you need assistance.', WC_Subscriptions::$text_domain), $_GET['change_subscription_to'])); } elseif (!in_array($_GET['change_subscription_to'], array('active', 'on-hold', 'cancelled'))) { $woocommerce->add_error(sprintf(__('Unknown subscription status: "%s". Please contact us if you need assistance.', WC_Subscriptions::$text_domain), $_GET['change_subscription_to'])); } else { switch ($_GET['change_subscription_to']) { case 'active': if (WC_Subscriptions_Manager::subscription_requires_payment($_GET['subscription_key'], $user_id)) { $woocommerce->add_error(sprintf(__('You can not reactive that subscription until paying to renew it. Please contact us if you need assistance.', WC_Subscriptions::$text_domain), $_GET['change_subscription_to'])); } else { self::reactivate_subscription($user_id, $_GET['subscription_key']); $status_message = __('reactivated', WC_Subscriptions::$text_domain); } break; case 'on-hold': if (self::current_user_can_suspend_subscription($_GET['subscription_key'])) { self::put_subscription_on_hold($user_id, $_GET['subscription_key']); $status_message = __('suspended', WC_Subscriptions::$text_domain); } else { $woocommerce->add_error(sprintf(__('You can not suspend that subscription - the suspension limit has been reached. Please contact us if you need assistance.', WC_Subscriptions::$text_domain), $_GET['change_subscription_to'])); } break; case 'cancelled': self::cancel_subscription($user_id, $_GET['subscription_key']); $status_message = __('cancelled', WC_Subscriptions::$text_domain); break; } if (isset($status_message)) { $order = new WC_Order($subscription['order_id']); $order->add_order_note(sprintf(__('The status of subscription %s was changed to %s by the subscriber from their account page.', WC_Subscriptions::$text_domain), $_GET['subscription_key'], $_GET['change_subscription_to'])); $woocommerce->add_message(sprintf(__('Your subscription has been %s.', WC_Subscriptions::$text_domain), $status_message)); } } wp_safe_redirect(get_permalink(woocommerce_get_page_id('myaccount'))); exit; } }
/** * scheduled_subscription_payment function. * * @param $amount_to_charge float The amount to charge. * @param $order WC_Order The WC_Order object of the order which the subscription was purchased in. * @param $product_id int The ID of the subscription product for which this payment relates. * * @access public * @return void * * @since 0.6.0 */ public function scheduled_subscription_payment($amount_to_charge, $order, $product_id) { // Process the payment $result = $this->process_subscription_payment($order, $amount_to_charge); // If the process results in error, then marked order as failed. If not, continue subscription if (is_wp_error($result)) { WC_Subscriptions_Manager::process_subscription_payment_failure_on_order($order, $product_id); } else { WC_Subscriptions_Manager::process_subscription_payments_on_order($order); } }