/** * Initialize the rule object. * * @since 4.6 */ protected function init() { global $wpdb; $this->filename = basename(__FILE__); // 'pc_subscription' rule. $this->add_rule('pc_subscription', __('For Members (Membership 2)', PO_LANG), __('Only shows the PopUp if the user has subscribed to a certain Membership (Membership2 plugin).', PO_LANG), 'pc_unsubscription', 25); // 'pc_unsubscription' rule. $this->add_rule('pc_unsubscription', __('For Non-Members (Membership 2)', PO_LANG), __('Only shows the PopUp if the user has not yet subscribed to a certain Membership (Membership2 plugin).', PO_LANG), 'pc_subscription', 25); // -- Initialize rule. /** * Note we're not using the M2 API yet, because it was introduced only * a few releases back and some people that use older version of M2/PC * will have problems if we do. * * @todo replace with official API function anytime in 2016 * * $this->is_active = false; * if ( apply_filters( 'ms_active', false ) ) { * $this->is_active = true; * $this->memberships = MS_Plugin::$api->list_memberships( true ); * } * */ $this->is_active = class_exists('MS_Plugin'); if (!$this->is_active) { return; } $args = array('include_base' => false, 'include_guest' => true); $list = MS_Model_Membership::get_memberships($args); $this->memberships = $list; }
/** * Constructor. * * @since 1.0.0 */ public function __construct() { parent::__construct(array('singular' => 'member', 'plural' => 'members', 'ajax' => false)); add_action('ms_helper_listtable_searchbox_start', array($this, 'searchbox_filters')); $memberships = MS_Model_Membership::get_memberships(array('include_guest' => 0)); self::$memberships = array(); foreach ($memberships as $item) { self::$memberships[$item->id] = (object) array('label' => $item->name, 'attr' => sprintf('data-color="%1$s"', $item->get_color())); } }
/** * Prepares fields for the edit form. * * @since 1.0.1.0 * @return array */ protected function get_fields() { $args = array('include_guest' => false); $memberships = MS_Model_Membership::get_memberships($args); $membership = $this->data['membership']; $action = MS_Controller_Membership::AJAX_ACTION_UPDATE_MEMBERSHIP; $nonce = wp_create_nonce($action); $fields = array(); /* * The value of "allow_val" is negated, because the radio-slider is * reversed. So allow_val == false means that upgrading is allowed. * * This is just a UI tweak, the function ->update_allowed() returns true * when upgrading is allowed. */ $list = array(); $list['guest'] = array('allow' => __('Users without Membership can subscribe', 'membership2'), 'allow_val' => !$membership->update_allowed('guest')); foreach ($memberships as $item) { if ($item->id == $membership->id) { continue; } $list[$item->id] = array('allow' => sprintf(__('Members of %s can subscribe', 'membership2'), $item->get_name_tag()), 'allow_val' => !$membership->update_allowed($item->id)); if (MS_Model_Addon::is_enabled(MS_Model_Addon::ADDON_MULTI_MEMBERSHIPS)) { $list[$item->id]['replace'] = sprintf(__('Cancel %s on subscription', 'membership2'), $item->get_name_tag()); $list[$item->id]['replace_val'] = $membership->update_replaces($item->id); } } foreach ($list as $id => $data) { $fields[] = array('id' => 'deny_update[' . $id . ']', 'type' => MS_Helper_Html::INPUT_TYPE_RADIO_SLIDER, 'title' => $data['allow'], 'value' => $data['allow_val'], 'before' => __('Allow', 'membership2'), 'after' => __('Deny', 'membership2'), 'class' => 'reverse', 'wrapper_class' => 'ms-block inline-label ms-allow', 'ajax_data' => array(1)); if (!empty($data['replace'])) { if (MS_Addon_Prorate::is_active()) { $after_label = __('Cancel and Pro-Rate', 'membership2'); } else { $after_label = __('Cancel', 'membership2'); } $fields[] = array('id' => 'replace_update[' . $id . ']', 'type' => MS_Helper_Html::INPUT_TYPE_RADIO_SLIDER, 'title' => $data['replace'], 'value' => $data['replace_val'], 'before' => __('Keep', 'membership2'), 'after' => $after_label, 'class' => 'reverse', 'wrapper_class' => 'ms-block inline-label ms-update-replace', 'ajax_data' => array(1)); } $fields[] = array('type' => MS_Helper_Html::TYPE_HTML_SEPARATOR); } foreach ($fields as $key => $field) { if (!empty($field['ajax_data'])) { if (!empty($field['ajax_data']['action'])) { continue; } if (!isset($fields[$key]['ajax_data']['field'])) { $fields[$key]['ajax_data']['field'] = $fields[$key]['id']; } $fields[$key]['ajax_data']['_wpnonce'] = $nonce; $fields[$key]['ajax_data']['action'] = $action; $fields[$key]['ajax_data']['membership_id'] = $membership->id; } } return $fields; }
public function prepare_items() { $this->_column_headers = array($this->get_columns(), $this->get_hidden_columns(), $this->get_sortable_columns()); $args = array(); if (!empty($_REQUEST['orderby']) && !empty($_REQUEST['order'])) { $args['orderby'] = $_REQUEST['orderby']; $args['order'] = $_REQUEST['order']; } // Prepare order by statement. if (!empty($args['orderby']) && property_exists('MS_Model_Membership', $args['orderby'])) { $args['meta_key'] = $args['orderby']; $args['orderby'] = 'meta_value'; } $this->items = apply_filters('membership_helper_listtable_membership_items', MS_Model_Membership::get_memberships($args)); }
/** * Initialize the list table * * @since 1.0.0 * @param MS_Rule $model Rule-Model */ public function __construct($model) { parent::__construct(array('singular' => 'rule_' . $this->id, 'plural' => 'rules_' . $this->id, 'ajax' => false)); $this->name['singular'] = __('Item', 'membership2'); $this->name['plural'] = __('Items', 'membership2'); $this->name['default_access'] = __('Everyone', 'membership2'); $this->model = $model; $this->membership = MS_Model_Membership::get_base(); $memberships = MS_Model_Membership::get_memberships(); self::$memberships = array(); foreach ($memberships as $item) { self::$memberships[$item->id] = (object) array('label' => $item->name, 'attr' => sprintf('data-color="%1$s"', $item->get_color())); } // Add code right before the bulk actions are displayed. add_action('ms_listtable_before_bulk_actions', array($this, 'add_rule_type')); }
/** * Checks if the current user is allowed to subscribe to the specified * membership. * * @since 1.0.1.0 * @api * @param int $membership_id A membership_id. * @return bool Whether subscription is allowed or not. */ public function can_subscribe_to($membership_id) { static $Access_Flags = null; if (null === $Access_Flags) { $Access_Flags = array(); $active_memberships = $this->get_active_memberships(); $all_memberships = MS_Model_Membership::get_memberships(); /** * Controls how to handle conflicts in upgrade path settings when a * member has multiple memberships. * * Default is true: * If one membership forbids the upgrade, then that's it. * * Custom set to false: * If one membership allows the upgrade, then allow it. * * @since 1.0.1.0 * @var bool */ $prefer_forbidden = apply_filters('ms_model_member_can_subscribe_to_prefer_forbidden', true); foreach ($active_memberships as $membership) { $base_id = $membership->id; if ($membership->is_guest() || $membership->is_user()) { $base_id = 'guest'; } foreach ($all_memberships as $ms) { if (isset($active_memberships[$ms->id])) { continue; } $is_allowed = $ms->update_allowed($base_id); if (!isset($Access_Flags[$ms->id])) { $Access_Flags[$ms->id] = $is_allowed; } else { if ($prefer_forbidden && !$is_allowed) { $Access_Flags[$ms->id] = $is_allowed; } elseif (!$prefer_forbidden && $is_allowed) { $Access_Flags[$ms->id] = $is_allowed; } } } } } $result = true; if (isset($Access_Flags[$membership_id])) { $result = $Access_Flags[$membership_id]; } return apply_filters('ms_model_member_can_subscribe_to', $result, $membership_id); }
/** * Upgrade from 1.0.2.x version to 1.0.2.4 version. */ private static function _upgrade_1_0_2_4() { lib3()->updates->clear(); $memberships = MS_Model_Membership::get_memberships(); foreach ($memberships as $item) { $source_id = $membership->source_id; if (empty($source_id)) { continue; } $data = lib3()->array->get($membership->get_custom_data('matching')); if (!isset($data['m1'])) { $data['m1'] = array(); } $data['m1'] = lib3()->array->get($data['m1']); $data['m1'][] = $source_id; $membership->set_custom_data('matching', $data); $membership->save(); } }
/** * Input fields displayed in the "Edit Member" screen. * * @since 1.0.1.0 * @return array */ public function prepare_fields_edit() { $action_update = MS_Controller_Member::ACTION_UPDATE_MEMBER; $action_modify = MS_Controller_Member::ACTION_MODIFY_SUBSCRIPTIONS; $user_id = $this->data['user_id']; $user = MS_Factory::load('MS_Model_Member', $user_id); $unused_memberships = array(); $temp_memberships = MS_Model_Membership::get_memberships(array('include_guest' => 0)); foreach ($temp_memberships as $membership) { $unused_memberships[$membership->id] = $membership; } $fields = array(); $fields['editor'] = array('title' => array('type' => MS_Helper_Html::TYPE_HTML_TEXT, 'class' => 'group-title', 'value' => __('Basic Profile details', MS_TEXT_DOMAIN)), 'username' => array('id' => 'username', 'type' => MS_Helper_Html::INPUT_TYPE_TEXT, 'title' => __('Username', MS_TEXT_DOMAIN), 'value' => $user->username, 'class' => 'ms-text-medium', 'config' => array('disabled' => 'disabled')), 'email' => array('id' => 'email', 'type' => MS_Helper_Html::INPUT_TYPE_TEXT, 'title' => __('Email', MS_TEXT_DOMAIN), 'value' => $user->email, 'class' => 'ms-text-medium'), 'first_name' => array('id' => 'first_name', 'type' => MS_Helper_Html::INPUT_TYPE_TEXT, 'title' => __('First Name', MS_TEXT_DOMAIN), 'value' => $user->first_name, 'class' => 'ms-text-medium'), 'last_name' => array('id' => 'last_name', 'type' => MS_Helper_Html::INPUT_TYPE_TEXT, 'title' => __('Last Name', MS_TEXT_DOMAIN), 'value' => $user->last_name, 'class' => 'ms-text-medium'), 'displayname' => array('id' => 'displayname', 'type' => MS_Helper_Html::INPUT_TYPE_TEXT, 'title' => __('Display Name', MS_TEXT_DOMAIN), 'value' => $user->get_user()->display_name, 'class' => 'ms-text-medium'), 'sep' => array('type' => MS_Helper_Html::TYPE_HTML_SEPARATOR), 'user_id' => array('id' => 'user_id', 'type' => MS_Helper_Html::INPUT_TYPE_HIDDEN, 'value' => $user->id), 'button' => array('id' => 'btn_save', 'type' => MS_Helper_Html::INPUT_TYPE_SUBMIT, 'value' => __('Save', MS_TEXT_DOMAIN)), 'profile' => array('id' => 'user_profile', 'type' => MS_Helper_Html::TYPE_HTML_LINK, 'value' => __('Full User Profile', MS_TEXT_DOMAIN) . ' »', 'url' => admin_url('user-edit.php?user_id=' . $user->id), 'class' => 'button wpmui-field-input'), 'action' => array('id' => 'action', 'type' => MS_Helper_Html::INPUT_TYPE_HIDDEN, 'value' => $action_update), '_wpnonce' => array('id' => '_wpnonce', 'type' => MS_Helper_Html::INPUT_TYPE_HIDDEN, 'value' => wp_create_nonce($action_update))); $fields['subscriptions'] = array(); // Section: Edit existing subscriptions. $fields['subscriptions'][] = array('type' => MS_Helper_Html::TYPE_HTML_TEXT, 'class' => 'group-title', 'value' => __('Manage Subscriptions', MS_TEXT_DOMAIN)); if ($user->subscriptions) { $gateways = MS_Model_Gateway::get_gateway_names(false, true); foreach ($user->subscriptions as $subscription) { if (MS_Model_Relationship::STATUS_DEACTIVATED == $subscription->status) { continue; } $the_membership = $subscription->get_membership(); unset($unused_memberships[$the_membership->id]); $status_options = array(MS_Model_Relationship::STATUS_PENDING => __('Pending (activate on next payment)', MS_TEXT_DOMAIN), MS_Model_Relationship::STATUS_WAITING => __('Waiting (activate on start date)', MS_TEXT_DOMAIN), MS_Model_Relationship::STATUS_TRIAL => __('Trial Active', MS_TEXT_DOMAIN), MS_Model_Relationship::STATUS_ACTIVE => __('Active', MS_TEXT_DOMAIN), MS_Model_Relationship::STATUS_CANCELED => __('Cancelled (deactivate on expire date)', MS_TEXT_DOMAIN), MS_Model_Relationship::STATUS_TRIAL_EXPIRED => __('Trial Expired (activate on next payment)', MS_TEXT_DOMAIN), MS_Model_Relationship::STATUS_EXPIRED => __('Expired (no access) ', MS_TEXT_DOMAIN), MS_Model_Relationship::STATUS_DEACTIVATED => __('Deactivated (no access)', MS_TEXT_DOMAIN)); if (!$the_membership->has_trial()) { unset($status_options[MS_Model_Relationship::STATUS_TRIAL]); unset($status_options[MS_Model_Relationship::STATUS_TRIAL_EXPIRED]); } if (isset($gateways[$subscription->gateway_id])) { $gateway_name = $gateways[$subscription->gateway_id]; } elseif (empty($subscription->gateway_id)) { $gateway_name = __('- No Gateway -', MS_TEXT_DOMAIN); } else { $gateway_name = '(' . $subscription->gateway_id . ')'; } $field_start = array('name' => 'mem_' . $the_membership->id . '[start]', 'type' => MS_Helper_Html::INPUT_TYPE_DATEPICKER, 'value' => $subscription->start_date); $field_expire = array('name' => 'mem_' . $the_membership->id . '[expire]', 'type' => MS_Helper_Html::INPUT_TYPE_DATEPICKER, 'value' => $subscription->expire_date); $field_status = array('name' => 'mem_' . $the_membership->id . '[status]', 'type' => MS_Helper_Html::INPUT_TYPE_SELECT, 'value' => $subscription->status, 'field_options' => $status_options); $fields['subscriptions'][] = array('name' => 'memberships[]', 'type' => MS_Helper_Html::INPUT_TYPE_HIDDEN, 'value' => $the_membership->id); $fields['subscriptions'][] = array('title' => $the_membership->get_name_tag(), 'type' => MS_Helper_Html::TYPE_HTML_TABLE, 'value' => array(array(__('Subscription ID', MS_TEXT_DOMAIN), $subscription->id), array(__('Payment Gateway', MS_TEXT_DOMAIN), $gateway_name), array(__('Payment Type', MS_TEXT_DOMAIN), $subscription->get_payment_description(null, true)), array(__('Start Date', MS_TEXT_DOMAIN) . ' <sup>*)</sup>', MS_Helper_Html::html_element($field_start, true)), array(__('Expire Date', MS_TEXT_DOMAIN) . ' <sup>*)</sup>', MS_Helper_Html::html_element($field_expire, true)), array(__('Status', MS_TEXT_DOMAIN) . ' <sup>*)</sup>', MS_Helper_Html::html_element($field_status, true))), 'field_options' => array('head_col' => true)); } } else { $fields['subscriptions'][] = array('type' => MS_Helper_Html::TYPE_HTML_TEXT, 'value' => __('This user does not have any subscriptions yet.', MS_TEXT_DOMAIN)); } // Section: Add new subscription. if (count($unused_memberships)) { $options = array(); if (MS_Model_Addon::is_enabled(MS_Model_Addon::ADDON_MULTI_MEMBERSHIPS)) { $field_type = MS_Helper_Html::INPUT_TYPE_CHECKBOX; $group_title = __('Add Subscriptions', MS_TEXT_DOMAIN); } else { $field_type = MS_Helper_Html::INPUT_TYPE_RADIO; $group_title = __('Set Subscription', MS_TEXT_DOMAIN); } $fields['subscriptions'][] = array('type' => MS_Helper_Html::TYPE_HTML_SEPARATOR); $fields['subscriptions'][] = array('type' => MS_Helper_Html::TYPE_HTML_TEXT, 'class' => 'group-title', 'value' => $group_title); foreach ($unused_memberships as $the_membership) { $options[$the_membership->id] = $the_membership->get_name_tag(); } $fields['subscriptions'][] = array('id' => 'subscribe', 'type' => $field_type, 'field_options' => $options); $fields['subscriptions'][] = array('id' => 'user_id', 'type' => MS_Helper_Html::INPUT_TYPE_HIDDEN, 'value' => $user->id); } if ($user->subscriptions) { $fields['subscriptions'][] = array('type' => MS_Helper_Html::TYPE_HTML_SEPARATOR); $fields['subscriptions'][] = array('type' => MS_Helper_Html::TYPE_HTML_TEXT, 'value' => '<sup>*)</sup> ' . __('Subscription Dates and Status are validated when saved and might result in a different value then the one specified above.', MS_TEXT_DOMAIN), 'class' => 'info-field'); } $fields['subscriptions'][] = array('id' => 'btn_modify', 'type' => MS_Helper_Html::INPUT_TYPE_SUBMIT, 'value' => __('Save Changes', MS_TEXT_DOMAIN)); $fields['subscriptions'][] = array('id' => 'history', 'type' => MS_Helper_Html::TYPE_HTML_LINK, 'value' => '<i class="dashicons dashicons-id"></i>' . __('History and logs', MS_TEXT_DOMAIN), 'url' => '#history', 'class' => 'button wpmui-field-input', 'config' => array('data-ms-dialog' => 'View_Member_Dialog', 'data-ms-data' => array('member_id' => $user->id))); $fields['subscriptions'][] = array('id' => 'action', 'type' => MS_Helper_Html::INPUT_TYPE_HIDDEN, 'value' => $action_modify); $fields['subscriptions'][] = array('id' => '_wpnonce', 'type' => MS_Helper_Html::INPUT_TYPE_HIDDEN, 'value' => wp_create_nonce($action_modify)); return apply_filters('ms_view_member_editor_fields_edit', $fields); }
/** * Toggle membership access. * * @since 1.0.0 * * @param int $post_id The post id or attachment id to save access to. * @param string $rule_type The membership rule type. * @param array $membership_id The membership id to toggle access */ public function toggle_membership_access($post_id, $rule_type, $membership_id) { if ($this->is_admin_user()) { $membership = MS_Factory::load('MS_Model_Membership', $membership_id); $rule = $membership->get_rule($rule_type); $protected = !$rule->get_rule_value($post_id); if ($membership->is_base()) { /* * If we just modified the protection for the whole post then we * have to update every single membership with the new rule * value before changing the base rule itself. */ $all_memberships = MS_Model_Membership::get_memberships(); foreach ($all_memberships as $the_membership) { if ($the_membership->is_base) { continue; } $the_rule = $the_membership->get_rule($rule_type); if ($protected) { $the_rule->give_access($post_id); } else { $the_rule->remove_access($post_id); } $the_membership->set_rule($rule_type, $the_rule); $the_membership->save(); } } if ($rule) { if ($protected) { $rule->give_access($post_id); } else { $rule->remove_access($post_id); } $membership->set_rule($rule_type, $rule); $membership->save(); } } do_action('ms_controller_membership_metabox_toggle_membership_access', $post_id, $rule_type, $membership_id, $this); }
/** * Display custom text after the view-links are rendered. * * @since 1.0.1.2 */ public function views() { parent::views(); if (!$this->matching_type || !$this->matching_type_id) { if (!MS_Model_Import::can_match()) { $url = MS_Controller_Plugin::get_admin_url('billing', array('show' => 'logs')); echo '<p>'; _e('No suitable transaction found.', 'membership2'); echo '</p><p>'; printf('<strong>%s</strong><br />', __('Nothing to do right now:', 'membership2')); _e('Transactions that can be automatically matched will appear here when they are processed by a payment gateway.<br>So simply check again later after new payments were made.', 'membership2'); echo '</p><p>'; printf(__('If you are impatient then "Retry" some error-state transactions in the %sTransaction Logs%s section and then see if they appear on this page.', 'membership2'), '<a href="' . $url . '">', '</a>'); echo '</p>'; } // Don't display anything if no matching source was selected. return; } if (!MS_Model_Import::can_match($this->matching_type_id, $this->matching_type)) { // For this transaction details is no matching possible right now. return; } $settings = MS_Factory::load('MS_Model_Settings'); $label = $this->get_source_label($this->matching_type, $this->matching_type_id); $memberships = MS_Model_Membership::get_memberships(); $options = array('0' => '-----'); foreach ($memberships as $item) { if ($item->is_system()) { continue; } if ($item->is_free()) { $options[$item->id] = sprintf('%s • %s', $item->name, __('Free', 'membership2')); } else { $options[$item->id] = sprintf('%s • %s • %s', $item->name, $settings->currency . ' ' . MS_Helper_Billing::format_price($item->price), $item->get_payment_type_desc()); } } asort($options); $field_memberships = array('id' => 'match_with', 'type' => MS_Helper_Html::INPUT_TYPE_SELECT, 'before' => sprintf(__('2. Link %s with', 'membership2'), '<b>' . $label . '</b>'), 'field_options' => $options); $field_action = array('id' => 'action', 'type' => MS_Helper_Html::INPUT_TYPE_HIDDEN, 'value' => MS_Controller_Import::AJAX_ACTION_MATCH); $field_source = array('id' => 'source', 'type' => MS_Helper_Html::INPUT_TYPE_HIDDEN, 'value' => $this->matching_type); $field_source_id = array('id' => 'source_id', 'type' => MS_Helper_Html::INPUT_TYPE_HIDDEN, 'value' => $this->matching_type_id); $field_save = array('class' => 'action-match', 'type' => MS_Helper_Html::INPUT_TYPE_SUBMIT, 'value' => __('Save', 'membership2')); $field_retry_action = array('class' => 'retry_action', 'type' => MS_Helper_Html::INPUT_TYPE_HIDDEN, 'value' => MS_Controller_Import::AJAX_ACTION_RETRY); $field_retry_nonce = array('class' => 'retry_nonce', 'type' => MS_Helper_Html::INPUT_TYPE_HIDDEN, 'value' => wp_create_nonce(MS_Controller_Import::AJAX_ACTION_RETRY)); ?> <div class="cf"></div> <form class="transaction-matching"> <?php wp_nonce_field(MS_Controller_Import::AJAX_ACTION_MATCH); MS_Helper_Html::html_element($field_retry_action); MS_Helper_Html::html_element($field_retry_nonce); MS_Helper_Html::html_element($field_action); MS_Helper_Html::html_element($field_source); MS_Helper_Html::html_element($field_source_id); ?> <div class="content"> <p><?php printf(__('1. Below is a list of possible "%s" transactions. Examine these transactions to find out which Membership they refer to.', 'membership2'), '<b>' . $label . '</b>'); ?> </p> <hr /> <p><?php MS_Helper_Html::html_element($field_memberships); ?> </p> <div style="margin-left:14px"> <?php _e('Notes:', 'membership2'); ?> <br /> <?php _e('This choice is saved so new transactions are processed automatically from now on.', 'membership2'); ?> <br /> <?php _e('Upon saving all transactions below will be processed, this might take a while.', 'membership2'); ?> </div> </div> <div class="buttons"> <?php MS_Helper_Html::html_element($field_save); ?> </div> </form> <?php }
/** * Returns an array with access-information on the current page/user * * @since 1.0.0 * * @return array { * Access information * * @type bool $has_access If the current user can view the current page. * @type array $memberships List of active membership-IDs the user has * registered to. * } */ public function get_access_info() { static $Info = null; if (null === $Info) { $Info = array('has_access' => null, 'is_admin' => false, 'memberships' => array(), 'url' => MS_Helper_Utility::get_current_url()); // The ID of the main system membership. $base_id = MS_Model_Membership::get_base()->id; $simulation = $this->member->is_simulated_user() || isset($_GET['explain']) && 'access' == $_GET['explain']; if ($simulation) { $Info['reason'] = array(); } if ($this->member->is_normal_admin()) { // Admins have access to ALL memberships. $Info['is_admin'] = true; $Info['has_access'] = true; if ($simulation) { $Info['reason'][] = __('Allow: Admin-User always has access', MS_TEXT_DOMAIN); } $memberships = MS_Model_Membership::get_memberships(); foreach ($memberships as $membership) { $Info['memberships'][] = $membership->id; } } else { /* * A non-admin visitor is only guaranteed access to special * Membership2 pages: * Registration, Login, etc. */ $ms_page = MS_Model_Pages::current_page(); if ($ms_page) { $Info['has_access'] = true; if ($simulation) { $Info['reason'][] = __('Allow: This is a Membership Page', MS_TEXT_DOMAIN); } } // Build a list of memberships the user belongs to and check permission. foreach ($this->member->subscriptions as $subscription) { // Verify status of the membership. // Only active, trial or canceled (until it expires) status memberships. if (!$this->member->has_membership($subscription->membership_id)) { if ($simulation) { $Info['reason'][] = sprintf(__('Skipped: Not a member of "%s"', MS_TEXT_DOMAIN), $subscription->get_membership()->name); } continue; } if ($base_id !== $subscription->membership_id) { $Info['memberships'][] = $subscription->membership_id; } // If permission is not clear yet then check current membership... if (true !== $Info['has_access']) { $membership = $subscription->get_membership(); $access = $membership->has_access_to_current_page(); if (null === $access) { if ($simulation) { $Info['reason'][] = sprintf(__('Ignored: Membership "%s"', MS_TEXT_DOMAIN), $membership->name); $Info['reason'][] = $membership->_access_reason; } continue; } if ($simulation) { $Info['reason'][] = sprintf(__('%s: Membership "%s"', MS_TEXT_DOMAIN), $access ? __('Allow', MS_TEXT_DOMAIN) : __('Deny', MS_TEXT_DOMAIN), $membership->name); $Info['deciding_membership'] = $membership->id; if ($access) { $Info['deciding_rule'] = $membership->_allow_rule; } else { $Info['deciding_rule'] = $membership->_deny_rule; } $Info['reason'][] = $membership->_access_reason; } $Info['has_access'] = $access; } } if (null === $Info['has_access']) { $Info['has_access'] = true; if ($simulation) { $Info['reason'][] = __('Allow: Page is not protected', MS_TEXT_DOMAIN); } } // "membership-id: 0" means: User does not belong to any membership. if (!count($Info['memberships'])) { $Info['memberships'][] = 0; } } $Info = apply_filters('ms_model_plugin_get_access_info', $Info); if ($simulation) { $access = lib2()->session->get_clear('ms-access'); lib2()->session->add('ms-access', $Info); for ($i = 0; $i < 9; $i += 1) { if (isset($access[$i])) { lib2()->session->add('ms-access', $access[$i]); } } if (WP_DEBUG && isset($_GET['explain']) && 'access' == $_GET['explain']) { echo '<style>code{background:#EEE;background:rgba(0,0,0,0.1);padding:1px 4px;}</style>'; echo '<h3>Note</h3>'; echo '<p>To disable the URL param <code>?explain=access</code> you have to set <code>WP_DEBUG</code> to false.</p>'; echo '<hr><h3>Recent Access checks</h3>'; lib2()->debug->stacktrace_off(); foreach ($access as $item) { printf('<a href="%1$s">%1$s</a>: <strong>%2$s</strong>', $item['url'], $item['has_access'] ? __('Allow', MS_TEXT_DOMAIN) : __('Deny', MS_TEXT_DOMAIN)); // Intended debug output, leave it here. lib2()->debug->dump($item); } wp_die(''); } } } return $Info; }
/** * Checks all Memberships and creates/updates the payment plan on stripe if * the membership changed since the plan was last changed. * * This function is called when the gateway is activated and after a * membership was saved to database. * * @since 1.0.0 */ public function update_stripe_data() { if (!$this->active) { return false; } $this->_api->set_gateway($this); // 1. Update all playment plans. $memberships = MS_Model_Membership::get_memberships(); foreach ($memberships as $membership) { $this->update_stripe_data_membership($membership); } // 2. Update all coupons (if Add-on is enabled) if (MS_Addon_Coupon::is_active()) { $coupons = MS_Addon_Coupon_Model::get_coupons(); foreach ($coupons as $coupon) { $this->update_stripe_data_coupon($coupon); } } }
/** * Prepare html fields. * * @since 1.0.0 * * @return array */ public function prepare_fields() { // The ID of the main system membership. $base_id = MS_Model_Membership::get_base()->id; $sorted_memberships = array(); $memberships = MS_Model_Membership::get_memberships(array('include_base' => 1)); foreach ($memberships as $membership) { if ($base_id == $membership->id) { $label = __('- No membership / Visitor -', MS_TEXT_DOMAIN); } else { $label = $membership->name; if (!$membership->active) { $label .= ' ' . __('(Inactive)', MS_TEXT_DOMAIN); } } $sorted_memberships[$membership->id] = $label; } asort($sorted_memberships); $fields = array('exit_button' => array('type' => MS_Helper_Html::TYPE_HTML_LINK, 'value' => __('Exit Test Mode', MS_TEXT_DOMAIN), 'url' => MS_Controller_Adminbar::get_simulation_exit_url(), 'class' => 'button'), 'action_field' => array('name' => 'action', 'value' => 'ms_simulate', 'type' => MS_Helper_Html::INPUT_TYPE_HIDDEN), 'membership_id' => array('id' => 'ab-membership-id', 'name' => 'membership_id', 'value' => $this->data['membership_id'], 'type' => MS_Helper_Html::INPUT_TYPE_SELECT, 'field_options' => $sorted_memberships), 'nonce_field' => array('id' => '_wpnonce', 'value' => wp_create_nonce('ms_simulate'), 'type' => MS_Helper_Html::INPUT_TYPE_HIDDEN), 'simulate_date' => array('id' => 'simulate_date', 'type' => MS_Helper_Html::INPUT_TYPE_DATEPICKER, 'value' => $this->data['simulate_date'], 'class' => 'ms-admin-bar-date ms-date'), 'simulate_submit' => array('id' => 'simulate_submit', 'type' => MS_Helper_Html::INPUT_TYPE_SUBMIT, 'value' => __('Go', MS_TEXT_DOMAIN), 'class' => 'ms-admin-bar-submit')); return apply_filters('ms_view_admin_bar_prepare_fields', $fields, $this); }
/** * Manages membership actions. * * Verifies GET and POST requests to manage members * * @since 1.0.0 */ public function members_admin_page_process_list() { $msg = 0; $redirect = false; if ($this->is_admin_user()) { $fields_new = array('new_member', 'action'); $fields_edit = array('member_id', 'action'); // Execute list table single action. if ($this->verify_nonce(null, 'GET') && self::validate_required($fields_edit, 'GET')) { $msg = $this->member_list_do_action($_GET['action'], array($_GET['member_id'])); $redirect = esc_url_raw(add_query_arg(array('msg' => $msg), remove_query_arg(array('member_id', 'action', '_wpnonce')))); } elseif ($this->verify_nonce('bulk')) { lib2()->array->equip_post('action', 'action2', 'member_id'); $action = $_POST['action']; if (empty($action) || $action == '-1') { $action = $_POST['action2']; } $members = $_POST['member_id']; /* * The Bulk-Edit action is built like 'cmd-id' * e.g. 'add-123' will add membership 123 to the selected items. */ if (empty($action)) { $cmd = array(); } elseif (empty($members)) { $cmd = array(); } elseif ('-1' == $action) { $cmd = array(); } else { $cmd = explode('-', $action); } if (2 == count($cmd)) { $action = $cmd[0]; $action_id = $cmd[1]; // Get a list of specified memberships... if (is_numeric($action_id)) { // ... either a single membership. $memberships = array(MS_Factory::load('MS_Model_Membership', $action_id)); } elseif ('all' == $action_id) { // ... or all memberships. $memberships = MS_Model_Membership::get_memberships(); } // Loop defined memberships and add/remove members. foreach ($memberships as $membership) { $msg = $this->member_list_do_action($action, $members, $membership->id); } $redirect = esc_url_raw(add_query_arg(array('msg' => $msg))); } } elseif (isset($_POST['submit']) && $this->verify_nonce() && self::validate_required($fields_edit, 'POST')) { if (is_array($_POST['member_id'])) { $member_ids = $_POST['member_id']; } else { $member_ids = explode(',', $_POST['member_id']); } $msg = $this->member_list_do_action($_POST['action'], $member_ids, $_POST['membership_id']); $redirect = esc_url_raw(add_query_arg(array('msg' => $msg))); } } if ($redirect) { wp_safe_redirect($redirect); exit; } }
/** * Find a M2 membership by a custom matching ID. * * The matching key and matching ID are stored in the memberships custom * data array. * * See MS_Helper_Listtable_TransactionMatching for a list of matching_keys. * * @since 1.0.1.2 * @param int $matching_key The matching key. * @param int $matching_id The matching ID. * @return MS_Model_Membership|null The M2 membership. */ public static function membership_by_matching($matching_key, $matching_id) { $res = null; $args = array('include_guest' => 0); $memberships = MS_Model_Membership::get_memberships($args); foreach ($memberships as $membership) { $data = $membership->get_custom_data('matching'); if (empty($data) || !is_array($data)) { continue; } if (!isset($data[$matching_key])) { continue; } $ids = lib3()->array->get($data[$matching_key]); foreach ($ids as $id) { if ($matching_id == $id) { $res = $membership; break 2; } } } return $res; }
/** * Process membership pages requests * * Verifies GET and POST requests to manage memberships. * Redirect to next step after processing. * * @since 1.0.0 */ public function admin_page_process() { $membership = $this->load_membership(); do_action('ms_controller_protection_admin_page_process', $this->get_active_tab()); // Only accessible to admin users if (!$this->is_admin_user()) { return false; } if ($this->verify_nonce('bulk')) { // Bulk-edit lib2()->array->equip_post('action', 'action2', 'item', 'rule_type'); $action = $_POST['action']; if (empty($action) || $action == '-1') { $action = $_POST['action2']; } $items = $_POST['item']; $rule_type = $_POST['rule_type']; /* * The Bulk-Edit action is built like 'cmd-id' * e.g. 'add-123' will add membership 123 to the selected items. */ if (empty($action)) { $cmd = array(); } elseif (empty($items)) { $cmd = array(); } elseif (empty($rule_type)) { $cmd = array(); } elseif ('-1' == $action) { $cmd = array(); } else { $cmd = explode('-', $action); } if (2 == count($cmd)) { $action = $cmd[0]; $action_id = $cmd[1]; // Get a list of specified memberships... if (is_numeric($action_id)) { // ... either a single membership. $memberships = array(MS_Factory::load('MS_Model_Membership', $action_id)); } elseif ('all' == $action_id) { // ... or all memberships. $memberships = MS_Model_Membership::get_memberships(); } // Loop specified memberships and add the selected items. foreach ($memberships as $membership) { $rule = $membership->get_rule($rule_type); foreach ($items as $item) { switch ($action) { case 'add': $rule->give_access($item); break; case 'rem': $rule->remove_access($item); break; } } $membership->set_rule($rule_type, $rule); $membership->save(); } } } else { // No action request found. } }
/** * Main entry point: Handles the export action. * * This task will exit the current request as the result will be a download * and no HTML page that is displayed. * * @since 1.0.0 */ public function process() { $data = (object) array(); $data->source_key = self::KEY; $data->source = 'Membership2'; $data->plugin_version = MS_PLUGIN_VERSION; $data->export_time = date('Y-m-d H:i'); $data->notes = array(__('Exported data:', MS_TEXT_DOMAIN), __('- Memberships (without protection rules)', MS_TEXT_DOMAIN), __('- Members (including Stripe/Authorize payment settings)', MS_TEXT_DOMAIN), __('- Subscriptions (link between Members and Memberships)', MS_TEXT_DOMAIN), __('- Invoices', MS_TEXT_DOMAIN)); $data->memberships = array(); // Export the base membership (i.e. the Membership2 settings) $membership = MS_Model_Membership::get_base(); $data->memberships[] = $this->export_membership($membership->id); // Export all memberships. $memberships = MS_Model_Membership::get_memberships(array('post_parent' => 0)); foreach ($memberships as $membership) { $data->memberships[] = $this->export_membership($membership->id); } // Export the members. $members = MS_Model_Member::get_members(); $data->members = array(); foreach ($members as $member) { if (!$member->is_member) { continue; } $data->members[] = $this->export_member($member->id); } // Export plugin settings. $obj = array(); $data->settings = $this->export_settings(); // Export Coupons. $data->coupons = array(); lib2()->net->file_download(json_encode($data), 'membership2-export.json'); }
/** * Removes all subscriptions and memberships from the current site. * This is done before the import if the "Replace existing data" flag is set. * * @since 1.0.0 */ protected function clear_memberships() { // Delete all Relationships. $subscriptions = MS_Model_Relationship::get_subscriptions(array('status' => 'all')); foreach ($subscriptions as $subscription) { $subscription->delete(); } // Delete all Memberships. $memberships = MS_Model_Membership::get_memberships(); foreach ($memberships as $membership) { if ($membership->is_base()) { continue; } $membership->delete(true); } }
/** * Set access status to content. * * @since 1.0.0 * @param string $id The content id to set access to. * @param bool $access The access status to set. */ public function set_access($id, $access) { if ($access) { $rule_usage = 1; $this->rule_value[$id] = MS_Model_Rule::RULE_VALUE_HAS_ACCESS; } else { $rule_usage = 0; unset($this->rule_value[$id]); unset($this->dripped[$id]); } // Update the base rule. if (!$this->is_base_rule) { $base = MS_Model_Membership::get_base(); $base_rule = $base->get_rule($this->rule_type); if (!$rule_usage) { $all_memberships = MS_Model_Membership::get_memberships(); foreach ($all_memberships as $membership) { if ($membership->is_base) { continue; } $mem_rule = $membership->get_rule($this->rule_type); if (!$mem_rule->get_rule_value($id)) { continue; } $rule_usage += 1; } } if (!$rule_usage) { $base_rule->remove_access($id); $base->set_rule($this->rule_type, $base_rule); $base->save(); } elseif (!$base_rule->get_rule_value($id)) { // Only `give_access()` when the item is not protected yet. $base_rule->give_access($id); $base->set_rule($this->rule_type, $base_rule); $base->save(); } } do_action('ms_rule_set_access', $id, $access, $this); }
/** * Returns a list of all available Memberships. * * @since 1.0.0 * @api * * @param bool $list_all If set to true then also private and internal * Memberships (e.g. Guest Membership) are included. * Default is false which returns only memberships that a guest user * can subscribe to. * @return MS_Model_Membership[] List of all available Memberships. */ public function list_memberships($list_all = false) { $args = array('include_base' => false, 'include_guest' => true); $list = MS_Model_Membership::get_memberships($args); if (!$list_all) { foreach ($list as $key => $item) { if (!$item->active) { unset($list[$key]); } elseif ($item->private) { unset($list[$key]); } } } return $list; }