/**
  * Get a list of products that grant access to a piece of content
  *
  * @since 1.0.0
  * @param int $post_id
  * @param string $rule_type
  * @return array|null
  */
 private function get_products_that_grant_access($post_id = null, $rule_type = null)
 {
     // Default to the 'current' post
     if (!$post_id) {
         global $post;
         $post_id = $post->ID;
     }
     // Get applied rules
     if ('purchasing_discount' == $rule_type) {
         $rules = wc_memberships()->rules->get_product_purchasing_discount_rules($post_id);
     } else {
         if (in_array(get_post_type($post_id), array('product', 'product_variation'))) {
             $rules = wc_memberships()->rules->get_the_product_restriction_rules($post_id);
         } else {
             $rules = wc_memberships()->rules->get_post_content_restriction_rules($post_id);
         }
     }
     // Find products that grant access
     $processed_plans = array();
     // holder for membership plans that have been processed already
     $products = array();
     foreach ($rules as $rule) {
         // Skip further checks if this membership plan has already been processed
         if (in_array($rule->get_membership_plan_id(), $processed_plans)) {
             continue;
         }
         $plan = wc_memberships_get_membership_plan($rule->get_membership_plan_id());
         if ($plan && $plan->has_products()) {
             foreach ($plan->get_product_ids() as $product_id) {
                 $products[] = $product_id;
             }
         }
         // Mark this plan as processed, we do not need look into it any further,
         // because we already know if it has any products that grant access or not.
         $processed_plans[] = $rule->get_membership_plan_id();
     }
     return !empty($products) ? $products : null;
 }
 /**
  * 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;
 }
 /**
  * View site as a member of a particular plan
  *
  * @since 1.0.0
  */
 public function view_as_member()
 {
     if (empty($_REQUEST['post'])) {
         return;
     }
     // Get the plan post ID
     $id = isset($_REQUEST['post']) ? absint($_REQUEST['post']) : '';
     check_admin_referer('wc-memberships-view-as-member-of_' . $id);
     $plan = wc_memberships_get_membership_plan($id);
     // Bail out if plan could not be determined
     if (!$id || !$plan) {
         return;
     }
     // Create a temporary user
     $username = uniqid('wcm_');
     /**
      * Filter temporary user data
      *
      * Allows adjusting the data for a temporary user, which is
      * created to allow viewing the site as a member of a particular
      * membership plan
      *
      * @since 1.0.0
      * @param array $data
      * @param WC_Memberships_Membership_Plan $plan
      */
     $temp_user_data = apply_filters('wc_memberships_temporary_user_data', array('user_login' => $username, 'user_pass' => uniqid('wcmp_'), 'user_email' => $username . '@.example.com', 'first_name' => sprintf(__('%s Plan', WC_Memberships::TEXT_DOMAIN), $plan->get_name()), 'last_name' => __('Test User', WC_Memberships::TEXT_DOMAIN), 'description' => sprintf(__("A temporary user created for testing the %s plan membership. If you don't use it, feel free to delete this user."), $plan->get_name()), 'role' => 'customer'), $plan);
     $user_id = wp_insert_user($temp_user_data);
     if (is_wp_error($user_id)) {
         return;
     }
     // Set a temporary value in DB indicating which temporary user has been created for the current user
     set_transient('wc_memberships_user_' . get_current_user_id() . '_viewing_as', $user_id, YEAR_IN_SECONDS);
     update_user_meta($user_id, '_wc_memberships_temp_user', 1);
     // Create user membership
     $membership_id = wp_insert_post(array('post_type' => 'wc_user_membership', 'post_parent' => $plan->get_id(), 'post_author' => $user_id, 'post_status' => 'wcm-active'));
     // Set membership start date to now
     update_post_meta($membership_id, '_start_date', current_time('mysql', true));
     $user = get_user_by('id', $user_id);
     // Now switch to that user
     $link = add_query_arg(array('action' => 'switch_to_user', 'user_id' => $user->ID, '_wpnonce' => wp_create_nonce("switch_to_user_{$user->ID}")), wp_login_url());
     wp_redirect($link);
     exit;
 }
 /**
  * Get the plan object
  *
  * @since 1.0.0
  * @return WC_Memberships_User_Membership Instance of WC_Memberships_User_Membership
  */
 public function get_plan()
 {
     if (!$this->plan) {
         $this->plan = wc_memberships_get_membership_plan($this->get_plan_id());
     }
     return $this->plan;
 }
 /**
  * Check if the membership plan has at least one subscription product that grants access
  *
  * @since 1.0.0
  * @param int $plan_id Membership Plan ID
  * @return bool True, if has a subscription product, false otherwise
  */
 public function has_membership_plan_subscription($plan_id)
 {
     if (!isset($this->_has_membership_plan_subscription[$plan_id])) {
         $plan = wc_memberships_get_membership_plan($plan_id);
         $product_ids = $plan->get_product_ids();
         $product_ids = !empty($product_ids) ? array_map('absint', $product_ids) : null;
         $this->_has_membership_plan_subscription[$plan_id] = false;
         if (!empty($product_ids)) {
             foreach ($product_ids as $product_id) {
                 if (!is_numeric($product_id) || !$product_id) {
                     continue;
                 }
                 $product = wc_get_product($product_id);
                 if (!$product) {
                     continue;
                 }
                 if ($product->is_type(array('subscription', 'subscription_variation', 'variable-subscription'))) {
                     $this->_has_membership_plan_subscription[$plan_id] = true;
                     break;
                 }
             }
         }
     }
     return $this->_has_membership_plan_subscription[$plan_id];
 }
 /**
  * Get user's membership
  * Supports getting user membership by membership ID, Post object
  * or a combination of the user ID and membership plan id/slug/Post object.
  *
  * If no $id is provided, defaults to getting the membership for the current user.
  *
  * @since 1.0.0
  * @param mixed $id Optional. Post object or post ID of the user membership, or user ID
  * @param mixed $plan Optional. Membership Plan slug, post object or related post ID
  * @return WC_Memberships_User_Membership|bool false on failure
  */
 public function get_user_membership($id = null, $plan = null)
 {
     // If a plan is provided, try to find user membership using user ID + plan ID
     if ($plan) {
         $user_id = $id ? $id : get_current_user_id();
         $membership_plan = wc_memberships_get_membership_plan($plan);
         // Bail out if no user ID or membership plan
         if (!$user_id || !$membership_plan) {
             return false;
         }
         $args = array('author' => $user_id, 'post_type' => 'wc_user_membership', 'post_parent' => $membership_plan->get_id(), 'post_status' => 'any');
         $user_memberships = get_posts($args);
         $post = !empty($user_memberships) ? $user_memberships[0] : null;
     } else {
         $post = $id;
         // Get from globals
         if (false === $post) {
             $post = $GLOBALS['post'];
         } elseif (is_numeric($post)) {
             $post = get_post($post);
         } elseif ($post instanceof WC_Memberships_User_Membership) {
             $post = get_post($post->get_id());
         } elseif (!$post instanceof WP_Post) {
             $post = false;
         }
     }
     // If no acceptable post is found, bail out
     if (!$post || 'wc_user_membership' !== get_post_type($post)) {
         return false;
     }
     return new WC_Memberships_User_Membership($post);
 }
 /**
  * Checks if a user has a certain capability
  *
  * @since 1.0.0
  * @param array $allcaps
  * @param array $caps
  * @param array $args
  * @return array
  */
 public function user_has_cap($allcaps, $caps, $args)
 {
     global $pagenow, $typenow;
     if (isset($caps[0])) {
         switch ($caps[0]) {
             case 'wc_memberships_access_all_restricted_content':
                 if ($this->can_manage_woocommerce($allcaps)) {
                     $allcaps[$caps[0]] = true;
                     break;
                 }
                 break;
             case 'wc_memberships_view_restricted_post_content':
                 if ($this->can_manage_woocommerce($allcaps)) {
                     $allcaps[$caps[0]] = true;
                     break;
                 }
                 $user_id = $args[1];
                 $post_id = $args[2];
                 if ($this->post_is_public($post_id)) {
                     $allcaps[$caps[0]] = true;
                     break;
                 }
                 $rules = wc_memberships()->rules->get_post_content_restriction_rules($post_id);
                 $allcaps[$caps[0]] = wc_memberships()->rules->user_has_content_access_from_rules($user_id, $rules, $post_id);
                 break;
             case 'wc_memberships_view_restricted_product':
                 if ($this->can_manage_woocommerce($allcaps)) {
                     $allcaps[$caps[0]] = true;
                     break;
                 }
                 $user_id = $args[1];
                 $post_id = $args[2];
                 if ($this->post_is_public($post_id)) {
                     $allcaps[$caps[0]] = true;
                     break;
                 }
                 $rules = wc_memberships()->rules->get_the_product_restriction_rules($post_id);
                 $allcaps[$caps[0]] = wc_memberships()->rules->user_has_product_view_access_from_rules($user_id, $rules, $post_id);
                 break;
             case 'wc_memberships_purchase_restricted_product':
                 if ($this->can_manage_woocommerce($allcaps)) {
                     $allcaps[$caps[0]] = true;
                     break;
                 }
                 $user_id = $args[1];
                 $post_id = $args[2];
                 if ($this->post_is_public($post_id)) {
                     $allcaps[$caps[0]] = true;
                     break;
                 }
                 $rules = wc_memberships()->rules->get_the_product_restriction_rules($post_id);
                 $allcaps[$caps[0]] = wc_memberships()->rules->user_has_product_purchase_access_from_rules($user_id, $rules, $post_id);
                 break;
             case 'wc_memberships_view_restricted_taxonomy_term':
                 if ($this->can_manage_woocommerce($allcaps)) {
                     $allcaps[$caps[0]] = true;
                     break;
                 }
                 $user_id = $args[1];
                 $taxonomy = $args[2];
                 $term_id = $args[3];
                 $rules = wc_memberships()->rules->get_taxonomy_term_content_restriction_rules($taxonomy, $term_id);
                 $allcaps[$caps[0]] = wc_memberships()->rules->user_has_content_access_from_rules($user_id, $rules, $term_id);
                 break;
             case 'wc_memberships_view_restricted_taxonomy':
                 if ($this->can_manage_woocommerce($allcaps)) {
                     $allcaps[$caps[0]] = true;
                     break;
                 }
                 $user_id = $args[1];
                 $taxonomy = $args[2];
                 $rules = wc_memberships()->rules->get_taxonomy_content_restriction_rules($taxonomy);
                 $allcaps[$caps[0]] = wc_memberships()->rules->user_has_content_access_from_rules($user_id, $rules);
                 break;
             case 'wc_memberships_view_restricted_post_type':
                 if ($this->can_manage_woocommerce($allcaps)) {
                     $allcaps[$caps[0]] = true;
                     break;
                 }
                 $user_id = $args[1];
                 $post_type = $args[2];
                 if (in_array($post_type, array('product', 'product_variation'))) {
                     $rules = wc_memberships()->rules->get_product_restriction_rules(array('content_type' => 'post_type', 'content_type_name' => 'product'));
                     $allcaps[$caps[0]] = wc_memberships()->rules->user_has_product_view_access_from_rules($user_id, $rules);
                 } else {
                     $rules = wc_memberships()->rules->get_post_type_content_restriction_rules($post_type);
                     $allcaps[$caps[0]] = wc_memberships()->rules->user_has_content_access_from_rules($user_id, $rules);
                 }
                 break;
             case 'wc_memberships_view_delayed_post_type':
                 if ($this->can_manage_woocommerce($allcaps)) {
                     $allcaps[$caps[0]] = true;
                     break;
                 }
                 $user_id = $args[1];
                 $post_type = $args[2];
                 $has_access = false;
                 $access_time = $this->get_user_access_start_time_for_post_type($user_id, $post_type);
                 if ($access_time && current_time('timestamp', true) >= $access_time) {
                     $has_access = true;
                 }
                 $allcaps[$caps[0]] = $has_access;
                 break;
             case 'wc_memberships_view_delayed_taxonomy':
                 if ($this->can_manage_woocommerce($allcaps)) {
                     $allcaps[$caps[0]] = true;
                     break;
                 }
                 $user_id = $args[1];
                 $taxonomy = $args[2];
                 $has_access = false;
                 $access_time = $this->get_user_access_start_time_for_taxonomy($user_id, $taxonomy);
                 if ($access_time && current_time('timestamp', true) >= $access_time) {
                     $has_access = true;
                 }
                 $allcaps[$caps[0]] = $has_access;
                 break;
             case 'wc_memberships_view_delayed_taxonomy_term':
                 if ($this->can_manage_woocommerce($allcaps)) {
                     $allcaps[$caps[0]] = true;
                     break;
                 }
                 $user_id = $args[1];
                 $taxonomy = $args[2];
                 $term = $args[3];
                 $has_access = false;
                 $access_time = $this->get_user_access_start_time_for_taxonomy_term($user_id, $taxonomy, $term);
                 if ($access_time && current_time('timestamp', true) >= $access_time) {
                     $has_access = true;
                 }
                 $allcaps[$caps[0]] = $has_access;
                 break;
             case 'wc_memberships_view_delayed_post_content':
             case 'wc_memberships_view_delayed_product':
                 if ($this->can_manage_woocommerce($allcaps)) {
                     $allcaps[$caps[0]] = true;
                     break;
                 }
                 $user_id = $args[1];
                 $post_id = $args[2];
                 $has_access = false;
                 if ($this->post_is_public($post_id)) {
                     $allcaps[$caps[0]] = true;
                     break;
                 }
                 $access_time = $this->get_user_access_start_time_for_post($user_id, $post_id, 'view');
                 if ($access_time && current_time('timestamp', true) >= $access_time) {
                     $has_access = true;
                 }
                 $allcaps[$caps[0]] = $has_access;
                 break;
             case 'wc_memberships_purchase_delayed_product':
                 if ($this->can_manage_woocommerce($allcaps)) {
                     $allcaps[$caps[0]] = true;
                     break;
                 }
                 $user_id = $args[1];
                 $post_id = $args[2];
                 $has_access = false;
                 if ($this->post_is_public($post_id)) {
                     $allcaps[$caps[0]] = true;
                     break;
                 }
                 $access_time = $this->get_user_access_start_time_for_post($user_id, $post_id, 'purchase');
                 if ($access_time && current_time('timestamp', true) >= $access_time) {
                     $has_access = true;
                 }
                 $allcaps[$caps[0]] = $has_access;
                 break;
                 // Editing a rule depends on the rule's content type and related capabilities
             // Editing a rule depends on the rule's content type and related capabilities
             case 'wc_memberships_edit_rule':
                 $user_id = $args[1];
                 $rule_id = $args[2];
                 $can_edit = false;
                 $rule = wc_memberships()->rules->get_rule($rule_id);
                 if ($rule) {
                     switch ($rule->get_content_type()) {
                         case 'post_type':
                             $post_type = get_post_type_object($rule->get_content_type_name());
                             if (!$post_type) {
                                 return false;
                             }
                             $can_edit = current_user_can($post_type->cap->edit_posts) && current_user_can($post_type->cap->edit_others_posts);
                             break;
                         case 'taxonomy':
                             $taxonomy = get_taxonomy($rule->get_content_type_name());
                             if (!$taxonomy) {
                                 return false;
                             }
                             $can_edit = current_user_can($taxonomy->cap->manage_terms) && current_user_can($taxonomy->cap->edit_terms);
                             break;
                     }
                 }
                 $allcaps[$caps[0]] = $can_edit;
                 break;
             case 'wc_memberships_cancel_membership':
             case 'wc_memberships_renew_membership':
                 $user_id = $args[1];
                 $user_membership_id = $args[2];
                 $user_membership = wc_memberships_get_user_membership($user_membership_id);
                 // complimentary memberships cannot be cancelled or renewed by the user
                 $allcaps[$caps[0]] = $user_membership && $user_membership->get_user_id() == $user_id && !$user_membership->has_status('complimentary');
                 break;
                 // Prevent deleting membership plans with active memberships
             // Prevent deleting membership plans with active memberships
             case 'delete_published_membership_plan':
             case 'delete_published_membership_plans':
                 // This workaround (*hack*, *cough*) allows displaying the trash/delete
                 // link on membership plans list table even if the plan has active members
                 if (is_admin() && 'edit.php' == $pagenow && 'wc_membership_plan' == $typenow && empty($_POST)) {
                     break;
                 }
                 $post_id = $args[2];
                 $plan = wc_memberships_get_membership_plan($post_id);
                 if ($plan->has_active_memberships()) {
                     $allcaps[$caps[0]] = false;
                 }
                 break;
         }
     }
     return $allcaps;
 }
    /**
     * Display the membership data meta box
     *
     * @param WP_Post $post
     * @since 1.0.0
     */
    public function output(WP_Post $post)
    {
        global $post;
        $membership_plan = wc_memberships_get_membership_plan($post);
        // Place post types and taxonomies into separate option groups
        // so that they are easier to distinguish visually.
        $content_restriction_content_type_options = array('post_types' => array(), 'taxonomies' => array());
        // We need to prefix post_type/taxonomy names (values), so that
        // if a post type and taxonomy share a name, we can still distinguish
        // between them
        foreach (wc_memberships()->admin->get_valid_post_types_for_content_restriction() as $post_type_name => $post_type) {
            $content_restriction_content_type_options['post_types']['post_type|' . $post_type_name] = $post_type;
        }
        foreach (wc_memberships()->admin->get_valid_taxonomies_for_content_restriction() as $taxonomy_name => $taxonomy) {
            $content_restriction_content_type_options['taxonomies']['taxonomy|' . $taxonomy_name] = $taxonomy;
        }
        // Prepare access_length period toggler options
        $access_length_period_toggler_options = array('unlimited' => __('unlimited', WC_Memberships::TEXT_DOMAIN), 'specific' => __('specify a length', WC_Memberships::TEXT_DOMAIN));
        // Prepare access_schedule period toggler options
        $access_schedule_period_toggler_options = array('immediate' => __('immediately', WC_Memberships::TEXT_DOMAIN), 'specific' => __('specify a time', WC_Memberships::TEXT_DOMAIN));
        $period_options = array('days' => __('day(s)', WC_Memberships::TEXT_DOMAIN), 'weeks' => __('week(s)', WC_Memberships::TEXT_DOMAIN), 'months' => __('month(s)', WC_Memberships::TEXT_DOMAIN), 'years' => __('year(s)', WC_Memberships::TEXT_DOMAIN));
        // Get applied content restriction rules
        $content_restriction_rules = $membership_plan->get_content_restriction_rules();
        // Add empty option to create a HTML template for new rules
        $content_restriction_rules['__INDEX__'] = new WC_Memberships_Membership_Plan_Rule(array('rule_type' => 'content_restriction', 'membership_plan_id' => $post->ID, 'id' => '', 'content_type' => '', 'content_type_name' => '', 'object_ids' => array(), 'access_schedule' => 'immediate', 'access_schedule_exclude_trial' => 'no'));
        // Prepare product content type options
        $post_type_product = get_post_type_object('product');
        $product_restriction_content_type_options = $purchasing_discount_content_type_options = array('post_types' => array('post_type|product' => $post_type_product), 'taxonomies' => array());
        // prepare product restriction access_type options
        $product_restriction_access_type_options = array('view' => __('View', WC_Memberships::TEXT_DOMAIN), 'purchase' => __('Purchase', WC_Memberships::TEXT_DOMAIN));
        foreach (wc_memberships()->admin->get_valid_taxonomies_for_product_restriction() as $taxonomy_name => $taxonomy) {
            $product_restriction_content_type_options['taxonomies']['taxonomy|' . $taxonomy_name] = $taxonomy;
        }
        foreach (wc_memberships()->admin->get_valid_taxonomies_for_purchasing_discounts() as $taxonomy_name => $taxonomy) {
            $purchasing_discount_content_type_options['taxonomies']['taxonomy|' . $taxonomy_name] = $taxonomy;
        }
        // Get applied product restriction rules
        $product_restriction_rules = $membership_plan->get_product_restriction_rules();
        // Add empty option to create a HTML template for new rules
        $product_restriction_rules['__INDEX__'] = new WC_Memberships_Membership_Plan_Rule(array('rule_type' => 'product_restriction', 'membership_plan_id' => $post->ID, 'id' => '', 'content_type' => '', 'content_type_name' => '', 'object_ids' => array(), 'access_type' => '', 'access_schedule' => 'immediate', 'access_schedule_exclude_trial' => 'no'));
        // prepare product restriction access_type options
        $purchasing_discount_type_options = array('percentage' => '%', 'amount' => '$');
        // Get applied product restriction rules
        $purchasing_discount_rules = $membership_plan->get_purchasing_discount_rules();
        // Add empty option to create a HTML template for new rules
        $purchasing_discount_rules['__INDEX__'] = new WC_Memberships_Membership_Plan_Rule(array('rule_type' => 'purchasing_discount', 'membership_plan_id' => $post->ID, 'id' => '', 'content_type' => '', 'content_type_name' => '', 'object_ids' => array(), 'discount_type' => '', 'discount_amount' => '', 'active' => ''));
        ?>

		<div class="panel-wrap data">

			<?php 
        if (!SV_WC_Plugin_Compatibility::is_wc_version_gte_2_3()) {
            ?>
				<div class="wc-tabs-back"></div>
			<?php 
        }
        ?>

			<ul class="membership_plan_data_tabs wc-tabs">
				<?php 
        /**
         * Filter membership plan data tabs
         *
         * @since 1.0.0
         * @param array $tabs Associative array of membership plan tabs
         */
        $membership_plan_data_tabs = apply_filters('wc_membership_plan_data_tabs', array('general' => array('label' => __('General', WC_Memberships::TEXT_DOMAIN), 'target' => 'membership-plan-data-general', 'class' => array('active')), 'restrict_content' => array('label' => __('Restrict Content', WC_Memberships::TEXT_DOMAIN), 'target' => 'membership-plan-data-restrict-content'), 'restrict_products' => array('label' => __('Restrict Products', WC_Memberships::TEXT_DOMAIN), 'target' => 'membership-plan-data-restrict-products'), 'purchasing_discounts' => array('label' => __('Purchasing Discounts', WC_Memberships::TEXT_DOMAIN), 'target' => 'membership-plan-data-purchasing-discounts')));
        foreach ($membership_plan_data_tabs as $key => $tab) {
            $class = isset($tab['class']) ? $tab['class'] : array();
            ?>
<li class="<?php 
            echo sanitize_html_class($key);
            ?>
_options <?php 
            echo sanitize_html_class($key);
            ?>
_tab <?php 
            echo implode(' ', array_map('sanitize_html_class', $class));
            ?>
">
							<a href="#<?php 
            echo esc_attr($tab['target']);
            ?>
"><?php 
            echo esc_html($tab['label']);
            ?>
</a>
						</li><?php 
        }
        /**
         * Fires after the membership plan write panel tabs are displayed
         *
         * @since 1.0.0
         */
        do_action('wc_membership_plan_write_panel_tabs');
        ?>
			</ul>


			<div id="membership-plan-data-general" class="panel woocommerce_options_panel"><?php 
        echo '<div class="options_group">';
        // Slug
        woocommerce_wp_text_input(array('id' => 'post_name', 'label' => __('Slug', WC_Memberships::TEXT_DOMAIN), 'value' => $post->post_name));
        echo '</div>';
        echo '<div class="options_group">';
        ?>
				<p class="form-field"><label for="_product_ids"><?php 
        esc_html_e('Grant Access to people who purchase:', WC_Memberships::TEXT_DOMAIN);
        ?>
</label>

				<?php 
        if (SV_WC_Plugin_Compatibility::is_wc_version_gte_2_3()) {
            ?>
					<input type="hidden" id="_product_ids" name="_product_ids" class="js-ajax-select-products" style="width: 50%;" data-placeholder="<?php 
            esc_attr_e('Search for a product&hellip;', WC_Memberships::TEXT_DOMAIN);
            ?>
" data-multiple="true" data-selected="<?php 
            $product_ids = array_filter(array_map('absint', (array) get_post_meta($post->ID, '_product_ids', true)));
            $json_ids = array();
            foreach ($product_ids as $product_id) {
                $product = wc_get_product($product_id);
                if (is_object($product)) {
                    $json_ids[$product_id] = wp_kses_post(html_entity_decode($product->get_formatted_name()));
                }
            }
            echo esc_attr(wc_memberships()->wp_json_encode($json_ids));
            ?>
" value="<?php 
            echo esc_attr(implode(',', array_keys($json_ids)));
            ?>
" />
				<?php 
        } else {
            ?>
					<select id="_product_ids" id="_product_ids" name="_product_ids[]" class="ajax_chosen_select_products js-ajax-select-products" multiple="multiple" data-placeholder="<?php 
            esc_attr_e('Search for a product&hellip;', WC_Memberships::TEXT_DOMAIN);
            ?>
">
						<?php 
            if ($membership_plan->get_product_ids()) {
                foreach ($membership_plan->get_product_ids() as $product_id) {
                    $product = wc_get_product($product_id);
                    if ($product) {
                        echo '<option value="' . esc_attr($product_id) . '" selected="selected">' . strip_tags($product->get_formatted_name()) . '</option>';
                    }
                }
            }
            ?>
					</select>
				<?php 
        }
        ?>

				<img class="help_tip" data-tip="<?php 
        esc_attr_e('Leave empty to only allow members you manually assign.', WC_Memberships::TEXT_DOMAIN);
        ?>
" src="<?php 
        echo esc_url(WC()->plugin_url());
        ?>
/assets/images/help.png" height="16" width="16" />

				</p>

				<p class="form-field plan-access-length-field">
					<label for="_access_length"><?php 
        esc_html_e('Membership Length', WC_Memberships::TEXT_DOMAIN);
        ?>
</label>

					<span class="plan-access-length-selectors">
						<?php 
        $current_access_length = $membership_plan->get_access_length() ? 'specific' : 'unlimited';
        ?>
						<?php 
        foreach ($access_length_period_toggler_options as $value => $label) {
            ?>
							<label class="label-radio">
								<input type="radio" name="_access_length" class="js-access-length-period-selector js-access-length-type" value="<?php 
            echo esc_attr($value);
            ?>
" <?php 
            checked($value, $current_access_length);
            ?>
 />
								<?php 
            echo esc_html($label);
            ?>
							</label>
						<?php 
        }
        ?>
						<img class="help_tip" data-tip="<?php 
        esc_attr_e('When does the membership expire?', WC_Memberships::TEXT_DOMAIN);
        ?>
" src="<?php 
        echo esc_url(WC()->plugin_url());
        ?>
/assets/images/help.png" height="16" width="16" />
					</span>

					<span class="plan-access-length-specific js-hide-if-access-length-unlimited <?php 
        if (!$membership_plan->get_access_length()) {
            ?>
hide<?php 
        }
        ?>
">

						<input type="number" min="0" name="_access_length_amount" id="_access_length_amount" value="<?php 
        echo esc_attr($membership_plan->get_access_length_amount());
        ?>
" class="access_length-amount" />

						<select name="_access_length_period" id="_access_length_period" class="short access_length-period js-access-length-period-selector">
							<?php 
        foreach ($period_options as $key => $label) {
            ?>
								<option value="<?php 
            echo esc_attr($key);
            ?>
" <?php 
            selected($key, $membership_plan->get_access_length_period());
            ?>
><?php 
            echo esc_html($label);
            ?>
</option>
							<?php 
        }
        ?>
						</select>

					</span>

				</p>

				<?php 
        echo '</div>';
        /**
         * Fires after the membership plan general data panel is displayed
         *
         * @since 1.0.0
         */
        do_action('wc_membership_plan_options_membership_plan_data_general');
        ?>
			</div><!-- //#membership-plan-data-general -->


			<div id="membership-plan-data-restrict-content" class="panel woocommerce_options_panel">

				<div class="table-wrap">
					<?php 
        require wc_memberships()->get_plugin_path() . '/includes/admin/meta-boxes/views/html-content-restriction-rules.php';
        ?>
				</div>

				<?php 
        if ($public_posts = wc_memberships()->rules->get_public_posts()) {
            ?>
					<p><?php 
            printf(__('These posts are public, and will be excluded from all restriction rules: %s', WC_Memberships::TEXT_DOMAIN), wc_memberships()->admin_list_post_links($public_posts));
            ?>
</p>
				<?php 
        }
        ?>

				<?php 
        /**
         * Fires after the membership plan content restriction panel is displayed
         *
         * @since 1.0.0
         */
        do_action('wc_membership_plan_options_membership_plan_data_restrict_content');
        ?>
			</div><!-- //#membership-plan-data-restrict-content -->


			<div id="membership-plan-data-restrict-products" class="panel woocommerce_options_panel">

				<div class="table-wrap">
					<?php 
        require wc_memberships()->get_plugin_path() . '/includes/admin/meta-boxes/views/html-product-restriction-rules.php';
        ?>
				</div>

				<?php 
        if ($public_products = wc_memberships()->rules->get_public_products()) {
            ?>
					<p><?php 
            printf(__('These products are public, and will be excluded from all restriction rules: %s', WC_Memberships::TEXT_DOMAIN), wc_memberships()->admin_list_post_links($public_products));
            ?>
</p>
				<?php 
        }
        ?>

				<?php 
        /**
         * Fires after the membership plan product restriction panel is displayed
         *
         * @since 1.0.0
         */
        do_action('wc_membership_plan_options_membership_plan_data_restrict_products');
        ?>
			</div><!-- //#membership-plan-data-restrict-products -->


			<div id="membership-plan-data-purchasing-discounts" class="panel woocommerce_options_panel">

				<div class="table-wrap">
					<?php 
        require wc_memberships()->get_plugin_path() . '/includes/admin/meta-boxes/views/html-purchasing-discount-rules.php';
        ?>
				</div>

				<?php 
        /**
         * Fires after the membership plan purchasing discounts panel is displayed
         *
         * @since 1.0.0
         */
        do_action('wc_membership_plan_options_membership_plan_data_purchasing_discounts');
        ?>
			</div><!-- //#membership-plan-data-purchase-discounts -->

			<?php 
        /**
         * Fires after the membership plan data panels are displayed
         *
         * @since 1.0.0
         */
        do_action('wc_membership_plan_data_panels');
        ?>

			<div class="clear"></div>

		</div><!-- //.panel-wrap -->

		<?php 
    }
 /**
  * Get all membership plans
  *
  * @since 1.0.0
  * @param array $args Optional array of arguments. Same as for get_posts.
  * @return array $plans Array of membership plans
  */
 public function get_membership_plans($args = array())
 {
     $defaults = array('posts_per_page' => -1);
     $args = wp_parse_args($args, $defaults);
     $args['post_type'] = 'wc_membership_plan';
     // Unique key for caching the applied rule results
     $cache_key = http_build_query($args);
     if (!isset($this->membership_plans[$cache_key])) {
         $membership_plan_posts = get_posts($args);
         $this->membership_plans[$cache_key] = array();
         if (!empty($membership_plan_posts)) {
             foreach ($membership_plan_posts as $post) {
                 $this->membership_plans[$cache_key][] = wc_memberships_get_membership_plan($post);
             }
         }
     }
     return $this->membership_plans[$cache_key];
 }
