/** * 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> </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); }