コード例 #1
0
?>
</th>
			<th scope="col" style="text-align:left; border: 1px solid #eee;"><?php 
_e('Start Date', 'woocommerce-subscriptions');
?>
</th>
			<th scope="col" style="text-align:left; border: 1px solid #eee;"><?php 
_e('End Date', 'woocommerce-subscriptions');
?>
</th>
		</tr>
	</thead>
	<tbody>
	<?php 
foreach ($order->get_items() as $item) {
    if (WC_Subscriptions_Order::is_item_subscription($order, $item)) {
        ?>
			<tr>
				<td scope="row" style="text-align:left; border: 1px solid #eee;"><?php 
        echo $item['name'];
        ?>
</td>
				<td scope="row" style="text-align:left; border: 1px solid #eee;"><?php 
        echo date_i18n(woocommerce_date_format(), strtotime($item['subscription_start_date']));
        ?>
</td>
				<td scope="row" style="text-align:left; border: 1px solid #eee;"><?php 
        echo !empty($item['subscription_expiry_date']) ? date_i18n(woocommerce_date_format(), strtotime($item['subscription_expiry_date'])) : __('When Cancelled', 'woocommerce-subscriptions');
        ?>
			</tr>
			<?php 
コード例 #2
0
 /**
  * Clear all subscriptions from a user's account for a given order.
  *
  * @param $order WC_Order The order for which subscriptions should be cleared.
  * @since 1.0
  */
 public static function maybe_trash_subscription($order)
 {
     if (!is_object($order)) {
         $order = new WC_Order($order);
     }
     if (WC_Subscriptions_Order::order_contains_subscription($order)) {
         foreach ($order->get_items() as $order_item) {
             if (WC_Subscriptions_Order::is_item_subscription($order, $order_item)) {
                 self::trash_subscription($order->customer_user, self::get_subscription_key($order->id, WC_Subscriptions_Order::get_items_product_id($order_item)));
             }
         }
     }
 }
コード例 #3
0
 /**
  * If the payment for a renewal order has previously failed and is then paid, we need to make sure the
  * subscription payment function is called.
  *
  * @param int $user_id The id of the user who purchased the subscription
  * @param string $subscription_key A subscription key of the form created by @see WC_Subscriptions_Manager::get_subscription_key()
  * @since 1.2
  */
 public static function process_subscription_payment_on_child_order($order_id, $payment_status = 'completed')
 {
     if (self::is_renewal($order_id, array('order_role' => 'child'))) {
         $child_order = new WC_Order($order_id);
         $parent_order = self::get_parent_order($child_order);
         $subscriptions_in_order = $child_order->get_items();
         // Should only be one subscription in the renewal order, but just in case
         foreach ($subscriptions_in_order as $item) {
             $item_id = WC_Subscriptions_Order::get_items_product_id($item);
             if (WC_Subscriptions_Order::is_item_subscription($parent_order, $item_id)) {
                 if ('failed' == $payment_status) {
                     // Don't duplicate renewal order
                     remove_action('processed_subscription_payment_failure', __CLASS__ . '::generate_failed_payment_renewal_order', 10, 2);
                     WC_Subscriptions_Manager::process_subscription_payment_failure_on_order($parent_order->id, $item_id);
                     // But make sure orders are still generated for other payments in the same request
                     add_action('processed_subscription_payment_failure', __CLASS__ . '::generate_failed_payment_renewal_order', 10, 2);
                 } else {
                     // Don't duplicate renewal order
                     remove_action('processed_subscription_payment', __CLASS__ . '::generate_paid_renewal_order', 10, 2);
                     WC_Subscriptions_Manager::process_subscription_payments_on_order($parent_order->id, $item_id);
                     // But make sure orders are still generated for other payments in the same request
                     add_action('processed_subscription_payment', __CLASS__ . '::generate_paid_renewal_order', 10, 2);
                     // Reactivate the subscription - activate_subscription doesn't operate on child orders
                     $subscription_key = WC_Subscriptions_Manager::get_subscription_key($parent_order->id, $item_id);
                     WC_Subscriptions_Manager::reactivate_subscription($parent_order->customer_user, $subscription_key);
                 }
             }
         }
     }
 }
コード例 #4
0
 /**
  * This function should be called whenever a subscription payment has failed.
  *
  * The function is a convenience wrapper for @see self::process_subscription_payment_failure(), so if calling that
  * function directly, do not call this function also.
  *
  * @param int|WC_Order $order The order or ID of the order for which subscription payments should be marked against.
  * @since 1.0
  */
 public static function process_subscription_payment_failure_on_order($order, $product_id = '')
 {
     if (!is_object($order)) {
         $order = new WC_Order($order);
     }
     if (empty($product_id)) {
         $order_items = WC_Subscriptions_Order::get_recurring_items($order);
         $first_order_item = reset($order_items);
         $product_id = WC_Subscriptions_Order::get_items_product_id($first_order_item);
     }
     if (WC_Subscriptions_Order::order_contains_subscription($order) && WC_Subscriptions_Order::is_item_subscription($order, $product_id)) {
         self::process_subscription_payment_failure($order->customer_user, self::get_subscription_key($order->id, $product_id));
         do_action('processed_subscription_payment_failure_for_order', $order);
     }
 }
コード例 #5
0
 /**
  * Tells if an order item is a subscription, provided that Subs is installed.
  *
  * @param  mixed      $order   order to check
  * @param  WC_Prder   $order   item to check
  * @return boolean             true if Subs exists and item is a Sub
  */
 function is_item_subscription($order, $item)
 {
     if (!class_exists('WC_Subscriptions_Order')) {
         return false;
     }
     return WC_Subscriptions_Order::is_item_subscription($order, $item);
 }
コード例 #6
0
 /**
  * When an order is added or updated from the admin interface, check if a new subscription product
  * has been manually added to the order, and if one has, create a new subscription. 
  * 
  * @param $post_id int The ID of the post which is the WC_Order object.
  * @param $post Object The post object of the order.
  * @since 1.1
  */
 public static function maybe_manually_change_subscriptions($post_id, $post)
 {
     $order = new WC_Order($post_id);
     // Check if all the subscription products on the order have associated subscriptions on the user's account, and if not, add a new one
     foreach ($_POST['item_id'] as $item_id) {
         if (!WC_Subscriptions_Order::is_item_subscription($order, $item_id)) {
             continue;
         }
         $subscription_key = WC_Subscriptions_Manager::get_subscription_key($post_id, $item_id);
         $subscription = array();
         // If order customer changed, move the subscription from the old customer's account to the new customer
         if (!empty($order->customer_user) && $order->customer_user != (int) $_POST['customer_user']) {
             $subscription = WC_Subscriptions_Manager::remove_users_subscription($order->customer_user, $subscription_key);
             $subscriptions = WC_Subscriptions_Manager::get_users_subscriptions((int) $_POST['customer_user']);
             if (!empty($subscription)) {
                 $subscriptions[$subscription_key] = $subscription;
                 WC_Subscriptions_Manager::update_users_subscriptions((int) $_POST['customer_user'], $subscriptions);
             }
         }
         // In case it's a new order or the customer has changed
         $order->customer_user = $order->user_id = (int) $_POST['customer_user'];
         $subscription = WC_Subscriptions_Manager::get_users_subscription($order->customer_user, $subscription_key);
         if (empty($subscription)) {
             // Add a new subscription
             // The order doesn't may not exist yet, so we need to set a few things ourselves
             $order->order_key = uniqid('order_');
             add_post_meta($post_id, '_order_key', $order->order_key, true);
             WC_Subscriptions_Manager::create_pending_subscription_for_order($order, $item_id);
             // Add the subscription meta for this item to the order
             $functions_and_meta = array('get_period' => '_order_subscription_periods', 'get_interval' => '_order_subscription_intervals', 'get_length' => '_order_subscription_lengths');
             foreach ($functions_and_meta as $function_name => $meta_key) {
                 $subscription_meta = self::get_meta($order, $meta_key, array());
                 $subscription_meta[$item_id] = WC_Subscriptions_Product::$function_name($item_id);
                 update_post_meta($order->id, $meta_key, $subscription_meta);
             }
             // Set the subscription's status if it should be something other than pending
             switch ($order->status) {
                 case 'completed':
                 case 'processing':
                     WC_Subscriptions_Manager::activate_subscription($order->customer_user, $subscription_key);
                     break;
                 case 'refunded':
                 case 'cancelled':
                     WC_Subscriptions_Manager::cancel_subscription($order->customer_user, $subscription_key);
                     break;
                 case 'failed':
                     WC_Subscriptions_Manager::failed_subscription_signup($order->customer_user, $subscription_key);
                     break;
             }
         }
     }
 }
コード例 #7
0
 /**
  * When an order is added or updated from the admin interface, check if a subscription product
  * has been manually added to the order or the details of the subscription have been modified, 
  * and create/update the subscription as required.
  *
  * Save subscription order meta items
  *
  * @param $post_id int The ID of the post which is the WC_Order object.
  * @param $post Object The post object of the order.
  * @since 1.1
  */
 public static function pre_process_shop_order_meta($post_id, $post)
 {
     global $woocommerce, $wpdb;
     $order_contains_subscription = false;
     $order = new WC_Order($post_id);
     $existing_product_ids = array();
     foreach ($order->get_items() as $existing_item) {
         $existing_product_ids[] = self::get_items_product_id($existing_item);
     }
     $product_ids = array();
     // WC <> 2.0 compatible posted product IDs
     if (isset($_POST['order_item_id'])) {
         foreach ($_POST['order_item_id'] as $order_item_id) {
             // WC 2.0+ has unique order item IDs and the product ID is a piece of meta
             $product_ids[$order_item_id] = woocommerce_get_order_item_meta($order_item_id, '_product_id');
         }
     } elseif (isset($_POST['item_id'])) {
         $product_ids = $_POST['item_id'];
     }
     // WC 1.x treated order item IDs as product IDs
     // Check if there are new subscription products to be added, or the order already has a subscription item
     foreach (array_merge($product_ids, $existing_product_ids) as $order_item_id => $product_id) {
         $is_existing_item = false;
         if (in_array($product_id, $existing_product_ids)) {
             $is_existing_item = true;
         }
         // If this is a new item and it's a subscription product, we have a subscription
         if (!$is_existing_item && WC_Subscriptions_Product::is_subscription($product_id)) {
             $order_contains_subscription = true;
         }
         // If this is an existing item and it's a subscription item, we have a subscription
         if ($is_existing_item && WC_Subscriptions_Order::is_item_subscription($order, $product_id)) {
             $order_contains_subscription = true;
         }
     }
     if (!$order_contains_subscription) {
         return $post_id;
     }
     // If the payment method is changing, make sure we have correct manual payment flag set
     $chosen_payment_method = stripslashes($_POST['_payment_method']);
     $existing_payment_method = get_post_meta($post_id, '_payment_method', true);
     if ($chosen_payment_method != $existing_payment_method || empty($chosen_payment_method)) {
         $payment_gateways = $woocommerce->payment_gateways->payment_gateways();
         if (isset($payment_gateways[$chosen_payment_method]) && $payment_gateways[$chosen_payment_method]->supports('subscriptions')) {
             $manual_renewal = 'false';
         } else {
             $manual_renewal = 'true';
         }
         update_post_meta($post_id, '_wcs_requires_manual_renewal', $manual_renewal);
     }
     // Make sure the recurring order totals are correct
     update_post_meta($post_id, '_order_recurring_discount_cart', stripslashes($_POST['_order_recurring_discount_cart']));
     update_post_meta($post_id, '_order_recurring_discount_total', stripslashes($_POST['_order_recurring_discount_total']));
     update_post_meta($post_id, '_order_recurring_tax_total', stripslashes($_POST['_order_recurring_tax_total']));
     update_post_meta($post_id, '_order_recurring_total', stripslashes($_POST['_order_recurring_total']));
     if (isset($_POST['recurring_order_taxes_id'])) {
         // WC 2.0+
         $tax_keys = array('recurring_order_taxes_id', 'recurring_order_taxes_rate_id', 'recurring_order_taxes_amount', 'recurring_order_taxes_shipping_amount');
         foreach ($tax_keys as $tax_key) {
             ${$tax_key} = isset($_POST[$tax_key]) ? $_POST[$tax_key] : array();
         }
         foreach ($recurring_order_taxes_id as $item_id) {
             $item_id = absint($item_id);
             $rate_id = absint($recurring_order_taxes_rate_id[$item_id]);
             if ($rate_id) {
                 $rate = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->prefix}woocommerce_tax_rates WHERE tax_rate_id = %s", $rate_id));
                 $label = $rate->tax_rate_name ? $rate->tax_rate_name : $woocommerce->countries->tax_or_vat();
                 $compound = $rate->tax_rate_compound ? 1 : 0;
                 $code = array();
                 $code[] = $rate->tax_rate_country;
                 $code[] = $rate->tax_rate_state;
                 $code[] = $rate->tax_rate_name ? $rate->tax_rate_name : 'TAX';
                 $code[] = absint($rate->tax_rate_priority);
                 $code = strtoupper(implode('-', array_filter($code)));
             } else {
                 $code = '';
                 $label = $woocommerce->countries->tax_or_vat();
             }
             $wpdb->update($wpdb->prefix . "woocommerce_order_items", array('order_item_name' => woocommerce_clean($code)), array('order_item_id' => $item_id), array('%s'), array('%d'));
             woocommerce_update_order_item_meta($item_id, 'rate_id', $rate_id);
             woocommerce_update_order_item_meta($item_id, 'label', $label);
             woocommerce_update_order_item_meta($item_id, 'compound', $compound);
             if (isset($recurring_order_taxes_amount[$item_id])) {
                 woocommerce_update_order_item_meta($item_id, 'tax_amount', woocommerce_clean($recurring_order_taxes_amount[$item_id]));
             }
             if (isset($recurring_order_taxes_shipping_amount[$item_id])) {
                 woocommerce_update_order_item_meta($item_id, 'shipping_tax_amount', woocommerce_clean($recurring_order_taxes_shipping_amount[$item_id]));
             }
         }
     } else {
         // WC 1.x
         if (!isset($_POST['_order_recurring_taxes'])) {
             $_POST['_order_recurring_taxes'] = array();
         }
         foreach ($_POST['_order_recurring_taxes'] as $index => $tax_details) {
             if (!isset($tax_details['compound'])) {
                 $_POST['_order_recurring_taxes'][$index]['compound'] = 0;
             }
         }
         update_post_meta($post_id, '_order_recurring_taxes', $_POST['_order_recurring_taxes']);
     }
     // Check if all the subscription products on the order have associated subscriptions on the user's account, and if not, add a new one
     foreach ($product_ids as $order_item_id => $product_id) {
         $is_existing_item = false;
         if (in_array($product_id, $existing_product_ids)) {
             $is_existing_item = true;
         }
         // If this is a new item and it's not a subscription product, ignore it
         if (!$is_existing_item && !WC_Subscriptions_Product::is_subscription($product_id)) {
             continue;
         }
         // If this is an existing item and it's not a subscription, ignore it
         if ($is_existing_item && !WC_Subscriptions_Order::is_item_subscription($order, $product_id)) {
             continue;
         }
         $subscription_key = WC_Subscriptions_Manager::get_subscription_key($post_id, $product_id);
         $subscription = array();
         // If order customer changed, move the subscription from the old customer's account to the new customer
         if (!empty($order->customer_user) && $order->customer_user != (int) $_POST['customer_user']) {
             $subscription = WC_Subscriptions_Manager::remove_users_subscription($order->customer_user, $subscription_key);
             if (!empty($subscription)) {
                 $subscriptions = WC_Subscriptions_Manager::get_users_subscriptions((int) $_POST['customer_user']);
                 $subscriptions[$subscription_key] = $subscription;
                 WC_Subscriptions_Manager::update_users_subscriptions((int) $_POST['customer_user'], $subscriptions);
             }
         }
         // In case it's a new order or the customer has changed
         $order->customer_user = $order->user_id = (int) $_POST['customer_user'];
         $subscription = WC_Subscriptions_Manager::get_users_subscription($order->customer_user, $subscription_key);
         if (empty($subscription)) {
             // Add a new subscription
             // The order may not exist yet, so we need to set a few things ourselves
             if (empty($order->order_key)) {
                 $order->order_key = uniqid('order_');
                 add_post_meta($post_id, '_order_key', $order->order_key, true);
             }
             if (empty($_POST['order_date'])) {
                 $start_date = gmdate('Y-m-d H:i:s');
             } else {
                 $start_date = get_gmt_from_date($_POST['order_date'] . ' ' . (int) $_POST['order_date_hour'] . ':' . (int) $_POST['order_date_minute'] . ':00');
             }
             WC_Subscriptions_Manager::create_pending_subscription_for_order($order, $product_id, array('start_date' => $start_date));
             // Add the subscription meta for this item to the order
             $functions_and_meta = array('get_period' => '_order_subscription_periods', 'get_interval' => '_order_subscription_intervals', 'get_length' => '_order_subscription_lengths');
             foreach ($functions_and_meta as $function_name => $meta_key) {
                 $subscription_meta = self::get_meta($order, $meta_key, array());
                 $subscription_meta[$product_id] = WC_Subscriptions_Product::$function_name($product_id);
                 update_post_meta($order->id, $meta_key, $subscription_meta);
             }
             // This works because process_shop_order_item_meta saves item meta to workaround a WC 1.x bug and in WC 2.0+ meta is added when the item is added via Ajax
             self::process_shop_order_item_meta($post_id, $post);
             // If the order's existing status is something other than pending and the order status is not being changed, manually set the subscription's status (otherwise, it will be handled when WC transitions the order's status)
             if ($order->status == $_POST['order_status'] && 'pending' != $order->status) {
                 switch ($order->status) {
                     case 'completed':
                     case 'processing':
                         WC_Subscriptions_Manager::activate_subscription($order->customer_user, $subscription_key);
                         break;
                     case 'refunded':
                     case 'cancelled':
                         WC_Subscriptions_Manager::cancel_subscription($order->customer_user, $subscription_key);
                         break;
                     case 'failed':
                         WC_Subscriptions_Manager::failed_subscription_signup($order->customer_user, $subscription_key);
                         break;
                 }
             }
         }
     }
     // Determine whether we need to update any subscription dates for existing subscriptions (before the item meta is updated)
     if (!empty($product_ids)) {
         $start_date = $_POST['order_date'] . ' ' . (int) $_POST['order_date_hour'] . ':' . (int) $_POST['order_date_minute'] . ':00';
         // Start date changed for an existing order
         if (!empty($order->order_date) && $order->order_date != $start_date) {
             self::$requires_update['expiration_date'] = array_values($product_ids);
             self::$requires_update['trial_expiration'] = array_values($product_ids);
             self::$requires_update['next_billing_date'] = array_values($product_ids);
         } elseif (isset($_POST['meta_key'])) {
             // WC 2.0+
             $item_meta_keys = isset($_POST['meta_key']) ? $_POST['meta_key'] : array();
             $new_meta_values = isset($_POST['meta_value']) ? $_POST['meta_value'] : array();
             foreach ($item_meta_keys as $item_meta_id => $meta_key) {
                 $meta_data = self::get_item_meta_data($item_meta_id);
                 $product_id = woocommerce_get_order_item_meta($meta_data->order_item_id, '_product_id');
                 // Set flags to update payment dates if required
                 switch ($meta_key) {
                     case '_subscription_period':
                     case '_subscription_interval':
                         if ($new_meta_values[$item_meta_id] != $meta_data->meta_value) {
                             self::$requires_update['next_billing_date'][] = $product_id;
                         }
                         break;
                     case '_subscription_trial_length':
                     case '_subscription_trial_period':
                         if ($new_meta_values[$item_meta_id] != $meta_data->meta_value) {
                             self::$requires_update['expiration_date'][] = $product_id;
                             self::$requires_update['trial_expiration'][] = $product_id;
                             self::$requires_update['next_billing_date'][] = $product_id;
                         }
                         break;
                     case '_subscription_length':
                         if ($new_meta_values[$item_meta_id] != $meta_data->meta_value) {
                             self::$requires_update['expiration_date'][] = $product_id;
                             self::$requires_update['next_billing_date'][] = $product_id;
                         }
                         break;
                 }
             }
         } elseif (isset($_POST['meta_name'])) {
             // WC 1.x
             $item_meta_names = isset($_POST['meta_name']) ? $_POST['meta_name'] : '';
             $item_meta_values = isset($_POST['meta_value']) ? $_POST['meta_value'] : '';
             $item_id_count = count($item_ids);
             for ($i = 0; $i < $item_id_count; $i++) {
                 if (!isset($item_ids[$i]) || !$item_ids[$i]) {
                     continue;
                 } elseif (!in_array($item_ids[$i], $existing_product_ids)) {
                     // New subscriptions throw a false positive
                     continue;
                 }
                 // Meta
                 $item_meta = new WC_Order_Item_Meta();
                 if (isset($item_meta_names[$i]) && isset($item_meta_values[$i])) {
                     $meta_names = $item_meta_names[$i];
                     $meta_values = $item_meta_values[$i];
                     $meta_names_count = count($meta_names);
                     for ($ii = 0; $ii < $meta_names_count; $ii++) {
                         $meta_name = esc_attr($meta_names[$ii]);
                         $meta_value = esc_attr($meta_values[$ii]);
                         if (!isset($meta_name) || !isset($meta_value)) {
                             continue;
                         }
                         // Set flags to update payment dates if required
                         switch ($meta_name) {
                             case '_subscription_period':
                             case '_subscription_interval':
                                 if ($meta_value != self::get_item_meta($order, $meta_name, $item_ids[$i])) {
                                     self::$requires_update['next_billing_date'][] = $item_ids[$i];
                                 }
                                 break;
                             case '_subscription_trial_length':
                             case '_subscription_trial_period':
                                 if ($meta_value != self::get_item_meta($order, $meta_name, $item_ids[$i])) {
                                     self::$requires_update['expiration_date'][] = $item_ids[$i];
                                     self::$requires_update['trial_expiration'][] = $item_ids[$i];
                                     self::$requires_update['next_billing_date'][] = $item_ids[$i];
                                 }
                                 break;
                             case '_subscription_length':
                                 if ($meta_value != self::get_item_meta($order, $meta_name, $item_ids[$i])) {
                                     self::$requires_update['expiration_date'][] = $item_ids[$i];
                                     self::$requires_update['next_billing_date'][] = $item_ids[$i];
                                 }
                                 break;
                         }
                     }
                 }
             }
         }
     }
 }