/**
 * Create a new user membership programmatically
 *
 * Returns a new user membership object on success which can then be used to add additional data.
 *
 * @since 1.3.0
 * @param array $args Array of arguments
 * @param string $action Action - either 'create' or 'renew'. When in doubt, use 'create'
 * @return WC_Memberships_User_Membership on success, WP_Error on failure
 */
function wc_memberships_create_user_membership($args = array(), $action = 'create')
{
    $defaults = array('user_membership_id' => 0, 'plan_id' => 0, 'user_id' => 0, 'product_id' => 0, 'order_id' => 0);
    $args = wp_parse_args($args, $defaults);
    $data = array('post_parent' => $args['plan_id'], 'post_author' => $args['user_id'], 'post_type' => 'wc_user_membership', 'post_status' => 'wcm-active', 'comment_status' => 'open');
    if ($args['user_membership_id'] > 0) {
        $updating = true;
        $data['ID'] = $args['user_membership_id'];
    } else {
        $updating = false;
    }
    /**
     * Filter new membership data, used when a product purchase grants access
     *
     * @param array $data
     * @param array $args
     */
    $data = apply_filters('wc_memberships_new_membership_data', $data, array('user_id' => $args['user_id'], 'product_id' => $args['product_id'], 'order_id' => $args['order_id']));
    if ($updating) {
        $user_membership_id = wp_update_post($data);
    } else {
        $user_membership_id = wp_insert_post($data);
    }
    // Bail out on error
    if (is_wp_error($user_membership_id)) {
        return $user_membership_id;
    }
    // Save/update product and order id that granted access
    if ($args['product_id'] > 0) {
        update_post_meta($user_membership_id, '_product_id', $args['product_id']);
    }
    if ($args['order_id'] > 0) {
        update_post_meta($user_membership_id, '_order_id', $args['order_id']);
    }
    // Save/update the membership start date, but only if the membership
    // is not active, ie is not being renewed early.
    if ('renew' != $action) {
        update_post_meta($user_membership_id, '_start_date', current_time('mysql', true));
    }
    // Get the membership plan object so we can calculate end time
    $plan = wc_memberships_get_membership_plan($args['plan_id']);
    // Calculate membership end date based on membership length, optionally
    // from the existing end date, if renewing early
    $end_date = '';
    if ($plan->get_access_length_amount()) {
        // Early renewals add to the existing membership length, normal
        // cases calculate membership length from now
        $now = 'renew' == $action ? strtotime(get_post_meta($user_membership_id, '_end_date', true)) : 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);
    /**
     * Fires after a user has been granted membership access
     *
     * @since 1.3.0
     * @param WC_Memberships_Membership_Plan $membership_plan The plan that user was granted access to
     * @param array $args
     */
    do_action('wc_memberships_user_membership_created', $plan, array('user_id' => $args['user_id'], 'user_membership_id' => $user_membership->get_id()));
    return $user_membership;
}
 /**
  * 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;
 }
Exemplo n.º 12
0
/**
* Check if current page is restricted (works with BuddyPress who doesn't have any page/post id)
*
* @param string|int|array $plans Optional. The membership plan or plans to check against.
*                                Accepts a plan slug, ID, or an array of slugs or IDs. Default: all plans.
* @param string $delay
* @param bool $exclude_trial
*/
function kmpl_wc_memberships_has_access_to_restricted_page($plans = null, $delay = null, $exclude_trial = false)
{
    $has_access = false;
    $member_since = null;
    $access_time = null;
    // grant access to super users
    if (is_user_logged_in() && current_user_can('wc_memberships_access_all_restricted_content')) {
        $has_access = true;
    }
    // Convert to an array in all cases
    $plans = (array) $plans;
    // default to use all plans if no plan is specified
    if (empty($plans)) {
        $plans = wc_memberships_get_membership_plans();
    }
    foreach ($plans as $plan_id_or_slug) {
        $membership_plan = wc_memberships_get_membership_plan($plan_id_or_slug);
        if ($membership_plan && wc_memberships_is_user_active_member(get_current_user_id(), $membership_plan->get_id())) {
            $has_access = true;
            if (!$delay && !$exclude_trial) {
                break;
            }
            // Determine the earliest membership for the user
            $user_membership = wc_memberships()->user_memberships->get_user_membership(get_current_user_id(), $membership_plan->get_id());
            // Create a pseudo-rule to help applying filters
            $rule = new WC_Memberships_Membership_Plan_Rule(array('access_schedule_exclude_trial' => $exclude_trial ? 'yes' : 'no'));
            /** This filter is documented in includes/class-wc-memberships-capabilities.php **/
            $from_time = apply_filters('wc_memberships_access_from_time', $user_membership->get_start_date('timestamp'), $rule, $user_membership);
            // If there is no time to calculate the access time from, simply
            // use the current time as access start time
            if (!$from_time) {
                $from_time = current_time('timestamp', true);
            }
            if (is_null($member_since) || $from_time < $member_since) {
                $member_since = $from_time;
            }
        }
    }
    // Add delay
    if ($has_access && ($delay || $exclude_trial) && $member_since) {
        $access_time = $member_since;
        // Determine access time
        if (strpos($delay, 'month') !== false) {
            $parts = explode(' ', $delay);
            $amount = isset($parts[1]) ? (int) $parts[0] : '';
            $access_time = wc_memberships()->add_months($member_since, $amount);
        } else {
            if ($delay) {
                $access_time = strtotime($delay, $member_since);
            }
        }
        // Output or show delayed access message
        if ($access_time <= current_time('timestamp', true)) {
            $has_access = true;
        } else {
            $has_access = false;
            $message = __('This content is part of your membership, but not yet! You will gain access on {date}', 'woocommerce-memberships');
            // Apply the deprecated filter
            if (has_filter('get_content_delayed_message')) {
                /** This filter is documented in includes/frontend/class-wc-memberships-frontend.php **/
                $message = apply_filters('get_content_delayed_message', $message, null, $access_time);
                // Notify developers that this filter is deprecated
                _deprecated_function('The get_content_delayed_message filter', '1.3.1', 'wc_memberships_get_content_delayed_message');
            }
            /** This filter is documented in includes/frontend/class-wc-memberships-frontend.php **/
            $message = apply_filters('wc_memberships_get_content_delayed_message', $message, null, $access_time);
            $message = str_replace('{date}', date_i18n(wc_date_format(), $access_time), $message);
            $output = '<div class="wc-memberships-content-delayed-message">' . $message . '</div>';
            echo $output;
        }
    }
    return $has_access;
}