/**
  * Import user membership from group membership
  *
  * @since 1.0.0
  * @param int $user_id
  * @param int $group_id
  * @param int $plan_id
  * @return int|bool Imported membership ID or false on skip/failure
  */
 private function import_user_membership($user_id, $group_id, $plan_id)
 {
     // User is already a member, skip
     if (wc_memberships_is_user_member($user_id, $plan_id)) {
         return false;
     }
     /**
      * Filter new membership data, used when importing membership from Groups
      *
      * @param array $data
      * @param array $args
      */
     $data = apply_filters('wc_memberships_groups_import_membership_data', array('post_parent' => $plan_id, 'post_author' => $user_id, 'post_type' => 'wc_user_membership', 'post_status' => 'wcm-active', 'comment_status' => 'open'), array('user_id' => $user_id, 'group_id' => $group_id));
     // Create a new membership
     $user_membership_id = wp_insert_post($data);
     // Bail out on failure
     if (is_wp_error($user_membership_id)) {
         return false;
     }
     // Save group ID that granted access
     update_post_meta($user_membership_id, '_group_id', $group_id);
     // Save the membership start date
     update_post_meta($user_membership_id, '_start_date', current_time('mysql', true));
     // Calculate membership end date based on membership length
     $plan = wc_memberships_get_membership_plan($plan_id);
     $end_date = '';
     if ($plan->get_access_length_amount()) {
         $now = current_time('timestamp');
         if (strpos($plan->get_access_length_period(), 'month') !== false) {
             $end = wc_memberships()->add_months($now, $plan->get_access_length_amount());
         } else {
             $end = strtotime('+ ' . $plan->get_access_length(), $now);
         }
         $end_date = date('Y-m-d H:i:s', $end);
     }
     // Save/update end date
     $user_membership = wc_memberships_get_user_membership($user_membership_id);
     $user_membership->set_end_date($end_date);
     // Add membership note
     $group = Groups_Group::read($group_id);
     $user_membership->add_note(sprintf(__('Membership imported from Group "%s" (ID #%d)'), $group->name, $group_id));
     return $user_membership_id;
 }
 /**
  * Grant access to a membership plan
  *
  * @since 1.0.0
  */
 public function grant_access_to_membership()
 {
     global $wpdb;
     if (empty($_REQUEST['post'])) {
         return;
     }
     // Get the ID
     $plan_id = isset($_REQUEST['post']) ? absint($_REQUEST['post']) : '';
     check_admin_referer('wc-memberships-grant-access-plan_' . $plan_id);
     $plan = wc_memberships_get_membership_plan($plan_id);
     $redirect_to = get_edit_post_link($plan_id, 'redirect');
     $product_ids = $plan->get_product_ids();
     $grant_count = 0;
     if (!empty($product_ids)) {
         foreach ($product_ids as $product_id) {
             $sql = "SELECT order_id FROM {$wpdb->prefix}woocommerce_order_items WHERE order_item_id IN ( SELECT order_item_id FROM {$wpdb->prefix}woocommerce_order_itemmeta WHERE meta_key = '_product_id' AND meta_value = {$product_id} ) AND order_item_type = 'line_item'";
             $order_ids = $wpdb->get_col($sql);
             if (empty($order_ids)) {
                 continue;
             }
             foreach ($order_ids as $order_id) {
                 $order = wc_get_order($order_id);
                 if (!$order) {
                     continue;
                 }
                 /**
                  * Filter the array of valid order statuses that grant access
                  *
                  * Allows actors to include additional custom order statuses that
                  * should grant access when the admin uses the "grant previous purchases access"
                  * action
                  *
                  * @since 1.0.0
                  * @param array $valid_order_statuses_for_grant array of order statuses
                  * @param object $plan the associated membership plan object
                  */
                 $valid_order_statuses_for_grant = apply_filters('wc_memberships_grant_access_from_existing_purchase_order_statuses', array('processing', 'completed'), $plan);
                 // skip if purchase doesn't have a valid status
                 if (!$order->has_status($valid_order_statuses_for_grant)) {
                     continue;
                 }
                 $user_id = $order->get_user_id();
                 // Skip if guest purchase or user is already a member
                 if (!$user_id || wc_memberships_is_user_member($user_id, $plan_id)) {
                     continue;
                 }
                 /**
                  * Filter whether an existing purchase of the product should grant access
                  * to the membership plan or not.
                  *
                  * Allows plugins to override if a previously purchased product should
                  * retroactively grant access to a membership plan or not.
                  *
                  * @since 1.0.0
                  * @param array $args
                  */
                 $grant_access = apply_filters('wc_memberships_grant_access_from_existing_purchase', true, array('user_id' => $user_id, 'product_id' => $product_id, 'order_id' => $order_id));
                 if (!$grant_access) {
                     continue;
                 }
                 // Grant access
                 $result = $plan->grant_access_from_purchase($user_id, $product_id, $order_id);
                 if ($result) {
                     $grant_count++;
                 }
             }
         }
     }
     // Add admin message
     if ($grant_count) {
         $message = sprintf(_n('%d customer was granted access from existing purchases.', '%d customers were granted access from existing purchases', $grant_count, WC_Memberships::TEXT_DOMAIN), $grant_count);
     } else {
         $message = __('No customers were granted access from existing purchases.', WC_Memberships::TEXT_DOMAIN);
     }
     wc_memberships()->admin->message_handler->add_message($message);
     // Redirect back to the edit screen
     wp_safe_redirect($redirect_to);
     exit;
 }
 /**
  * Grant a user access to this plan from a purchase
  *
  * @since 1.0.0
  * @param int $user_id User ID
  * @param int $product_id Product ID
  * @param int $order_id Order ID
  * @return int|null New/Existing User Membership ID or null on failure
  */
 public function grant_access_from_purchase($user_id, $product_id, $order_id)
 {
     $user_membership_id = null;
     $action = 'create';
     // Check if user is perhaps a member, but membership is expired/cancelled
     if (wc_memberships_is_user_member($user_id, $this->get_id())) {
         $user_membership = wc_memberships_get_user_membership($user_id, $this->get_id());
         $user_membership_id = $user_membership->get_id();
         // Do not allow the same order to renew or reactivate the membership. This
         // prevents admins changing order statuses from extending/reactivating the
         // membership.
         $order_ids = get_post_meta($user_membership_id, '_order_id');
         if (!empty($order_ids) && in_array($order_id, $order_ids)) {
             return null;
         }
         // Otherwise... continue as usual
         $action = 'reactivate';
         if (wc_memberships_is_user_active_member($user_id, $this->get_id())) {
             /**
              * Filter whether an already active membership will be renewed
              *
              * @since 1.0.0
              * @param bool $renew
              * @param WC_Memberships_Membership_Plan $plan
              * @param array $args
              */
             $renew_membership = apply_filters('wc_memberships_renew_membership', (bool) $this->get_access_length_amount(), $this, array('user_id' => $user_id, 'product_id' => $product_id, 'order_id' => $order_id));
             if (!$renew_membership) {
                 return null;
             }
             $action = 'renew';
         }
     }
     // Create/update the user membership
     $user_membership = wc_memberships_create_user_membership(array('user_membership_id' => $user_membership_id, 'user_id' => $user_id, 'product_id' => $product_id, 'order_id' => $order_id, 'plan_id' => $this->get_id()), $action);
     // Add membership note
     $product = wc_get_product($product_id);
     $order = wc_get_order($order_id);
     $user_membership->add_note(sprintf(__('Membership access granted from purchasing %s (Order %s)'), $product->get_title(), $order->get_order_number()));
     /**
      * Fires after a user has been granted membership access from a purchase
      *
      * @since 1.0.0
      * @param WC_Memberships_Membership_Plan $membership_plan The plan that user was granted access to
      * @param array $args
      */
     do_action('wc_memberships_grant_membership_access_from_purchase', $this, array('user_id' => $user_id, 'product_id' => $product_id, 'order_id' => $order_id, 'user_membership_id' => $user_membership->get_id()));
     return $user_membership->get_id();
 }