Skip to content

Instantly share code, notes, and snippets.

@wpmudev-sls
Last active May 24, 2019 06:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wpmudev-sls/351aaa686d6ce8f8b3fd35f9ac8418e1 to your computer and use it in GitHub Desktop.
Save wpmudev-sls/351aaa686d6ce8f8b3fd35f9ac8418e1 to your computer and use it in GitHub Desktop.
[Membership] - Override Cron Status Check
<?php
/**
* Plugin Name: [Membership] - Override Cron Status Check
* Plugin URI: https://premium.wpmudev.org/
* Description: Override Cron Status Check
* Author: Panos Lyrakis @ WPMUDEV
* Author URI: https://premium.wpmudev.org/
* License: GPLv2 or later
*/
// NOTE :
// At this point we only care about setting the db status to expired where required.
// We skip the rest cases so they are handled by the `check_membership_status()` method
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'WPMUDEV_MS_Cron_Status_Check' ) ) {
class WPMUDEV_MS_Cron_Status_Check {
private static $_instance = null;
private $transaction_type = 'ms_transaction_log';
public static function get_instance() {
if( is_null( self::$_instance ) ){
self::$_instance = new WPMUDEV_MS_Cron_Status_Check();
}
return self::$_instance;
}
private function __construct() {
add_filter( 'ms_model_relationship_skip_membership_status_check', array( $this, 'subscription_status_check' ), 20, 2 );
}
/*
* This method checks purely the expiration date based on last transaction log.
* It does not check the invoice dates
* It creates an invoice only if subscription gets expired and there is no current invoice
*/
public function subscription_status_check( $skip, $subscription ) {
if ( $subscription->is_trial_eligible()
&& strtotime( $subscription->trial_expire_date ) >= strtotime( MS_Helper_Period::current_date() )
) {
// Still on trial. Lets continue with normal Cron check
return $skip;
}
/**
* TODO:
* We can set the STATUS_TRIAL_EXPIRED status temporarily if is_trial_eligible and trial_expire_date has passed.
*/
if ( empty( $subscription->expire_date ) ) {
// If there is no expiration date, subscription should be set to active.
// This can be handled by the Cron check
return $skip;
}
$subscription_current_status = get_post_meta( $subscription->id, 'status', true );
$subscription_next_status = '';
$subscription_expiration_date = $subscription->expire_date;;
if ( 'admin' != $subscription->gateway_id && 'free' != $subscription->gateway_id ) {
$payment = $this->get_subscription_last_payment( $subscription );
if ( ! $payment || empty( $payment ) ){
return $skip;
}
$last_payment_date = $payment->date;
$subscription_expiration_date = $this->get_subscription_expiration_date( $subscription, $last_payment_date );
}
if ( strtotime( $subscription_expiration_date ) >= strtotime( MS_Helper_Period::current_date() ) ) {
//Should be set to active
$subscription_next_status = MS_Model_Relationship::STATUS_ACTIVE;
}
else {
// if current status is MS_Model_Relationship::STATUS_PENDING, it should ermain like that else
//should be set to expired
if ( MS_Model_Relationship::STATUS_PENDING == $subscription->status ) {
$subscription_next_status = MS_Model_Relationship::STATUS_PENDING;
}
else {
$subscription_next_status = MS_Model_Relationship::STATUS_EXPIRED;
$this->set_status( $subscription, $subscription_next_status );
return true;
}
}
//$this->set_status( $subscription, $subscription_next_status );
//switch( $subscription->status ) {
//}
/**
* Filter documented in class-ms-model-relationship.php
*/
/*
do_action(
'ms_relationship_status_check_communication',
$subscription_next_status,
$days,
$membership,
$subscription,
false
);
*/
//return true;
// It is better/safer to just to skip as at this point we have set all the expired ones.
return $skip;
}
private function maybe_move_membership( $subscription, $membership ) {
// Do not continue if on_end_membership_id is empty.
if ( empty( $membership->on_end_membership_id ) ) {
return;
}
// Deactivate the current membership.
$subscription->deactivate_membership();
// Move membership to configured 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', $subscription->user_id );
$new_subscription = $member->add_membership(
$membership->on_end_membership_id,
$subscription->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 its free we set it as active
*/
if ( ! $new_membership->is_free() ) {
$new_subscription->status = MS_Model_Relationship::STATUS_PENDING;
} else {
$new_subscription->status = MS_Model_Relationship::STATUS_ACTIVE;
}
// Save new membership.
$new_subscription->save();
}
}
private function set_status( $subscription, $status ) {
update_post_meta( $subscription->id, 'status', $status );
if ( MS_Model_Relationship::STATUS_EXPIRED == $status ) {
// Since this subscription is expired, lets check if we need to move membership:
$membership = $subscription->get_membership();
if ( ! empty( $membership->on_end_membership_id ) ) {
$this->maybe_move_membership( $subscription, $membership );
}
}
}
public function get_subscription_last_payment( $subscription ) {
$transaction = $this->get_subscription_last_transaction( $subscription->id );
if ( ! $transaction || empty( $transaction ) ) {
return false;
}
return $this->payment_from_transaction( $transaction );
}
public function get_subscription_last_transaction( $subscription_id ) {
if ( is_object( $subscription_id ) ) {
if ( ! isset( $subscription_id->id ) ) {
return false;
}
$subscription_id = $subscription_id->id;
}
$transaction = array();
$args = array(
'numberposts' => 1,
'offset' => 0,
'post_status' => 'any', //'private', // transaction logs have private status in posts table
'post_type' => 'ms_transaction_log',
'meta_query' => array(
array(
'key' => 'subscription_id',
'value' => $subscription_id,
'compare' => '=',
),
array(
'key' => 'success',
'value' => 'ok',
'compare' => '='
)
)
);
$transactions = get_posts( $args );
if ( ! empty( $transactions ) ) {
return $transactions[0];
}
else {
return false;
}
}
// This returns the required fields of the transaction.
public function payment_from_transaction( $transaction ) {
$payment = array();
if ( ! $transaction instanceof WP_Post || 'ms_transaction_log' != $transaction->post_type ) {
return $payment;
}
$payment = array(
'id' => $transaction->ID,
'date' => $transaction->post_date
);
/*
// Currently we don't need to use transaction meta
$meta = get_post_meta( $transaction->ID );
foreach ( $meta as $meta_key => $meta_value ) {
if ( isset( $meta_value[0] ) && ! isset( $payment[ $meta_key ] ) ) {
$payment[ $meta_key ] = $meta_value[0];
}
}
*/
return (object) $payment;
}
public function get_subscription_expiration_date( $subscription, $last_payment_date ) {
$grace_period = apply_filters(
'ms_subscription_expiration_grace_period',
1,
$subscription
);
$period_duration = $this->get_subscription_duration( $subscription );
$expiration_date = date( 'Y-m-d H:i:s', strtotime( $last_payment_date . "+{$period_duration->period_unit} {$period_duration->period_type}" ) );
return date( 'Y-m-d H:i:s', strtotime( $expiration_date . "+{$grace_period} days" ) );
}
public function get_subscription_duration( $subscription ) {
if ( ! $subscription instanceof MS_Model_Relationship ) {
return false;
}
return (object) MS_Factory::load(
'MS_Model_Membership',
$subscription->membership_id
)->period;
}
}
if ( ! function_exists( 'wpmudev_ms_cron_status_check' ) ) {
function wpmudev_ms_cron_status_check(){
return WPMUDEV_MS_Cron_Status_Check::get_instance();
};
add_action( 'plugins_loaded', 'wpmudev_ms_cron_status_check', 10 );
}
}
@wpmudev-sls
Copy link
Author

Requires to add the following filter at the beginning of MS_Model_Relationship::check_membership_status


		if ( apply_filters( 'ms_model_relationship_skip_membership_status_check', false, $this ) ) {
			return;
		}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment