/** * Creates group membership for the order. * @param int $order_id */ public static function order_status_completed($order_id) { $unhandled = self::register_order($order_id); $order = new WC_Order(); if ($order->get_order($order_id)) { if ($items = $order->get_items()) { if ($user_id = $order->user_id) { // not much we can do if there isn't foreach ($items as $item) { if ($product = $order->get_product_from_item($item)) { if ($product_groups = get_post_meta($product->id, '_groups_groups', false)) { // don't act on subscriptions here if (!class_exists('WC_Subscriptions_Product') || !WC_Subscriptions_Product::is_subscription($product->id)) { if (count($product_groups) > 0) { // add the groups to the user by order and product so that if the product is changed later on, // the data is still valid for what has been purchased $groups_product_groups = get_user_meta($user_id, '_groups_product_groups', true); if (empty($groups_product_groups)) { $groups_product_groups = array(); } $groups_product_groups[$order_id][$product->id]['groups'] = $product_groups; update_user_meta($user_id, '_groups_product_groups', $groups_product_groups); global $groups_ws_product_with_duration; $groups_ws_product_with_duration = Groups_WS_Product::has_duration($product); // add the user to the groups foreach ($product_groups as $group_id) { $result = Groups_User_Group::create(array('user_id' => $user_id, 'group_id' => $group_id)); if ($groups_ws_product_with_duration) { if ($unhandled) { Groups_WS_Terminator::schedule_termination(time() + Groups_WS_Product::get_duration($product), $user_id, $group_id); } } else { Groups_WS_Terminator::mark_as_eternal($user_id, $group_id); } } } } } // remove from groups if ($product_groups_remove = get_post_meta($product->id, '_groups_groups_remove', false)) { if (!class_exists('WC_Subscriptions_Product') || !WC_Subscriptions_Product::is_subscription($product->id)) { if (count($product_groups_remove) > 0) { $groups_product_groups_remove = get_user_meta($user_id, '_groups_product_groups_remove', true); if (empty($groups_product_groups_remove)) { $groups_product_groups_remove = array(); } $groups_product_groups_remove[$order_id][$product->id]['groups'] = $product_groups_remove; update_user_meta($user_id, '_groups_product_groups_remove', $groups_product_groups_remove); // remove the user from the groups foreach ($product_groups_remove as $group_id) { $result = Groups_User_Group::delete($user_id, $group_id); } } } } } } } } } }
/** * Returns an array of order IDs for valid orders that grant group * membership for the given group to the user related to the order. * * @param int $user_id * @param int $group_id * @return array of int, order IDs */ public static function get_valid_order_ids_granting_group_membership_from_order_items($user_id, $group_id) { $order_ids = array(); if (!empty($user_id)) { $base_statuses = array('processing', 'completed'); $statuses = array('completed'); $options = get_option('groups-woocommerce', array()); $order_status = isset($options[GROUPS_WS_MEMBERSHIP_ORDER_STATUS]) ? $options[GROUPS_WS_MEMBERSHIP_ORDER_STATUS] : GROUPS_WS_DEFAULT_MEMBERSHIP_ORDER_STATUS; if ($order_status == 'processing') { $statuses[] = 'processing'; } // DO NOT use groups_ws_order_status( $statuses ) for $statuses or $base_statuses here, // $order->status doesn't provide the wc- prefix. $groups_product_groups = get_user_meta($user_id, '_groups_product_groups', true); if (empty($groups_product_groups)) { $groups_product_groups = array(); } foreach ($groups_product_groups as $order_id => $product_ids) { if ($order = Groups_WS_Helper::get_order($order_id)) { // If this is a completed/processing order, consider group assignments. // We check the order status for non-subscription products below, // for subscriptions the subscription status is checked. if (in_array($order->status, $base_statuses)) { // Note that for orders placed with versions up to 1.4.1, the following won't give the results we might expect if the product group-related information has changed since the order was placed. // As we don't store that information (WC doesn't store the whole lot of the product when purchased, nor does GW) checking the duration based on the product is the best effort at // finding out about the group membership duration we can make. // Use the order items (only existing order items are taken into account). if ($items = $order->get_items()) { foreach ($items as $item) { if ($product = $order->get_product_from_item($item)) { // Use the groups that were stored for the product when it was ordered, // this avoids hickups when the product's groups were changed since. if (isset($product_ids[$product->id]) && isset($product_ids[$product->id]['groups'])) { $product_groups = $product_ids[$product->id]['groups']; if (in_array($group_id, $product_groups)) { // non-subscriptions if (!class_exists('WC_Subscriptions_Product') || !WC_Subscriptions_Product::is_subscription($product->id)) { if (in_array($order->status, $statuses)) { if (isset($product_ids[$product->id]) && isset($product_ids[$product->id]['version'])) { $has_duration = isset($product_ids[$product->id]['duration']) && $product_ids[$product->id]['duration'] && isset($product_ids[$product->id]['duration_uom']); } else { $has_duration = Groups_WS_Product::has_duration($product); } // unlimited membership if (!$has_duration) { if (!in_array($order_id, $order_ids)) { $order_ids[] = $order_id; } } else { if (isset($product_ids[$product->id]) && isset($product_ids[$product->id]['version'])) { $duration = Groups_WS_Product::calculate_duration($product_ids[$product->id]['duration'], $product_ids[$product->id]['duration_uom']); } else { // <= 1.4.1 $duration = Groups_WS_Product::get_duration($product); } // time-limited membership if ($duration) { $start_date = $order->order_date; if ($paid_date = get_post_meta($order_id, '_paid_date', true)) { $start_date = $paid_date; } $end = strtotime($start_date) + $duration; if (time() < $end) { if (!in_array($order_id, $order_ids)) { $order_ids[] = $order_id; } } } } } } else { // include active subscriptions ( subscriptions >= 2.x ) if (function_exists('wcs_get_subscriptions_for_order')) { if ($subscriptions = wcs_get_subscriptions_for_order($order_id)) { if (is_array($subscriptions)) { foreach ($subscriptions as $subscription) { if ($subscription->has_product($product->id)) { $valid = false; if ($subscription->get_status() == 'active') { $valid = true; } else { if ($subscription->get_status() == 'cancelled') { $hook_args = array('subscription_id' => $subscription->id); $end_timestamp = wp_next_scheduled('scheduled_subscription_end_of_prepaid_term', $hook_args); if ($end_timestamp !== false && $end_timestamp > time()) { $valid = true; } } } if ($valid) { if (!in_array($order_id, $order_ids)) { $order_ids[] = $order_id; break; } } } } } } } else { $subscription_key = WC_Subscriptions_Manager::get_subscription_key($order_id, $product->id); $subscription = WC_Subscriptions_Manager::get_subscription($subscription_key); if (isset($subscription['status'])) { $valid = false; if ($subscription['status'] == 'active') { $valid = true; } else { if ($subscription['status'] == 'cancelled') { $hook_args = array('user_id' => (int) $user_id, 'subscription_key' => $subscription_key); $end_timestamp = wp_next_scheduled('scheduled_subscription_end_of_prepaid_term', $hook_args); if ($end_timestamp !== false && $end_timestamp > time()) { $valid = true; } } } if ($valid) { if (!in_array($order_id, $order_ids)) { $order_ids[] = $order_id; } } } } } } } } } } } } } } return $order_ids; }