/**
  * 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);
    }
Example #15
0
 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);
     }
 }