/**
  * Prepare html fields.
  *
  * @since  1.0.0
  *
  * @return array
  */
 function prepare_fields()
 {
     $invitation = $this->data['invitation'];
     if (!$invitation->is_valid()) {
         $invitation->code = substr(md5(time()), 0, 20);
     }
     $fields = array('code' => array('id' => 'code', 'title' => __('Invitation code', MS_TEXT_DOMAIN), 'type' => MS_Helper_Html::INPUT_TYPE_TEXT, 'value' => $invitation->code, 'class' => 'widefat'), 'start_date' => array('id' => 'start_date', 'title' => __('Start date', MS_TEXT_DOMAIN), 'type' => MS_Helper_Html::INPUT_TYPE_DATEPICKER, 'value' => $invitation->start_date ? $invitation->start_date : MS_Helper_Period::current_date(), 'class' => 'ms-date'), 'expire_date' => array('id' => 'expire_date', 'title' => __('Expire date', MS_TEXT_DOMAIN), 'type' => MS_Helper_Html::INPUT_TYPE_DATEPICKER, 'value' => $invitation->expire_date, 'class' => 'ms-date'), 'membership_id' => array('id' => 'membership_id', 'title' => __('Invitation can be applied to these Memberships', MS_TEXT_DOMAIN), 'type' => MS_Helper_Html::INPUT_TYPE_CHECKBOX, 'field_options' => $this->data['memberships'], 'value' => $invitation->membership_id), 'max_uses' => array('id' => 'max_uses', 'title' => __('Max uses', MS_TEXT_DOMAIN), 'type' => MS_Helper_Html::INPUT_TYPE_NUMBER, 'value' => $invitation->max_uses, 'config' => array('step' => '1', 'min' => 0)), 'invitation_id' => array('id' => 'invitation_id', 'type' => MS_Helper_Html::INPUT_TYPE_HIDDEN, 'value' => $invitation->id), '_wpnonce' => array('id' => '_wpnonce', 'type' => MS_Helper_Html::INPUT_TYPE_HIDDEN, 'value' => wp_create_nonce($this->data['action'])), 'action' => array('id' => 'action', 'type' => MS_Helper_Html::INPUT_TYPE_HIDDEN, 'value' => $this->data['action']), 'separator' => array('type' => MS_Helper_Html::TYPE_HTML_SEPARATOR), 'cancel' => array('id' => 'cancel', 'type' => MS_Helper_Html::TYPE_HTML_LINK, 'title' => __('Cancel', MS_TEXT_DOMAIN), 'value' => __('Cancel', MS_TEXT_DOMAIN), 'url' => remove_query_arg(array('action', 'invitation_id')), 'class' => 'wpmui-field-button button'), 'submit' => array('id' => 'submit', 'type' => MS_Helper_Html::INPUT_TYPE_SUBMIT, 'value' => __('Save Changes', MS_TEXT_DOMAIN)));
     return apply_filters('ms_addon_invitation_view_edit_prepare_fields', $fields, $this);
 }
 /**
  * Returns the effective date on which the specified item becomes available.
  *
  * @since  1.0.0
  *
  * @param string $item_id The content id to verify dripped access.
  * @param string $start_date The start date of the member membership.
  * @return string Date on which the item is revealed (e.g. '2015-02-16')
  */
 public function get_dripped_avail_date($item_id, $start_date = null)
 {
     $avail_date = MS_Helper_Period::current_date();
     $drip_data = false;
     if (!is_array($this->dripped)) {
         $this->dripped = array();
     }
     if (isset($this->dripped[$item_id])) {
         $drip_data = $this->dripped[$item_id];
     }
     if (is_array($drip_data)) {
         lib3()->array->equip($drip_data, 'type', 'date', 'delay_unit', 'delay_type');
         switch ($drip_data['type']) {
             case MS_Model_Rule::DRIPPED_TYPE_SPEC_DATE:
                 $avail_date = $drip_data['date'];
                 break;
             case MS_Model_Rule::DRIPPED_TYPE_FROM_REGISTRATION:
                 if (empty($start_date)) {
                     $start_date = MS_Helper_Period::current_date(null, false);
                 }
                 $period_unit = $drip_data['delay_unit'];
                 $period_type = $drip_data['delay_type'];
                 $avail_date = MS_Helper_Period::add_interval($period_unit, $period_type, $start_date);
                 break;
             case MS_Model_Rule::DRIPPED_TYPE_INSTANTLY:
             default:
                 $avail_date = MS_Helper_Period::current_date();
                 break;
         }
     }
     return apply_filters('ms_rule_get_dripped_avail_date', $avail_date, $item_id, $start_date, $this);
 }
 /**
  * Check for card expiration date.
  *
  * Save event for card expire soon.
  *
  * @since  1.0.0
  *
  * @access protected
  * @param MS_Model_Relationship $subscription The membership relationship.
  */
 public function check_card_expiration($subscription)
 {
     do_action('ms_gateway_check_card_expiration_before', $this);
     $member = MS_Factory::load('MS_Model_Member', $subscription->user_id);
     $card_exp = $member->get_gateway_profile($this->id, 'card_exp');
     if (!empty($card_exp)) {
         $comm = MS_Model_Communication::get_communication(MS_Model_Communication::COMM_TYPE_CREDIT_CARD_EXPIRE);
         $days = MS_Helper_Period::get_period_in_days($comm->period['period_unit'], $comm->period['period_type']);
         $card_expire_days = MS_Helper_Period::subtract_dates($card_exp, MS_Helper_Period::current_date(), DAY_IN_SECONDS, true);
         if ($card_expire_days < 0 || $days == $card_expire_days) {
             MS_Model_Event::save_event(MS_Model_Event::TYPE_CREDIT_CARD_EXPIRE, $subscription);
         }
     }
     do_action('ms_gateway_check_card_expiration_after', $this, $subscription);
 }
 public function column_due_date($item, $column_name)
 {
     $due_now = false;
     $is_paid = $item->is_paid();
     if (!$is_paid) {
         $diff = MS_Helper_Period::subtract_dates($item->due_date, MS_Helper_Period::current_date(), null, true);
         $due_now = $diff < 0;
     }
     $due_date = MS_Helper_Period::format_date($item->due_date);
     if ($due_now) {
         $html = sprintf('<span class="due-now" title="%2$s">%1$s</span>', $due_date, __('Payment is overdue', 'membership2'));
     } elseif ($item->pay_date) {
         $pay_date = MS_Helper_Period::format_date($item->pay_date, 'M j, Y');
         $html = sprintf('<span class="is-paid" title="%2$s">%1$s</span>', $due_date, sprintf(__('Paid: %s', 'membership2'), $pay_date));
     } else {
         $html = sprintf('<span>%1$s</span>', $due_date);
     }
     return $html;
 }
 public function column_due_date($item, $column_name)
 {
     $due_now = false;
     if (!$item->is_paid()) {
         $diff = MS_Helper_Period::subtract_dates($item->due_date, MS_Helper_Period::current_date(), null, true);
         $due_now = $diff < 0;
     }
     $date = MS_Helper_Period::format_date($item->due_date);
     if ($due_now) {
         $html = sprintf('<span class="due-now" title="%2$s">%1$s</span>', $date, __('Payment is overdue', MS_TEXT_DOMAIN));
     } else {
         $html = sprintf('<span>%1$s</span>', $date);
     }
     return $html;
 }
 /**
  * Refreshes the due-date of the invoice.
  *
  * @since  1.0.0
  */
 public function set_due_date()
 {
     // Never change due-date of paid invoices.
     if ($this->is_paid()) {
         return;
     }
     $subscription = $this->get_subscription();
     $due_date = false;
     // Handle special cases in due date calculation.
     switch ($subscription->status) {
         case MS_Model_Relationship::STATUS_TRIAL:
             $due_date = $subscription->trial_expire_date;
             break;
         case MS_Model_Relationship::STATUS_ACTIVE:
         case MS_Model_Relationship::STATUS_CANCELED:
             $due_date = $subscription->expire_date;
             break;
     }
     // Default due date is today.
     if (empty($due_date)) {
         if ($subscription->is_trial_eligible()) {
             /*
              * This invoice includes a trial period.
              * Payment is due on last day of trial
              */
             $due_date = $subscription->trial_expire_date;
         } else {
             // No trial period is used for this invoice. Due now.
             $due_date = MS_Helper_Period::current_date();
         }
     }
     // Update the trial expiration date.
     $this->trial_ends = $subscription->trial_expire_date;
     $this->due_date = $due_date;
 }
 /**
  * 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);
 }
    /**
     * Overrides parent's to_html() method.
     *
     * @since  1.0.0
     *
     * @return string
     */
    public function to_html()
    {
        $fields = $this->prepare_fields();
        $sim = $this->data['subscription'];
        $mem = $sim->get_membership();
        $pay_types = $mem->get_payment_types();
        if (is_admin()) {
            $toggle_icon = 'dashicons-arrow-down';
            $toggle_state = 'collapsed';
        } else {
            $toggle_icon = 'dashicons-arrow-up';
            $toggle_state = '';
        }
        $details = lib2()->session->get('ms-access');
        $denied_url = false;
        $deciding_membership = false;
        $deciding_rule = false;
        if (isset($details[1]) && !$details[1]['has_access']) {
            $denied_url = $details[1]['url'];
            $deciding_membership = $details[1]['deciding_membership'];
            $deciding_rule = $details[1]['deciding_rule'];
        } elseif (isset($details[0]) && $details[0]['has_access']) {
            $deciding_membership = $details[0]['deciding_membership'];
            $deciding_rule = $details[0]['deciding_rule'];
        }
        ob_start();
        $this->output_scripts();
        ?>
		<div class="ms-sim-info <?php 
        echo esc_attr($toggle_state);
        ?>
">
			<div class="ms-sim-block">
				<h4 class="toggle-wrap">
					<?php 
        _e('Simulation Overview', MS_TEXT_DOMAIN);
        ?>
					<span class="toggle"><i class="dashicons <?php 
        echo esc_attr($toggle_icon);
        ?>
"></i></span>
				</h4>
				<div class="ms-sim-body">
					<form id="view-site-as" method="POST" class="inside">
					<table cellspacing="0" cellpadding="0" width="100%" border="0">
						<tr>
							<th><?php 
        _e('View as', MS_TEXT_DOMAIN);
        ?>
</th>
							<td><?php 
        MS_Helper_Html::html_element($fields['membership_id']);
        ?>
</td>
						</tr>
						<?php 
        if ($this->data['datepicker']) {
            ?>
						<tr>
							<th><?php 
            _e('View on', MS_TEXT_DOMAIN);
            ?>
</th>
							<td><?php 
            MS_Helper_Html::html_element($fields['simulate_date']);
            ?>
</td>
						</tr>
						<?php 
        }
        ?>
						<tr>
							<th>&nbsp;</th>
							<td><button class="button"><?php 
        _e('Update', MS_TEXT_DOMAIN);
        ?>
</button></td>
						</tr>
					</table>
					<?php 
        MS_Helper_Html::html_element($fields['action_field']);
        MS_Helper_Html::html_element($fields['nonce_field']);
        ?>
					</form>

					<h4 class="inside">
						<?php 
        _e('Simulated Membership', MS_TEXT_DOMAIN);
        ?>
					</h4>
					<table cellspacing="0" cellpadding="0" width="100%" border="0" class="inside">
						<tr>
							<th><?php 
        _e('Membership', MS_TEXT_DOMAIN);
        ?>
</th>
							<td style="white-space: nowrap"><?php 
        echo esc_html($mem->name);
        ?>
</td>
						</tr>
						<tr>
							<th><?php 
        _e('Type', MS_TEXT_DOMAIN);
        ?>
</th>
							<td><?php 
        echo esc_html($mem->get_type_description());
        ?>
</td>
						</tr>
						<tr>
							<th><?php 
        _e('Start Date', MS_TEXT_DOMAIN);
        ?>
</th>
							<td><?php 
        echo esc_html($sim->start_date);
        ?>
</td>
						</tr>
						<tr>
							<th><?php 
        _e('Expire Date', MS_TEXT_DOMAIN);
        ?>
</th>
							<td><?php 
        echo esc_html($sim->expire_date);
        ?>
</td>
						</tr>
						<?php 
        if ($this->data['datepicker']) {
            ?>
						<tr>
							<th><?php 
            _e('Simulated Date', MS_TEXT_DOMAIN);
            ?>
</th>
							<td><?php 
            echo esc_html(MS_Helper_Period::current_date());
            ?>
</td>
						</tr>
						<?php 
        }
        ?>
						<tr>
							<th><?php 
        _e('Status', MS_TEXT_DOMAIN);
        ?>
</th>
							<td><?php 
        if (MS_Model_Relationship::STATUS_ACTIVE == $sim->status) {
            $status_class = 'ms-sim-active';
        } else {
            $status_class = 'ms-sim-inactive';
        }
        printf('<span class="%1$s">%2$s</span>', $status_class, $sim->status);
        ?>
</td>
						</tr>
						<tr>
							<th><?php 
        _e('Payment model', MS_TEXT_DOMAIN);
        ?>
</th>
							<td><?php 
        echo esc_html($pay_types[$mem->payment_type]);
        ?>
</td>
						</tr>
						<tr>
							<th><?php 
        _e('Payment details', MS_TEXT_DOMAIN);
        ?>
</th>
							<td><?php 
        echo esc_html(strip_tags($sim->get_payment_description(null, true)));
        ?>
</td>
						</tr>
					</table>
				</div>
				<div class="ms-sim-footer">
					<div class="inside">
					<?php 
        $this->output_deciding_info($denied_url, $deciding_membership, $deciding_rule);
        ?>
					</div>
					<?php 
        MS_Helper_Html::html_element($fields['exit_button']);
        ?>
				</div>
			</div>
		</div>
		<?php 
        $html = ob_get_clean();
        return apply_filters('ms_view_admin_bar_to_html', $html, $this);
    }
 /**
  * Prepare html fields.
  *
  * @since  1.0.0
  *
  * @return array
  */
 protected function prepare_fields()
 {
     $coupon = $this->data['coupon'];
     $fields = array('code' => array('id' => 'code', 'title' => __('Coupon code', 'membership2'), 'type' => MS_Helper_Html::INPUT_TYPE_TEXT, 'value' => $coupon->code, 'class' => 'widefat'), 'discount' => array('id' => 'discount', 'title' => __('Discount', 'membership2'), 'type' => MS_Helper_Html::INPUT_TYPE_NUMBER, 'value' => $coupon->discount, 'config' => array('step' => 'any', 'min' => 0)), 'discount_type' => array('id' => 'discount_type', 'title' => __('Discount Type', 'membership2'), 'type' => MS_Helper_Html::INPUT_TYPE_SELECT, 'field_options' => $coupon->get_discount_types(), 'value' => $coupon->discount_type), 'start_date' => array('id' => 'start_date', 'title' => __('Start date', 'membership2'), 'type' => MS_Helper_Html::INPUT_TYPE_DATEPICKER, 'value' => $coupon->start_date ? $coupon->start_date : MS_Helper_Period::current_date(), 'class' => 'ms-date'), 'expire_date' => array('id' => 'expire_date', 'title' => __('Expire date', 'membership2'), 'type' => MS_Helper_Html::INPUT_TYPE_DATEPICKER, 'value' => $coupon->expire_date, 'class' => 'ms-date'), 'membership_id' => array('id' => 'membership_id', 'title' => __('Coupon can be applied to these Memberships', 'membership2'), 'type' => MS_Helper_Html::INPUT_TYPE_CHECKBOX, 'field_options' => $this->data['memberships'], 'value' => $coupon->membership_id), 'max_uses' => array('id' => 'max_uses', 'title' => __('Max uses', 'membership2'), 'type' => MS_Helper_Html::INPUT_TYPE_NUMBER, 'value' => $coupon->max_uses, 'config' => array('step' => '1', 'min' => 0)), 'coupon_id' => array('id' => 'coupon_id', 'type' => MS_Helper_Html::INPUT_TYPE_HIDDEN, 'value' => $coupon->id), '_wpnonce' => array('id' => '_wpnonce', 'type' => MS_Helper_Html::INPUT_TYPE_HIDDEN, 'value' => wp_create_nonce($this->data['action'])), 'action' => array('id' => 'action', 'type' => MS_Helper_Html::INPUT_TYPE_HIDDEN, 'value' => $this->data['action']), 'separator' => array('type' => MS_Helper_Html::TYPE_HTML_SEPARATOR), 'cancel' => array('id' => 'cancel', 'type' => MS_Helper_Html::TYPE_HTML_LINK, 'title' => __('Cancel', 'membership2'), 'value' => __('Cancel', 'membership2'), 'url' => esc_url_raw(remove_query_arg(array('action', 'coupon_id'))), 'class' => 'wpmui-field-button button'), 'submit' => array('id' => 'submit', 'type' => MS_Helper_Html::INPUT_TYPE_SUBMIT, 'value' => __('Save Changes', 'membership2')));
     return apply_filters('ms_addon_coupon_view_edit_prepare_fields', $fields, $this);
 }
 /**
  * Returns property associated with the render.
  *
  * @since  1.0.0
  *
  * @param  string $property The name of a property.
  * @return mixed Returns mixed value of a property or NULL if a property doesn't exist.
  */
 public function __get($property)
 {
     $value = null;
     if (property_exists($this, $property)) {
         switch ($property) {
             case 'date':
                 if (empty($this->date)) {
                     $this->date = MS_Helper_Period::current_date();
                 }
                 $value = $this->date;
                 break;
             default:
                 $value = $this->{$property};
                 break;
         }
     }
     return apply_filters('ms_model_simulate__get', $value, $property, $this);
 }
 /**
  * Verify if a event was already created in the same day.
  *
  * @since  1.0.0
  *
  * @param MS_Model_Event $event The event to verify.
  * @param mixed $data The additional data.
  */
 public static function is_duplicate($event, $data)
 {
     $is_duplicate = false;
     $check_events = apply_filters('ms_model_event_is_duplicate_check_events', array(self::TYPE_MS_BEFORE_TRIAL_FINISHES, self::TYPE_MS_BEFORE_FINISHES, self::TYPE_MS_AFTER_FINISHES, self::TYPE_CREDIT_CARD_EXPIRE, self::TYPE_PAYMENT_BEFORE_DUE, self::TYPE_PAYMENT_AFTER_DUE));
     if (in_array($event->type, $check_events) && ($last_event = self::get_last_event_of_type($event))) {
         $event_date = gmdate(MS_Helper_Period::PERIOD_FORMAT, strtotime($last_event->date));
         if ($event_date === MS_Helper_Period::current_date()) {
             $is_duplicate = true;
         }
     }
     return apply_filters('ms_model_event_is_duplicate', $is_duplicate, $event, $data);
 }
 /**
  * Test changing the membership payment plan from permanent to recurring.
  * @test
  */
 function permanent_to_recurring()
 {
     $user_id = TData::id('user', 'editor');
     $membership_id = TData::id('membership', 'simple');
     $subscription = TData::subscribe($user_id, $membership_id);
     $invoice = $subscription->get_current_invoice();
     $invoice->pay_it('stripe', 'external_123');
     // Now we have a user that is subscribed to a permanent membership.
     $start_date = MS_Helper_Period::current_date();
     $this->assertEquals($start_date, $subscription->start_date);
     $this->assertEquals('', $subscription->expire_date);
     $this->assertTrue($invoice->is_paid());
     $this->assertEquals('active', $subscription->status);
     // This check should not modify the subscription.
     $subscription->check_membership_status();
     $this->assertEquals($start_date, $subscription->start_date);
     $this->assertEquals('', $subscription->expire_date);
     $this->assertTrue($invoice->is_paid());
     $this->assertEquals('active', $subscription->status);
     // Now the user changes the membership to recurring.
     $membership = $subscription->get_membership();
     $membership->payment_type = MS_Model_Membership::PAYMENT_TYPE_RECURRING;
     $membership->pay_cycle_period_unit = 7;
     $membership->pay_cycle_period_type = 'days';
     $membership->save();
     $this->assertEquals(MS_Model_Membership::PAYMENT_TYPE_RECURRING, $membership->payment_type);
     // The membership status check is automaticaly done every six hours.
     // It will update the subscription details to match the new payment type.
     $subscription->check_membership_status();
     // Confirm that the existing subscription has a correct expire date.
     $expire_date = MS_Helper_Period::add_interval(7, 'days', $start_date);
     $this->assertEquals($expire_date, $subscription->expire_date);
 }