/** * Get membership plan rules * * General rules builder & getter. * * @since 1.0.0 * * @param string $rule_type Rule type. One of 'content_restriction', 'product_restriction' or 'purchasing_discount'. * @return array|bool $rules Array of rules or false on error */ private function get_rules($rule_type) { if (!isset($this->rules[$rule_type])) { $all_rules = get_option('wc_memberships_rules'); $this->rules[$rule_type] = array(); if (!empty($all_rules)) { foreach ($all_rules as $rule) { // Skip empty items if (empty($rule) || !is_array($rule)) { continue; } $rule = new WC_Memberships_Membership_Plan_Rule($rule); if ($rule_type == $rule->get_rule_type() && $rule->get_membership_plan_id() == $this->get_id()) { $this->rules[$rule_type][] = $rule; } } } } return $this->rules[$rule_type]; }
/** * Adjust user membership post scheduled content 'access from' time for subscription-based memberships * * @since 1.0.0 * @param string $from_time Access from time, as a timestamp * @param WC_Memberships_Membership_Plan_rule $rule Related rule * @param WC_Memberships_User_Membership $user_membership * @return string Modified from_time, as timestamp */ public function adjust_post_access_from_time($from_time, WC_Memberships_Membership_Plan_Rule $rule, WC_Memberships_User_Membership $user_membership) { if ('yes' == $rule->get_access_schedule_exclude_trial()) { $has_subscription = $this->has_user_membership_subscription($user_membership->get_id()); $trial_end_date = $this->get_user_membership_trial_end_date($user_membership->get_id(), 'timestamp'); if ($has_subscription && $trial_end_date) { $from_time = $trial_end_date; } } return $from_time; }
/** * Update rules for each provided rule type * * This method should be used by individual meta boxes that are updating rules * * @since 1.0.0 * @param int $post_id * @param array $rule_types Array of rule types to update * @param string $target Optional. Indicates the context we are updating rules in. One of 'plan' or 'post' */ public function update_rules($post_id, $rule_types, $target = 'plan') { $rules = get_option('wc_memberships_rules'); foreach ($rule_types as $rule_type) { $rule_type_post_key = '_' . $rule_type . '_rules'; if (!isset($_POST[$rule_type_post_key])) { continue; } // Save rule type $posted_rules = $_POST[$rule_type_post_key]; // Remove template rule if (isset($posted_rules['__INDEX__'])) { unset($posted_rules['__INDEX__']); } // Stop processing rule type if no rules left if (empty($posted_rules)) { continue; } // Pre-process rules before saving foreach ($posted_rules as $key => $rule) { // If not updating rules for a plan, but rather a single post, // do not process or update inherited rules or rules that apply to multiple objects if ('post' === $target && isset($rule['object_ids']) && is_array($rule['object_ids']) && isset($rule['object_ids'][0]) && $rule['object_ids'][0] != $post_id) { unset($posted_rules[$key]); continue; } // Make sure each rule has an ID if (!isset($rule['id']) || !$rule['id']) { $rule['id'] = uniqid('rule_'); } // Make sure each rule has the rule type set $rule['rule_type'] = $rule_type; // If updating rules for a single plan, set the plan ID // and content type fields on the rule if ('plan' == $target) { // Make sure each rule has correct membership plan ID $rule['membership_plan_id'] = $post_id; // Normalize content type: break content_type_key into parts $content_type_parts = explode('|', $rule['content_type_key']); $rule['content_type'] = $content_type_parts[0]; $rule['content_type_name'] = $content_type_parts[1]; unset($rule['content_type_key']); // Normalize object IDs if (isset($rule['object_ids']) && $rule['object_ids'] && !is_array($rule['object_ids'])) { $rule['object_ids'] = explode(',', $rule['object_ids']); } } else { // Ensure that the correct object ID is set if (!isset($rule['object_ids']) || empty($rule['object_ids'])) { $rule['object_ids'] = array($post_id); } // Ensure correct content type & name is set $rule['content_type'] = 'post_type'; $rule['content_type_name'] = get_post_type($post_id); } // Content restriction & product restricion: if (in_array($rule_type, array('content_restriction', 'product_restriction'))) { // Make sure access_schedule_exclude_trial is set, even if it's a no if (!isset($rule['access_schedule_exclude_trial'])) { $rule['access_schedule_exclude_trial'] = 'no'; } // If no access schedule is set, set it to immediate by default if (!isset($rule['access_schedule'])) { $rule['access_schedule'] = 'immediate'; } // Normalize access schedule if ('specific' == $rule['access_schedule']) { if (!$rule['access_schedule_amount']) { $rule['access_schedule'] = 'immediate'; } else { // Create textual (human-readable) representation of the access schedule $rule['access_schedule'] = sprintf('%d %s', $rule['access_schedule_amount'], $rule['access_schedule_period']); } } unset($rule['access_schedule_amount']); unset($rule['access_schedule_period']); } else { if ('purchasing_discount' == $rule_type) { // Make sure active is set, even if it's a no $rule['active'] = isset($rule['active']) && $rule['active'] ? 'yes' : 'no'; } } // Update rule properties $posted_rules[$key] = $rule; } // end pre-processing rules // Process posted rules foreach ($posted_rules as $key => $posted) { $existing_rule_key = wc_memberships()->array_search_key_value($rules, 'id', $posted['id']); // This is an existing rule if (is_numeric($existing_rule_key)) { $rule = new WC_Memberships_Membership_Plan_Rule($rules[$existing_rule_key]); // Check capabilities if ($rule->content_type_exists() && !$rule->current_user_can_edit()) { continue; } // Check if current context allows editing if (!$rule->current_context_allows_editing()) { continue; } if (isset($posted['remove']) && $posted['remove']) { unset($rules[$existing_rule_key]); continue; } // Remove unnecessary keys unset($posted['remove']); // Update existing rule $rules[$existing_rule_key] = $posted; } else { // Remove unnecessary keys unset($posted['remove']); // Check capabilities switch ($posted['content_type']) { case 'post_type': $post_type = get_post_type_object($posted['content_type_name']); // Skip if user has no capabilities to edit the associated post type if (!(current_user_can($post_type->cap->edit_posts) && current_user_can($post_type->cap->edit_others_posts))) { continue; } break; case 'taxonomy': $taxonomy = get_taxonomy($posted['content_type_name']); // Skip if user has no capabilities to edit the associated taxonomy if (!(current_user_can($taxonomy->cap->manage_terms) && current_user_can($taxonomy->cap->edit_terms))) { continue; } break; } $rules[] = $posted; } } } update_option('wc_memberships_rules', !empty($rules) ? array_values($rules) : array()); }