/** * Calculate the membership status. * * Calculate status for the membership verifying the start date, * trial exire date and expire date. * * @since 1.0.0 * @internal * * @param string $set_status The set status to compare. * @return string The calculated status. */ protected function calculate_status($set_status = null, $debug = false) { /** * Documented in check_membership_status() * * @since 1.0.0 */ if (MS_Plugin::get_modifier('MS_LOCK_SUBSCRIPTIONS')) { return $set_status; } $membership = $this->get_membership(); $calc_status = null; $debug_msg = array(); $check_trial = $this->is_trial_eligible(); if (!empty($this->payments)) { /* * The user already paid for this membership, so don't check for * trial status anymore */ $check_trial = false; } // If the start-date is not reached yet, then set membership to Pending. if (!$calc_status && !empty($this->start_date) && strtotime($this->start_date) > strtotime(MS_Helper_Period::current_date())) { $calc_status = self::STATUS_WAITING; $debug_msg[] = '[WAITING: Start-date not reached]'; } elseif (!$calc_status && $debug) { $debug_msg[] = '[Not WAITING: No start-date or start-date reached]'; } if ($check_trial) { if (!$calc_status && strtotime($this->trial_expire_date) >= strtotime(MS_Helper_Period::current_date())) { $calc_status = self::STATUS_TRIAL; $debug_msg[] = '[TRIAL: Trial-Expire date not reached]'; } elseif (!$calc_status && $debug) { $debug_msg[] = '[Not TRIAL: Trial-Expire date reached]'; } if (!$calc_status && strtotime($this->trial_expire_date) < strtotime(MS_Helper_Period::current_date())) { $calc_status = self::STATUS_TRIAL_EXPIRED; $debug_msg[] = '[TRIAL-EXPIRED: Trial-Expire date reached]'; } elseif (!$calc_status && $debug) { $debug_msg[] = '[Not TRIAL-EXPIRED: Trial-Expire date not reached]'; } } elseif (!$calc_status && $debug) { $debug_msg[] = '[Skipped TRIAL status]'; } // Status an only become active when added by admin or invoice is paid. $can_activate = false; if ('admin' == $this->gateway_id) { $can_activate = true; $debug_msg[] = '[Can activate: Admin gateway]'; } elseif ($membership->is_free()) { $can_activate = true; $debug_msg[] = '[Can activate: Free membership]'; } elseif (!empty($this->source)) { $can_activate = true; $debug_msg[] = '[Can activate: Imported subscription]'; } else { $valid_payment = false; // Check if there is *any* payment, no matter what height. foreach ($this->get_payments() as $payment) { if ($payment['amount'] > 0) { $valid_payment = true; $debug_msg[] = '[Can activate: Payment found]'; break; } } if (!$valid_payment) { // Check if any invoice was paid already. for ($ind = $this->current_invoice_number; $ind > 0; $ind -= 1) { $invoice = MS_Model_Invoice::get_invoice($this->id, $ind); if (!$invoice) { continue; } if ($invoice->uses_trial) { continue; } if ($invoice->is_paid()) { $valid_payment = true; $debug_msg[] = '[Can activate: Paid invoice found]'; break; } } } if (!$valid_payment) { // Check if the current invoice is free. $invoice = $this->get_current_invoice(); if (0 == $invoice->total) { $valid_payment = true; } } if ($valid_payment) { $can_activate = true; } if (!$can_activate && $debug) { $debug_msg[] = sprintf('[Can not activate: Gateway: %s; Price: %s; Invoice: %s]', $this->gateway_id, $membership->price, $invoice->total); } } if ($can_activate) { // Permanent memberships grant instant access, no matter what. if (!$calc_status && MS_Model_Membership::PAYMENT_TYPE_PERMANENT == $membership->payment_type) { $calc_status = self::STATUS_ACTIVE; $debug_msg[] = '[ACTIVE(1): Payment-type is permanent]'; } elseif (!$calc_status && $debug) { $debug_msg[] = '[Not ACTIVE(1): Payment-type is not permanent]'; } // If expire date is empty and Active-state is requests then use active. if (!$calc_status && empty($this->expire_date) && self::STATUS_ACTIVE == $set_status) { $calc_status = self::STATUS_ACTIVE; $debug_msg[] = '[ACTIVE(2): Expire date empty and active requested]'; } elseif (!$calc_status && $debug) { $debug_msg[] = '[Not ACTIVE(2): Expire date set or wrong status-request]'; } // If expire date is not reached then membership obviously is active. if (!$calc_status && !empty($this->expire_date) && strtotime($this->expire_date) >= strtotime(MS_Helper_Period::current_date())) { $calc_status = self::STATUS_ACTIVE; $debug_msg[] = '[ACTIVE(3): Expire date set and not reached]'; } elseif (!$calc_status && $debug) { $debug_msg[] = '[Not ACTIVE(3): Expire date set and reached]'; } } elseif (!$calc_status && self::STATUS_PENDING == $this->status) { // Invoice is not paid yet. $calc_status = self::STATUS_PENDING; $debug_msg[] = '[PENDING: Cannot activate pending subscription]'; } elseif (!$calc_status && $debug) { $debug_msg[] = '[Not ACTIVE/PENDING: Cannot activate subscription]'; } // If no other condition was true then the expire date was reached. if (!$calc_status) { $calc_status = self::STATUS_EXPIRED; $debug_msg[] = '[EXPIRED: Default status]'; } // Did the user cancel the membership? $cancel_it = self::STATUS_CANCELED == $set_status || self::STATUS_CANCELED == $this->status && self::STATUS_ACTIVE != $set_status && self::STATUS_TRIAL != $set_status; if ($cancel_it) { /* * When a membership is cancelled then it will stay "Cancelled" * until the expiration date is reached. A user has access to the * contents of a cancelled membership until it expired. */ if (self::STATUS_EXPIRED == $calc_status) { // Membership has expired. Finally deactivate it! // (possibly it was cancelled a few days earlier) $calc_status = self::STATUS_DEACTIVATED; } elseif (self::STATUS_TRIAL_EXPIRED == $calc_status) { // Trial period has expired. Finally deactivate it! $calc_status = self::STATUS_DEACTIVATED; } elseif (self::STATUS_TRIAL == $calc_status) { // User can keep access until trial period finishes... $calc_status = self::STATUS_CANCELED; } elseif (MS_Model_Membership::PAYMENT_TYPE_PERMANENT == $membership->payment_type) { // This membership has no expiration-time. Deactivate it! $calc_status = self::STATUS_DEACTIVATED; } elseif (self::STATUS_WAITING == $calc_status) { // The membership did not yet start. Deactivate it! $calc_status = self::STATUS_DEACTIVATED; } elseif (!$this->expire_date) { // Membership without expire date cannot be cancelled. Deactivate it! $calc_status = self::STATUS_DEACTIVATED; } else { // Wait until the expiration date is reached... $calc_status = self::STATUS_CANCELED; } } if ($debug) { // Intended debug output, leave it here. lib3()->debug->dump($debug_msg); } return apply_filters('membership_model_relationship_calculate_status', $calc_status, $this); }