/**
  * Add a dependency check to this add-on: It can only be enabled when the
  * parent Add-on "Media" is also enabled.
  *
  * Filter: 'ms_model_addon_is_enabled_addon_mediafiles'
  *
  * @since  1.0.0
  * @internal
  *
  * @param  bool $enabled State of this add-on
  *         (without considering the parent add-on)
  * @return bool The actual state of this add-on.
  */
 public function is_enabled($enabled)
 {
     if ($enabled) {
         $enabled = MS_Model_Addon::is_enabled(MS_Model_Addon::ADDON_MEDIA);
     }
     return $enabled;
 }
 /**
  * Checks if the current Add-on is enabled
  *
  * @since  1.0.0
  * @return bool
  */
 public static function is_active()
 {
     if (!self::buddypress_active() && MS_Model_Addon::is_enabled(self::ID)) {
         $model = MS_Factory::load('MS_Model_Addon');
         $model->disable(self::ID);
     }
     return MS_Model_Addon::is_enabled(self::ID);
 }
 /**
  * Get list table columns.
  *
  * @since  1.0.0
  *
  * @return array {
  *		Returns array of $id => $title.
  *
  *		@type string $id The list table column id.
  *		@type string $title The list table column title.
  * }
  */
 public function get_columns()
 {
     $columns = array('cb' => '<input type="checkbox" />', 'username' => __('Username', MS_TEXT_DOMAIN), 'email' => __('E-mail', MS_TEXT_DOMAIN), 'membership' => __('Membership', MS_TEXT_DOMAIN), 'infos' => '&nbsp;');
     if (!MS_Model_Addon::is_enabled(MS_Model_Addon::ADDON_TRIAL)) {
         unset($columns['trial']);
     }
     return apply_filters('ms_helper_listtable_member_get_columns', $columns);
 }
 /**
  * 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;
 }
 /**
  * Set initial protection.
  *
  * Add [ms-protect-content] shortcode to protect membership content inside post.
  *
  * @since  1.0.0
  */
 public function protect_content()
 {
     parent::protect_content();
     self::$membership_ids[] = $this->membership_id;
     add_shortcode(self::PROTECT_CONTENT_SHORTCODE, array(__CLASS__, 'protect_content_shortcode'));
     if (MS_Model_Addon::is_enabled(MS_Model_Addon::ADDON_SHORTCODE)) {
         global $shortcode_tags;
         $exclude = MS_Helper_Shortcode::get_membership_shortcodes();
         foreach ($shortcode_tags as $shortcode => $callback_funciton) {
             if (in_array($shortcode, $exclude)) {
                 continue;
             }
             if (!parent::has_access($shortcode)) {
                 $shortcode_tags[$shortcode] = array(&$this, 'do_protected_shortcode');
             }
         }
     }
 }
    /**
     * Returns the contens of the dialog
     *
     * @since  1.0.0
     *
     * @return object
     */
    public function get_contents($data)
    {
        $member = $data['model'];
        $currency = MS_Plugin::instance()->settings->currency;
        $show_trial = MS_Model_Addon::is_enabled(MS_Model_Addon::ADDON_TRIAL);
        $all_subscriptions = MS_Model_Relationship::get_subscriptions(array('user_id' => $member->id, 'status' => 'all', 'meta_key' => 'expire_date', 'orderby' => 'meta_value', 'order' => 'DESC'));
        // Prepare the form fields.
        $inp_dialog = array('type' => MS_Helper_Html::INPUT_TYPE_HIDDEN, 'name' => 'dialog', 'value' => 'View_Member_Dialog');
        $inp_id = array('type' => MS_Helper_Html::INPUT_TYPE_HIDDEN, 'name' => 'member_id', 'value' => $member->id);
        $inp_nonce = array('type' => MS_Helper_Html::INPUT_TYPE_HIDDEN, 'name' => '_wpnonce', 'value' => wp_create_nonce(self::ACTION_SAVE));
        $inp_action = array('type' => MS_Helper_Html::INPUT_TYPE_HIDDEN, 'name' => 'dialog_action', 'value' => self::ACTION_SAVE);
        $inp_save = array('type' => MS_Helper_Html::INPUT_TYPE_SUBMIT, 'value' => __('Save', 'membership2'), 'class' => 'ms-submit-form', 'data' => array('form' => 'ms-edit-member'));
        $inp_cancel = array('type' => MS_Helper_Html::INPUT_TYPE_BUTTON, 'value' => __('Close', 'membership2'), 'class' => 'close');
        ob_start();
        ?>
		<div>
			<form class="ms-form wpmui-ajax-update ms-edit-member" data-wpmui-ajax="<?php 
        echo esc_attr('save');
        ?>
">
				<div class="ms-form wpmui-form wpmui-grid-8">
					<table class="widefat">
					<thead>
						<tr>
							<th class="column-membership">
								<?php 
        _e('Membership', 'membership2');
        ?>
							</th>
							<th class="column-status">
								<?php 
        _e('Status', 'membership2');
        ?>
							</th>
							<th class="column-start">
								<?php 
        _e('Subscribed on', 'membership2');
        ?>
							</th>
							<th class="column-expire">
								<?php 
        _e('Expires on', 'membership2');
        ?>
							</th>
							<?php 
        if ($show_trial) {
            ?>
							<th class="column-trialexpire">
								<?php 
            _e('Trial until', 'membership2');
            ?>
							</th>
							<?php 
        }
        ?>
							<th class="column-payments">
								<?php 
        _e('Payments', 'membership2');
        ?>
							</th>
						</tr>
					</thead>
					<tbody>
					<?php 
        foreach ($all_subscriptions as $subscription) {
            $membership = $subscription->get_membership();
            $payments = $subscription->get_payments();
            $num_payments = count($payments);
            $amount_payments = 0;
            foreach ($payments as $payment) {
                $amount_payments += $payment['amount'];
            }
            $subscription_info = array('subscription_id' => $subscription->id);
            $update_info = array('subscription_id' => $subscription->id, 'statuscheck' => 'yes');
            ?>
						<tr>
							<td class="column-membership">
								<?php 
            $membership->name_tag();
            ?>
							</td>
							<td class="column-status">
								<?php 
            printf('<a href="#" data-ms-dialog="View_Member_Subscription" data-ms-data="%2$s">%1$s</a>
									<a href="#" data-ms-dialog="View_Member_Subscription" data-ms-data="%3$s" title="%5$s">%4$s</a>', $subscription->status, esc_attr(json_encode($subscription_info)), esc_attr(json_encode($update_info)), '<i class="dashicons dashicons-update"></i>', __('Check and update subscription status', 'membership2'));
            ?>
							</td>
							<td class="column-start">
								<?php 
            echo $subscription->start_date;
            ?>
							</td>
							<td class="column-expire">
								<?php 
            echo $subscription->expire_date;
            ?>
							</td>
							<?php 
            if ($show_trial) {
                ?>
							<td class="column-trialexpire">
								<?php 
                if ($subscription->start_date == $subscription->trial_expire_date) {
                    echo '-';
                } else {
                    echo $subscription->trial_expire_date;
                }
                ?>
							</td>
							<?php 
            }
            ?>
							<td class="column-payments">
								<?php 
            $total = sprintf('<b>%1$s</b> (%3$s %2$s)', $num_payments, MS_Helper_Billing::format_price($amount_payments), $currency);
            printf('<a href="#" data-ms-dialog="View_Member_Payment" data-ms-data="%1$s">%2$s</a>', esc_attr(json_encode($subscription_info)), $total);
            ?>
							</td>
						</tr>
					<?php 
        }
        ?>
					</tbody>
					</table>
				</div>
				<?php 
        MS_Helper_Html::html_element($inp_id);
        MS_Helper_Html::html_element($inp_dialog);
        MS_Helper_Html::html_element($inp_nonce);
        MS_Helper_Html::html_element($inp_action);
        ?>
			</form>
			<div class="buttons">
				<?php 
        MS_Helper_Html::html_element($inp_cancel);
        // MS_Helper_Html::html_element( $inp_save );
        ?>
			</div>
		</div>
		<?php 
        $html = ob_get_clean();
        return apply_filters('ms_view_member_dialog_to_html', $html);
    }
Пример #7
0
 /**
  * Add rewrite rules.
  *
  * @since  1.0.0
  */
 public function add_rewrite_rules()
 {
     $settings = MS_Factory::load('MS_Model_Settings');
     // Gateway return - IPN.
     add_rewrite_rule('ms-payment-return/(.+)/?', 'index.php?paymentgateway=$matches[1]', 'top');
     // Alternative payment return URL: Membership
     if (MS_Model_Import_Membership::did_import()) {
         add_rewrite_rule('paymentreturn/(.+)/?', 'index.php?paymentgateway=$matches[1]', 'top');
     }
     // Media / download
     $mmask = $settings->downloads['masked_url'];
     $mtype = $settings->downloads['protection_type'];
     if (MS_Model_Addon::is_enabled(MS_Model_Addon::ADDON_MEDIA) && $mmask) {
         if (MS_Rule_Media_Model::PROTECTION_TYPE_HYBRID == $mtype) {
             add_rewrite_rule(sprintf('^%1$s/?$', $mmask), 'index.php?protectedfile=0', 'top');
         } else {
             add_rewrite_rule(sprintf('^%1$s/([^/]+)', $mmask), 'index.php?protectedfile=$matches[1]', 'top');
         }
     }
     // End: Media / download
     do_action('ms_plugin_add_rewrite_rules', $this);
 }
 /**
  * Checks if the current page is a special page and if the special page is
  * protected by this rule.
  *
  * @since  1.0.0
  *
  * @return bool
  */
 public function has_rule_for_current_page()
 {
     if (null === $this->_has_rule) {
         if (!MS_Model_Addon::is_enabled(MS_Model_Addon::ADDON_SPECIAL_PAGES)) {
             $this->_has_rule = false;
         } else {
             $base = $this->get_membership()->get_base();
             $base_rule = $base->get_rule($this->rule_type);
             $this->_has_rule = $this->check_current_page($base_rule->rule_value);
         }
     }
     return $this->_has_rule;
 }
 /**
  * Determine whether Membership access can be changed or is read-only.
  *
  * @since  1.0.0
  * @param string $post_type The post type of the post.
  * @return bool
  */
 public function is_read_only($post_type)
 {
     if ('post' == $post_type && !MS_Model_Addon::is_enabled(MS_Model_Addon::ADDON_POST_BY_POST)) {
         $read_only = true;
     } elseif ('attachment' == $post_type) {
         $read_only = true;
     } else {
         $read_only = false;
     }
     return apply_filters('ms_controller_membership_metabox_is_read_only', $read_only, $post_type, $this);
 }
 /**
  * Membership signup callback function.
  *
  * @since  1.0.0
  *
  * @param mixed[] $atts Shortcode attributes.
  */
 public function membership_signup($atts)
 {
     MS_Helper_Shortcode::did_shortcode(MS_Helper_Shortcode::SCODE_SIGNUP);
     $data = apply_filters('ms_controller_shortcode_membership_signup_atts', shortcode_atts(array(MS_Helper_Membership::MEMBERSHIP_ACTION_SIGNUP . '_text' => __('Signup', 'membership2'), MS_Helper_Membership::MEMBERSHIP_ACTION_MOVE . '_text' => __('Change', 'membership2'), MS_Helper_Membership::MEMBERSHIP_ACTION_CANCEL . '_text' => __('Cancel', 'membership2'), MS_Helper_Membership::MEMBERSHIP_ACTION_RENEW . '_text' => __('Renew', 'membership2'), MS_Helper_Membership::MEMBERSHIP_ACTION_PAY . '_text' => __('Complete Payment', 'membership2')), $atts));
     $member = MS_Model_Member::get_current_member();
     $data['member'] = $member;
     $data['subscriptions'] = array();
     $exclude = array();
     if ($member->is_valid()) {
         // Get member's memberships, including pending relationships.
         $data['subscriptions'] = MS_Model_Relationship::get_subscriptions(array('user_id' => $data['member']->id, 'status' => 'valid'));
         foreach ($data['subscriptions'] as $key => $subscription) {
             $exclude[] = $subscription->membership_id;
             if (!$member->can_subscribe_to($subscription->membership_id)) {
                 unset($data['subscriptions'][$key]);
             }
         }
     }
     $memberships = MS_Model_Membership::get_signup_membership_list(null, $exclude);
     $data['memberships'] = $memberships;
     $move_from_ids = array();
     // When Multiple memberships is not enabled, a member should move to another membership.
     if (!MS_Model_Addon::is_enabled(MS_Model_Addon::ADDON_MULTI_MEMBERSHIPS)) {
         // Membership Relationship status which can move to another one
         $valid_status = array(MS_Model_Relationship::STATUS_TRIAL, MS_Model_Relationship::STATUS_ACTIVE, MS_Model_Relationship::STATUS_EXPIRED);
         foreach ($data['member']->subscriptions as $subscription) {
             if ($subscription->is_system()) {
                 continue;
             }
             if (in_array($subscription->status, $valid_status)) {
                 $move_from_ids[] = $subscription->membership_id;
             }
         }
         foreach ($data['memberships'] as $key => $membership) {
             $data['memberships'][$key]->_move_from = $move_from_ids;
         }
     } else {
         foreach ($data['memberships'] as $key => $membership) {
             $move_from_ids = $member->cancel_ids_on_subscription($membership->id);
             $data['memberships'][$key]->_move_from = $move_from_ids;
         }
     }
     $data['action'] = MS_Helper_Membership::MEMBERSHIP_ACTION_SIGNUP;
     $data['step'] = MS_Controller_Frontend::STEP_PAYMENT_TABLE;
     $view = MS_Factory::create('MS_View_Shortcode_MembershipSignup');
     $view->data = apply_filters('ms_view_shortcode_membershipsignup_data', $data, $this);
     return $view->to_html();
 }
 /**
  * Initializes the Add-on. Always executed.
  *
  * @since  1.0.1.0
  */
 public function init()
 {
     MS_Model_Addon::disable(self::ID);
 }
 /**
  * Returns the active flag for a specific rule.
  * State depends on Add-on
  *
  * @since  1.0.0
  * @return bool
  */
 public static function is_active()
 {
     return MS_Model_Addon::is_enabled(MS_Model_Addon::ADDON_POST_BY_POST);
 }
 /**
  * Returns the active flag for a specific rule.
  * State depends on Add-on
  *
  * @since  1.0.0
  * @return bool
  */
 public static function is_active()
 {
     $def = MS_Model_Addon::is_enabled(MS_Model_Addon::ADDON_MEMBERCAPS);
     $adv = MS_Model_Addon::is_enabled(MS_Model_Addon::ADDON_MEMBERCAPS_ADV);
     return $def && !$adv;
 }
 /**
  * Verify access to the current content.
  *
  * @since  1.0.0
  *
  * @param string $id The content id to verify access.
  * @return bool|null True if has access, false otherwise.
  *     Null means: Rule not relevant for current page.
  */
 public function has_access($id, $admin_has_access = true)
 {
     $has_access = null;
     // Only verify permission if ruled by cpt post by post.
     if (MS_Model_Addon::is_enabled(MS_Model_Addon::ADDON_CPT_POST_BY_POST)) {
         if (empty($id)) {
             $id = $this->get_current_post_id();
         }
         if (!empty($id)) {
             $post_type = get_post_type($id);
             $mspt = MS_Rule_CptGroup_Model::get_ms_post_types();
             $cpt = MS_Rule_CptGroup_Model::get_custom_post_types();
             if (in_array($post_type, $mspt)) {
                 // Always allow access to Membership2 pages.
                 $has_access = true;
             } elseif (in_array($post_type, $cpt)) {
                 // Custom post type
                 $has_access = parent::has_access($id, $admin_has_access);
             } else {
                 // WordPress core pages are ignored by this rule.
                 $has_access = null;
             }
         }
     }
     return apply_filters('ms_rule_custom_post_type_has_access', $has_access, $id, $this);
 }
 /**
  * Checks if the current user can access the specified attachment.
  *
  * @since  1.0.0
  * @param  int $attachment_id
  * @return bool
  */
 public function can_access_file($attachment_id)
 {
     $access = false;
     if (MS_Model_Member::is_normal_admin()) {
         return true;
     }
     if (!MS_Model_Addon::is_enabled(MS_Addon_Mediafiles::ID)) {
         /*
          * Default protection mode:
          * Protect Attachments based on the parent post.
          */
         $parent_id = get_post_field('post_parent', $attachment_id);
         if (!$parent_id) {
             $access = true;
         } else {
             $member = MS_Model_Member::get_current_member();
             foreach ($member->subscriptions as $subscription) {
                 $membership = $subscription->get_membership();
                 $access = $membership->has_access_to_post($parent_id);
                 if ($access) {
                     break;
                 }
             }
         }
     } else {
         /*
          * Advanced protection mode (via Add-on):
          * Each Attachment can be protected individually.
          */
         $member = MS_Model_Member::get_current_member();
         foreach ($member->subscriptions as $subscription) {
             $rule = $subscription->get_membership()->get_rule(MS_Rule_Media::RULE_ID);
             $access = $rule->has_access($attachment_id);
             if ($access) {
                 break;
             }
         }
     }
     return apply_filters('ms_rule_media_can_access_file', $access, $attachment_id);
 }
 /**
  * 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) . ' &raquo;', '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);
 }
Пример #17
0
 /**
  * Verify if a post/custom post type has protection rules.
  *
  * @since  1.0.0
  *
  * @return boolean True if has access, false otherwise.
  */
 public function has_rule_for_post($post_id)
 {
     $has_rules = false;
     if (MS_Model_Addon::is_enabled(MS_Model_Addon::ADDON_URL_GROUPS)) {
         $url = get_permalink($post_id);
         if ($this->check_url_expression_match($url, $this->get_protected_urls())) {
             $has_rules = true;
         }
     }
     return apply_filters('ms_rule_url_model_has_rule_for_post', $has_rules, $this);
 }
 /**
  * Checks the /app/addon directory for a list of all addons and loads these
  * files.
  *
  * @since  1.0.0
  */
 protected static function load_core_addons()
 {
     $model = MS_Factory::load('MS_Model_Addon');
     $root_path = trailingslashit(dirname(dirname(MS_Plugin::instance()->dir)));
     $plugin_dir = substr(MS_Plugin::instance()->dir, strlen($root_path));
     $addon_dir = $plugin_dir . 'app/addon/';
     if (empty($model->addon_files) || self::$_reload_files) {
         // In Admin dashboard we always refresh the addon-list...
         self::$_reload_files = false;
         $mask = $root_path . $addon_dir . '*/class-ms-addon-*.php';
         $addons = glob($mask);
         $model->addon_files = array();
         foreach ($addons as $file) {
             $model->addon_files[] = substr($file, strlen($root_path));
         }
         /**
          * Allow other plugins/themes to register custom addons
          *
          * @since  1.0.0
          *
          * @var array
          */
         $model->addon_files = apply_filters('ms_model_addon_files', $model->addon_files);
         $model->save();
     }
     // Loop all recignized Add-ons and initialize them.
     foreach ($model->addon_files as $file) {
         $addon = $root_path . $file;
         // Get class-name from file-name
         $class = basename($file);
         $class = str_replace('.php', '', $class);
         $class = implode('_', array_map('ucfirst', explode('-', $class)));
         $class = substr($class, 6);
         // remove 'Class_' prefix
         if (file_exists($addon)) {
             if (!class_exists($class)) {
                 try {
                     include_once $addon;
                 } catch (Exception $ex) {
                 }
             }
             if (class_exists($class)) {
                 MS_Factory::load($class);
             }
         }
     }
     /**
      * Allow custom addon-initialization code to run
      *
      * @since  1.0.0
      */
     do_action('ms_model_addon_load');
 }
 /**
  * Returns the active flag for a specific rule.
  * State depends on Add-on
  *
  * @since  1.0.0
  * @return bool
  */
 public static function is_active()
 {
     return MS_Model_Addon::is_enabled(MS_Addon_Category::ID);
 }
 /**
  * Returns true if this membership is eligable for trial period.
  *
  * @since  1.0.1.0
  * @return bool
  */
 public function has_trial()
 {
     $result = $this->trial_period_enabled;
     if ($result) {
         if (!MS_Model_Addon::is_enabled(MS_Model_Addon::ADDON_TRIAL)) {
             $result = false;
         }
     }
     return $result;
 }
 /**
  * Handle protected media access.
  *
  * Search for masked file and show the proper content, or no access image if don't have access.
  *
  * Realted Action Hooks:
  * - parse_request
  *
  * @since  1.0.0
  *
  * @param WP_Query $query The WP_Query object to filter.
  */
 public function handle_download_protection($query)
 {
     do_action('ms_rule_media_model_handle_download_protection_before', $query, $this);
     $the_file = false;
     $requested_item = false;
     $download_settings = MS_Plugin::instance()->settings->downloads;
     $protection_type = $download_settings['protection_type'];
     if (!MS_Model_Addon::is_enabled(MS_Model_Addon::ADDON_MEDIA)) {
         return;
     }
     if (!empty($query->query_vars['protectedfile'])) {
         $requested_item = explode('/', $query->query_vars['protectedfile']);
         $requested_item = array_pop($requested_item);
     } elseif (!empty($_GET['ms_file']) && self::PROTECTION_TYPE_HYBRID == $protection_type) {
         $requested_item = $_GET['ms_file'];
     }
     if (!empty($requested_item)) {
         // At this point we know that the requested post is an attachment.
         $f_info = $this->extract_file_info($requested_item);
         switch ($protection_type) {
             case self::PROTECTION_TYPE_COMPLETE:
             case self::PROTECTION_TYPE_HYBRID:
                 // Work out the post_id again
                 $attachment_id = preg_replace('/^' . self::FILE_PROTECTION_PREFIX . '/', '', $f_info->filename);
                 $attachment_id -= (int) self::FILE_PROTECTION_INCREMENT;
                 $the_file = $this->restore_filename($attachment_id, $f_info->size_extension);
                 break;
             default:
             case self::PROTECTION_TYPE_BASIC:
                 $home = untrailingslashit(get_option('home'));
                 $attachment_id = $this->get_attachment_id($home . $f_info->filename);
                 $the_file = $this->restore_filename($attachment_id, $f_info->size_extension);
                 break;
         }
         if (!empty($the_file) && !empty($attachment_id) && is_numeric($attachment_id)) {
             if ($this->can_access_file($attachment_id)) {
                 $upload_dir = wp_upload_dir();
                 $file = trailingslashit($upload_dir['basedir']) . $the_file;
                 $this->output_file($file);
             } else {
                 $this->show_no_access_image();
             }
         }
     }
     do_action('ms_rule_media_model_handle_download_protection_after', $query, $this);
 }
 /**
  * Verify access to the current content.
  *
  * @since  1.0.0
  *
  * @param string $id The content id to verify access.
  * @return bool|null True if has access, false otherwise.
  *     Null means: Rule not relevant for current page.
  */
 public function has_access($id, $admin_has_access = true)
 {
     $has_access = null;
     // Only verify permission if NOT ruled by cpt post by post.
     if (MS_Model_Addon::is_enabled(MS_Model_Addon::ADDON_CPT_POST_BY_POST)) {
         return $has_access;
     }
     if (!empty($id)) {
         $post = get_post($id);
     } else {
         $post = get_queried_object();
     }
     $post_type = !empty($post->post_type) ? $post->post_type : '';
     if (empty($post_type) && !empty($post->query_var)) {
         $post_type = $post->query_var;
     }
     if (in_array($post_type, self::get_ms_post_types())) {
         // Always allow access to Membership2 pages.
         $has_access = true;
     } elseif (in_array($post_type, self::get_custom_post_types())) {
         // Custom post type
         $has_access = parent::has_access($post_type, $admin_has_access);
     } else {
         // WordPress core pages are ignored by this rule.
         $has_access = null;
     }
     return apply_filters('ms_rule_cptgroup_model_has_access', $has_access, $id, $this);
 }
 /**
  * Prepares fields for the edit form.
  *
  * @since  1.0.1.0
  * @return array
  */
 protected function get_fields()
 {
     $membership = $this->data['membership'];
     $action = MS_Controller_Membership::AJAX_ACTION_UPDATE_MEMBERSHIP;
     $nonce = wp_create_nonce($action);
     $fields = array();
     // Prepare the form fields.
     $fields['name'] = array('id' => 'name', 'type' => MS_Helper_Html::INPUT_TYPE_TEXT, 'title' => apply_filters('ms_translation_flag', __('Name:', MS_TEXT_DOMAIN), 'membership-name'), 'value' => $membership->name, 'ajax_data' => array(1));
     $fields['description'] = array('id' => 'description', 'type' => MS_Helper_Html::INPUT_TYPE_TEXT_AREA, 'title' => apply_filters('ms_translation_flag', __('Description:', MS_TEXT_DOMAIN), 'membership-name'), 'value' => $membership->description, 'ajax_data' => array(1));
     $fields['active'] = array('id' => 'active', 'type' => MS_Helper_Html::INPUT_TYPE_RADIO_SLIDER, 'title' => __('This membership is active', MS_TEXT_DOMAIN), 'before' => __('No', MS_TEXT_DOMAIN), 'after' => __('Yes', MS_TEXT_DOMAIN), 'class' => 'ms-active', 'value' => $membership->active, 'ajax_data' => array(1));
     $fields['public'] = array('id' => 'public', 'type' => MS_Helper_Html::INPUT_TYPE_RADIO_SLIDER, 'title' => __('This membership is public', MS_TEXT_DOMAIN), 'desc' => __('Users can see it listed on your site and can register for it', MS_TEXT_DOMAIN), 'before' => __('No', MS_TEXT_DOMAIN), 'after' => __('Yes', MS_TEXT_DOMAIN), 'class' => 'ms-public', 'value' => $membership->public, 'ajax_data' => array(1));
     $fields['paid'] = array('id' => 'is_paid', 'type' => MS_Helper_Html::INPUT_TYPE_RADIO_SLIDER, 'title' => __('This is a paid membership', MS_TEXT_DOMAIN), 'before' => __('No', MS_TEXT_DOMAIN), 'after' => __('Yes', MS_TEXT_DOMAIN), 'class' => 'ms-paid', 'value' => $membership->is_paid, 'ajax_data' => array(1));
     $priority_list = array();
     $args = array('include_guest' => 0);
     $count = MS_Model_Membership::get_membership_count($args);
     for ($i = 1; $i <= $count; $i += 1) {
         $priority_list[$i] = $i;
     }
     $priority_list[$membership->priority] = $membership->priority;
     $fields['priority'] = array('id' => 'priority', 'type' => MS_Helper_Html::INPUT_TYPE_SELECT, 'title' => __('Membership order', MS_TEXT_DOMAIN), 'desc' => __('This defines the display order on the Membership Page.', MS_TEXT_DOMAIN), 'class' => 'ms-priority', 'before' => __('Order', MS_TEXT_DOMAIN), 'value' => $membership->priority, 'field_options' => $priority_list, 'ajax_data' => array(1));
     if (MS_Model_Addon::is_enabled(MS_Model_Addon::ADDON_MULTI_MEMBERSHIPS)) {
         $fields['priority']['desc'] .= '<br>' . __('It also controlls which Protection Message is used in case a member has multiple memberships (the lowest value wins)', MS_TEXT_DOMAIN);
     }
     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;
 }
 /**
  * Returns the active flag for a specific rule.
  * State depends on Add-on
  *
  * @since  1.0.0
  * @return bool
  */
 public static function is_active()
 {
     return MS_Model_Addon::is_enabled(MS_Model_Addon::ADDON_ADMINSIDE);
 }
 /**
  * Load all the Add-ons.
  *
  * Related Action Hooks:
  * - ms_load_member
  *
  * @since  1.0.0
  */
 public function load_addons()
 {
     do_action('ms_load_addons', $this);
     // Initialize all Add-ons
     MS_Model_Addon::get_addons();
 }
 /**
  * Get available tabs for Membership2 page.
  *
  * @since  1.0.0
  *
  * @return array The tabs configuration.
  */
 public function get_available_tabs()
 {
     static $Tabs = null;
     if (null === $Tabs) {
         $membership = $this->load_membership();
         $membership_id = $membership->id;
         $is_base = $membership->is_base();
         $settings = MS_Factory::load('MS_Model_Settings');
         // First create a list including all possible tabs.
         $tabs = array(MS_Rule_Page::RULE_ID => true, MS_Rule_Post::RULE_ID => true, MS_Rule_Category::RULE_ID => true, MS_Rule_Content::RULE_ID => true, MS_Rule_Media::RULE_ID => true, MS_Rule_MenuItem::RULE_ID => true, MS_Rule_ReplaceMenu::RULE_ID => true, MS_Rule_ReplaceLocation::RULE_ID => true, MS_Rule_Shortcode::RULE_ID => true, MS_Rule_Url::RULE_ID => true, MS_Rule_Special::RULE_ID => true, MS_Rule_MemberCaps::RULE_ID => true, MS_Rule_MemberRoles::RULE_ID => true);
         // Now remove items from the list that are not available.
         // Optionally show "Posts"
         if (!MS_Model_Addon::is_enabled(MS_Model_Addon::ADDON_POST_BY_POST)) {
             $tabs[MS_Rule_Post::RULE_ID] = false;
         }
         // Optionally show "Category"
         if (!MS_Model_Addon::is_enabled(MS_Addon_Category::ID)) {
             $tabs[MS_Rule_Category::RULE_ID] = false;
         }
         // Optionally show "Media"
         if (!MS_Model_Addon::is_enabled(MS_Addon_Mediafiles::ID)) {
             $tabs[MS_Rule_Media::RULE_ID] = false;
         }
         // Either "Menu Item" or "Menus" or "Menu Location"
         switch ($settings->menu_protection) {
             case 'menu':
                 $tabs[MS_Rule_MenuItem::RULE_ID] = false;
                 $tabs[MS_Rule_ReplaceLocation::RULE_ID] = false;
                 break;
             case 'location':
                 $tabs[MS_Rule_MenuItem::RULE_ID] = false;
                 $tabs[MS_Rule_ReplaceMenu::RULE_ID] = false;
                 break;
             case 'item':
             default:
                 $tabs[MS_Rule_ReplaceMenu::RULE_ID] = false;
                 $tabs[MS_Rule_ReplaceLocation::RULE_ID] = false;
                 break;
         }
         // Maybe "Special Pages".
         if (!MS_Model_Addon::is_enabled(MS_Model_Addon::ADDON_SPECIAL_PAGES)) {
             $tabs[MS_Rule_Special::RULE_ID] = false;
         }
         // Maybe "URLs"
         if (!MS_Model_Addon::is_enabled(MS_Model_Addon::ADDON_URL_GROUPS)) {
             $tabs[MS_Rule_Url::RULE_ID] = false;
         }
         // Maybe "Shortcodes"
         if (!MS_Model_Addon::is_enabled(MS_Model_Addon::ADDON_SHORTCODE)) {
             $tabs[MS_Rule_Shortcode::RULE_ID] = false;
         }
         // Maybe "Membercaps"
         if (MS_Model_Addon::is_enabled(MS_Model_Addon::ADDON_MEMBERCAPS)) {
             if (MS_Model_Addon::is_enabled(MS_Model_Addon::ADDON_MEMBERCAPS_ADV)) {
                 $tabs[MS_Rule_MemberRoles::RULE_ID] = false;
             } else {
                 $tabs[MS_Rule_MemberCaps::RULE_ID] = false;
             }
         } else {
             $tabs[MS_Rule_MemberRoles::RULE_ID] = false;
             $tabs[MS_Rule_MemberCaps::RULE_ID] = false;
         }
         lib2()->array->equip($_GET, 'page');
         // Allow Add-ons to add or remove rule tabs
         $tabs = apply_filters('ms_controller_protection_tabs', $tabs, $membership_id);
         $page = sanitize_html_class($_GET['page'], MS_Controller_Plugin::MENU_SLUG . '-memberships');
         $rule_titles = MS_Model_Rule::get_rule_type_titles();
         $result = array();
         foreach ($tabs as $rule_type => $state) {
             if (!$state) {
                 continue;
             }
             $url = sprintf('%s?page=%s&tab=%s', admin_url('admin.php'), $page, $rule_type);
             // Try to keep the selected Membership and Status filter.
             if (!empty($_REQUEST['membership_id'])) {
                 $url = esc_url_raw(add_query_arg(array('membership_id' => $_REQUEST['membership_id']), $url));
             }
             if (!empty($_REQUEST['status'])) {
                 $url = esc_url_raw(add_query_arg(array('status' => $_REQUEST['status']), $url));
             }
             $result[$rule_type] = array('title' => $rule_titles[$rule_type], 'url' => $url);
         }
         $Tabs = apply_filters('ms_controller_protection_get_available_tabs', $result, $membership_id, $this);
     }
     return $Tabs;
 }
 /**
  * Checks if the current Add-on is enabled
  *
  * @since  1.0.0
  * @return bool
  */
 public static function is_active()
 {
     return MS_Model_Addon::is_enabled(self::ID);
 }
 /**
  * This list has no views.
  *
  * @since  1.0.2.0
  *
  * @return array
  */
 public function get_views()
 {
     $views = array();
     $args = array();
     $count = 0;
     $views['label'] = array('label' => __('Subscription Status:', 'membership2'));
     if (empty($_REQUEST['membership_id'])) {
         // All users
         $url = esc_url_raw(add_query_arg('status', 'all'));
         $views['all'] = array('url' => $url, 'label' => __('All users', 'membership2'));
     } else {
         $args['membership_id'] = $_REQUEST['membership_id'];
     }
     // Active, Trial, Cancelled
     $url = esc_url_raw(remove_query_arg('status'));
     $args['subscription_status'] = MS_Model_Relationship::STATUS_ACTIVE;
     $count = MS_Model_Member::get_members_count($args);
     $views['active'] = array('url' => $url, 'label' => __('Active subscription', 'membership2'), 'count' => $count);
     // Cancelled
     $url = esc_url_raw(add_query_arg('status', MS_Model_Relationship::STATUS_CANCELED));
     $args['subscription_status'] = MS_Model_Relationship::STATUS_CANCELED;
     $count = MS_Model_Member::get_members_count($args);
     $views['cancelled'] = array('url' => $url, 'label' => __('Cancelled', 'membership2'), 'count' => $count);
     // Trial
     if (MS_Model_Addon::is_enabled(MS_Model_Addon::ADDON_TRIAL)) {
         $url = esc_url_raw(add_query_arg('status', MS_Model_Relationship::STATUS_TRIAL));
         $args['subscription_status'] = MS_Model_Relationship::STATUS_TRIAL;
         $count = MS_Model_Member::get_members_count($args);
         $views['trial'] = array('url' => $url, 'label' => __('Trial', 'membership2'), 'count' => $count);
     }
     // Expired, Trial-Expired
     $url = esc_url_raw(add_query_arg('status', 'expired'));
     $args['subscription_status'] = 'expired';
     $count = MS_Model_Member::get_members_count($args);
     $views['expired'] = array('url' => $url, 'label' => __('Expired', 'membership2'), 'count' => $count);
     return $views;
 }
Пример #29
0
 /**
  * Returns a specific property.
  *
  * @since  1.0.0
  *
  * @param  string $property The name of a property.
  * @return mixed $value The value of a property.
  */
 public function __get($property)
 {
     $value = null;
     switch ($property) {
         case 'menu_protection':
             if (!MS_Model_Addon::is_enabled(MS_Model_Addon::ADDON_ADV_MENUS)) {
                 $value = 'item';
             } else {
                 $value = $this->menu_protection;
             }
             break;
         default:
             if (property_exists($this, $property)) {
                 $value = $this->{$property};
             } else {
                 switch ($property) {
                     case 'currency_symbol':
                         // Same translation table in:
                         // -> ms-view-membership-setup-payment.js
                         $symbol = $this->currency;
                         switch ($symbol) {
                             case 'USD':
                                 $symbol = '$';
                                 break;
                             case 'EUR':
                                 $symbol = '€';
                                 break;
                             case 'JPY':
                                 $symbol = '¥';
                                 break;
                         }
                         $value = $symbol;
                 }
             }
     }
     return apply_filters('ms_model_settings__get', $value, $property, $this);
 }
 /**
  * Check membership status.
  *
  * Execute actions when time/period condition are met.
  * E.g. change membership status, add communication to queue, create invoices.
  *
  * This check is called via a cron job.
  *
  * @since  1.0.0
  * @internal  Used by Cron
  * @see MS_Model_Plugin::check_membership_status()
  */
 public function check_membership_status()
 {
     do_action('ms_model_relationship_check_membership_status_before', $this);
     /**
      * Use `define( 'MS_LOCK_SUBSCRIPTIONS', true );` in wp-config.php to prevent
      * Membership2 from sending *any* emails to users.
      * Also any currently enqueued message is removed from the queue
      *
      * @since  1.0.0
      */
     if (MS_Plugin::get_modifier('MS_LOCK_SUBSCRIPTIONS')) {
         return false;
     }
     $membership = $this->get_membership();
     $remaining_days = $this->get_remaining_period();
     $remaining_trial_days = $this->get_remaining_trial_period();
     $comms = MS_Model_Communication::get_communications($membership);
     $invoice_before_days = 5;
     //@todo create a setting to configure this period.
     $deactivate_expired_after_days = 30;
     //@todo create a setting to configure this period.
     $deactivate_pending_after_days = 30;
     //@todo create a setting to configure this period.
     $deactivate_trial_expired_after_days = 5;
     //@todo create a setting to configure this period.
     //@todo: Add a flag to subscriptions with sent communications. Then improve the conditions below to prevent multiple emails.
     do_action('ms_check_membership_status-' . $this->status, $this, $remaining_days, $remaining_trial_days);
     // Update the Subscription status.
     $next_status = $this->calculate_status(null);
     switch ($next_status) {
         case self::STATUS_TRIAL:
             if (MS_Model_Addon::is_enabled(MS_Model_Addon::ADDON_TRIAL) && MS_Model_Addon::is_enabled(MS_Model_Addon::ADDON_AUTO_MSGS_PLUS)) {
                 // Send trial end communication.
                 $comm = $comms[MS_Model_Communication::COMM_TYPE_BEFORE_TRIAL_FINISHES];
                 if ($comm->enabled) {
                     $days = MS_Helper_Period::get_period_in_days($comm->period['period_unit'], $comm->period['period_type']);
                     //@todo: This will send out the reminder multiple times on the reminder-day (4 times or more often)
                     if ($days == $remaining_trial_days) {
                         $comm->add_to_queue($this->id);
                         MS_Model_Event::save_event(MS_Model_Event::TYPE_MS_BEFORE_TRIAL_FINISHES, $this);
                     }
                 }
             }
             // Check for card expiration
             $gateway = $this->get_gateway();
             $gateway->check_card_expiration($this);
             break;
         case self::STATUS_TRIAL_EXPIRED:
             if (MS_Model_Addon::is_enabled(MS_Model_Addon::ADDON_TRIAL)) {
                 // Mark the trial period as completed. $this->save() is below.
                 $this->trial_period_completed = true;
                 // Request payment to the gateway (for gateways that allows it).
                 $gateway = $this->get_gateway();
                 /*
                  * The subscription will be either automatically activated
                  * or set to pending.
                  *
                  * Important: Set trial_period_completed=true before calling
                  * request_payment()!
                  */
                 if ($gateway->request_payment($this)) {
                     $next_status = self::STATUS_ACTIVE;
                     $this->status = $next_status;
                     $this->config_period();
                     // Needed because of status change.
                 }
                 // Check for card expiration
                 $gateway->check_card_expiration($this);
                 // Deactivate expired memberships after a period of time.
                 if ($deactivate_trial_expired_after_days < -$remaining_trial_days) {
                     $this->deactivate_membership();
                 }
             }
             break;
         case self::STATUS_ACTIVE:
         case self::STATUS_EXPIRED:
         case self::STATUS_CANCELED:
             /*
              * Make sure the expire date has a correct value, in case the user
              * changed the payment_type of the parent membership after this
              * subscription was created.
              */
             if ($this->payment_type != $membership->payment_type) {
                 $this->payment_type = $membership->payment_type;
                 switch ($this->payment_type) {
                     case MS_Model_Membership::PAYMENT_TYPE_PERMANENT:
                         $this->expire_date = false;
                         break;
                     default:
                         // Either keep the current expire date (if valid) or
                         // calculate a new expire date, based on current date.
                         if (!$this->expire_date) {
                             $this->expire_date = $this->calc_expire_date(MS_Helper_Period::current_date());
                         }
                         break;
                 }
                 // Recalculate the days until the subscription expires.
                 $remaining_days = $this->get_remaining_period();
                 // Recalculate the new Subscription status.
                 $next_status = $this->calculate_status();
             }
             /*
              * Only "Recurring" memberships will ever try to automatically
              * renew the subscription. All other types will expire when the
              * end date is reached.
              */
             $auto_renew = $membership->payment_type == MS_Model_Membership::PAYMENT_TYPE_RECURRING;
             $deactivate = false;
             $invoice = null;
             if ($auto_renew && $membership->pay_cycle_repetitions > 0) {
                 /*
                  * The membership has a payment-repetition limit.
                  * When this limit is reached then we do not auto-renew the
                  * subscription but expire it.
                  */
                 $payments = $this->get_payments();
                 if (count($payments) >= $membership->pay_cycle_repetitions) {
                     $auto_renew = false;
                 }
             }
             if ($auto_renew) {
                 if ($remaining_days < $invoice_before_days) {
                     // Create a new invoice.
                     $invoice = $this->get_next_invoice();
                 } else {
                     $invoice = $this->get_current_invoice();
                 }
             } else {
                 $invoice = $this->get_current_invoice();
             }
             // Advanced communications Add-on.
             if (MS_Model_Addon::is_enabled(MS_Model_Addon::ADDON_AUTO_MSGS_PLUS)) {
                 // Before finishes communication.
                 $comm = $comms[MS_Model_Communication::COMM_TYPE_BEFORE_FINISHES];
                 $days = MS_Helper_Period::get_period_in_days($comm->period['period_unit'], $comm->period['period_type']);
                 if ($days == $remaining_days) {
                     $comm->add_to_queue($this->id);
                     MS_Model_Event::save_event(MS_Model_Event::TYPE_MS_BEFORE_FINISHES, $this);
                 }
                 // After finishes communication.
                 $comm = $comms[MS_Model_Communication::COMM_TYPE_AFTER_FINISHES];
                 $days = MS_Helper_Period::get_period_in_days($comm->period['period_unit'], $comm->period['period_type']);
                 if ($remaining_days < 0 && $days == abs($remaining_days)) {
                     $comm->add_to_queue($this->id);
                     MS_Model_Event::save_event(MS_Model_Event::TYPE_MS_AFTER_FINISHES, $this);
                 }
                 // Before payment due.
                 $comm = $comms[MS_Model_Communication::COMM_TYPE_BEFORE_PAYMENT_DUE];
                 $days = MS_Helper_Period::get_period_in_days($comm->period['period_unit'], $comm->period['period_type']);
                 $invoice_days = MS_Helper_Period::subtract_dates($invoice->due_date, MS_Helper_Period::current_date());
                 if (MS_Model_Invoice::STATUS_BILLED == $invoice->status && $days == $invoice_days) {
                     $comm->add_to_queue($this->id);
                     MS_Model_Event::save_event(MS_Model_Event::TYPE_PAYMENT_BEFORE_DUE, $this);
                 }
                 // After payment due event
                 $comm = $comms[MS_Model_Communication::COMM_TYPE_AFTER_PAYMENT_DUE];
                 $days = MS_Helper_Period::get_period_in_days($comm->period['period_unit'], $comm->period['period_type']);
                 $invoice_days = MS_Helper_Period::subtract_dates($invoice->due_date, MS_Helper_Period::current_date());
                 if (MS_Model_Invoice::STATUS_BILLED == $invoice->status && $days == $invoice_days) {
                     $comm->add_to_queue($this->id);
                     MS_Model_Event::save_event(MS_Model_Event::TYPE_PAYMENT_AFTER_DUE, $this);
                 }
             }
             // -- End of advanced communications Add-on
             // Subscription ended. See if we can renew it.
             if ($remaining_days <= 0) {
                 if ($auto_renew) {
                     /*
                      * The membership can be renewed. Try to renew it
                      * automatically by requesting the next payment from the
                      * payment gateway (only works if gateway supports this)
                      */
                     $gateway = $this->get_gateway();
                     $gateway->check_card_expiration($this);
                     $gateway->request_payment($this);
                     // Check if the payment was successful.
                     $remaining_days = $this->get_remaining_period();
                 }
                 /*
                  * User did not renew the membership. Give him some time to
                  * react before restricting his access.
                  */
                 if ($deactivate_expired_after_days < -$remaining_days) {
                     $deactivate = true;
                 }
             }
             $next_status = $this->calculate_status(null);
             /*
              * When the subscription expires the first time then create a
              * new event that triggers the "Expired" email.
              */
             if (self::STATUS_EXPIRED == $next_status && $next_status != $this->status) {
                 MS_Model_Event::save_event(MS_Model_Event::TYPE_MS_EXPIRED, $this);
             } elseif ($deactivate) {
                 $this->deactivate_membership();
                 $next_status = $this->status;
                 // Move membership to configured membership.
                 $membership = $this->get_membership();
                 $new_membership = MS_Factory::load('MS_Model_Membership', $membership->on_end_membership_id);
                 if ($new_membership->is_valid()) {
                     $member = MS_Factory::load('MS_Model_Member', $this->user_id);
                     $new_subscription = $member->add_membership($membership->on_end_membership_id, $this->gateway_id);
                     MS_Model_Event::save_event(MS_Model_Event::TYPE_MS_MOVED, $new_subscription);
                     /*
                      * If the new membership is paid we want that the user
                      * confirms the payment in his account. So we set it
                      * to "Pending" first.
                      */
                     if (!$new_membership->is_free()) {
                         $new_subscription->status = self::STATUS_PENDING;
                     }
                 }
             }
             break;
         case self::STATUS_DEACTIVATED:
             /*
              * A subscription was finally deactivated.
              * Lets check if the member has any other active subscriptions,
              * or (if not) his account should be deactivated.
              *
              * First get a list of all subscriptions that do not have status
              * Pending / Deactivated.
              */
             $subscriptions = self::get_subscriptions(array('user_id' => $this->user_id));
             // Check if there is a subscription that keeps the user active.
             $deactivate = true;
             foreach ($subscriptions as $item) {
                 if ($item->id == $this->id) {
                     continue;
                 }
                 $deactivate = false;
             }
             if ($deactivate) {
                 $member = $this->get_member();
                 $member->is_member = false;
                 $member->save();
             }
             break;
         case self::STATUS_PENDING:
         default:
             // Do nothing.
             break;
     }
     // Save the new status.
     $this->status = $next_status;
     $this->save();
     // Save the changed email queue.
     foreach ($comms as $comm) {
         $comm->save();
     }
     do_action('ms_model_relationship_check_membership_status_after', $this);
 }