Created
May 28, 2019 19:12
-
-
Save wpmudev-sls/f2a3bb4c3ef9f3289d91386bb2b326e5 to your computer and use it in GitHub Desktop.
[Affiliates - M2 Add on] - Delay on Payment Balance. Delays the balance to show up in affiliate's admin page.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Plugin Name: [Affiliates - M2 Add on] - Delay on Payment Balance | |
* Plugin URI: https://premium.wpmudev.org/ | |
* Description: Delays the balance to show up in affiliates admin page. | |
* Author: Panos Lyrakis @ WPMUDEV | |
* Author URI: https://premium.wpmudev.org/ | |
* License: GPLv2 or later | |
*/ | |
if ( ! defined( 'ABSPATH' ) ) { | |
exit; | |
} | |
if ( ! class_exists( 'WPMUDEV_Aff_MS_Balance_Delay' ) ) { | |
class WPMUDEV_Aff_MS_Balance_Delay { | |
private static $_instance = null; | |
private static $delay_days = 30; | |
private static $option_name = '_wpmudev_aff_pending_balance_items_list'; | |
private static $schedule_hook = 'wpmudev_aff_pending_balance_scheduled_check'; | |
const AREA_KEY = 'paid:membership2'; | |
public static function get_instance() { | |
if( is_null( self::$_instance ) ){ | |
self::$_instance = new WPMUDEV_Aff_MS_Balance_Delay(); | |
} | |
return self::$_instance; | |
} | |
private function __construct() { | |
add_action( 'ms_invoice_paid', array( $this, 'remove_default_action' ), 1, 2 ); | |
add_action( self::$schedule_hook,array( $this, 'schedule_pending_balances' ) ); | |
} | |
public function remove_default_action( $invoice, $subscription ) { | |
global $wp_filter; | |
$tag = 'ms_invoice_paid'; | |
$hook = 'payment_processed'; | |
$hook_class = 'Affiliate_Membership2_Integration'; | |
foreach ( $wp_filter[$tag]->callbacks as $key => $callback_array ) { | |
foreach ( $callback_array as $c_key => $callback ) { | |
if ( substr_compare( $c_key, $hook, strlen( $c_key )-strlen( $hook ), strlen( $hook ) ) === 0 ) { | |
if ( $callback['function'][0] instanceof $hook_class ){ | |
unset( $wp_filter[$tag]->callbacks[$key][$c_key] ); | |
$referrer_id = get_current_user_id(); | |
$invoice_id = $invoice->id; | |
$subscription_id = $subscription->id; | |
$this->push_balance_to_list( $referrer_id, $invoice_id, $subscription_id ); | |
} | |
} | |
} | |
} | |
} | |
public function push_balance_to_list( $referrer_id, $invoice_id, $subscription_id ) { | |
$pending_items_listed = get_option( self::$option_name, array() ); | |
$pending_items_listed[] = array( | |
'date' => current_time( 'timestamp' ), | |
'referrer_id' => $referrer_id, | |
'invoice_id' => $invoice_id, | |
'subscription_id' => $subscription_id | |
); | |
update_option( self::$option_name, $pending_items_listed ); | |
$this->maybe_set_schedule(); | |
} | |
public function schedule_pending_balances() { | |
if ( ! class_exists( 'MS_Factory' ) || ! class_exists( 'Affiliate_Membership2_Integration' ) ) { | |
return; | |
} | |
$now = new DateTime( date( 'Y-m-d H:i:s', current_time( 'timestamp' ) ) ); | |
$pending_items_listed = get_option( self::$option_name, array() ); | |
if ( ! empty( $pending_items_listed ) ) { | |
foreach ( $pending_items_listed as $key => $item ) { | |
$date_paid = new DateTime( date( 'Y-m-d H:i:s', $item['date'] ) ); | |
if ( self::$delay_days <= $date_paid->diff( $now )->days ) { | |
$invoice = MS_Factory::load( 'MS_Model_Invoice', (int)$item['invoice_id'] ); | |
$subscription = MS_Factory::load( 'MS_Model_Relationship', (int)$item['subscription_id'] ); | |
$this->payment_processed( $invoice, $subscription ); | |
unset( $pending_items_listed[$key] ); | |
} | |
} | |
update_option( self::$option_name, $pending_items_listed ); | |
} | |
} | |
public function payment_processed( $invoice, $subscription ) { | |
global $affiliate; // Used for communication with Affiliates plugin. | |
global $blog_id, $site_id; // Used for logging. | |
// Don't pay a commission if the membership is not active. | |
if ( $subscription->status != $subscription::STATUS_ACTIVE ) { | |
return; | |
} | |
$user_id = $invoice->user_id; | |
$membership = $subscription->get_membership(); | |
$pay_once = defined( 'AFFILIATE_PAYONCE' ) && 'yes' == AFFILIATE_PAYONCE; | |
$user_id_referrer = get_user_meta( $user_id, 'affiliate_referred_by', true ); | |
if ( empty( $user_id_referrer ) ) { | |
// We do not know who referred the user, don't pay a commission. | |
return; | |
} | |
$affiliate_paid = get_user_meta( $user_id, 'affiliate_paid', true ); | |
if ( $pay_once && 'yes' == $affiliate_paid ) { | |
// The referrer already got a one-time commission, don't pay again. | |
return; | |
} | |
$complete_records = $affiliate->get_complete_records( | |
$user_id_referrer, | |
date( 'Ym' ), | |
array( self::AREA_KEY ), | |
$user_id | |
); | |
if ( $pay_once && is_array( $complete_records ) ) { | |
// Make sure that this subscription was not commissioned before. | |
foreach ( $complete_records as $record ) { | |
$meta = maybe_unserialize( $record->meta ); | |
if ( $meta['subscription_id'] == $subscription->id ) { | |
// It seems this subscription was already commissioned. | |
return; | |
} | |
} | |
} | |
// Okay, the referrer is entitiled to the commission! | |
/* | |
* Reward is the money that the user receives. | |
* It is stored in cents/milli-percent. | |
* I.e. '100' $ -> 1.00 $ and '100' % -> 1.00 % | |
*/ | |
$reward = $this->get_value( $membership ); | |
$type = $this->get_type( $membership ); | |
switch ( $type ) { | |
case 'inv': | |
$base = $invoice->subtotal; // Invoice amount without taxes. | |
$reward = $base * $reward / 100; | |
break; | |
case 'mem': | |
$base = $membership->price; // Membership price setting. | |
$reward = $base * $reward / 100; | |
break; | |
case 'abs': | |
default: | |
// Reward already has correct value. | |
break; | |
} | |
$reward = round( $reward, 2, PHP_ROUND_HALF_DOWN ); | |
// Note: lib2() used here is provided by the Membership2 plugin. | |
$meta = array( | |
'subscription_id' => $subscription->id, | |
'invoice_id' => $invoice->id, | |
'gateway_id' => $invoice->gateway_id, | |
'transaction_id' => $invoice->external_id, | |
'blog_id' => $blog_id, | |
'site_id' => $site_id, | |
'current_user_id' => get_current_user_id(), | |
'REMOTE_URL' => $_SERVER['HTTP_REFERER'], | |
'LOCAL_URL' => mslib3()->net->current_url(), | |
'IP' => mslib3()->net->current_ip()->ip, | |
); | |
$affiliate_process_payment = apply_filters( 'affiliate_process_payment', true, $user_id_referrer, $reward, $user_id, $meta ); | |
if ( ! $affiliate_process_payment ) return; | |
do_action( | |
'affiliate_purchase', | |
$user_id_referrer, | |
$reward, | |
self::AREA_KEY, | |
$user_id, | |
__( 'Membership2', 'affiliate' ), | |
$meta | |
); | |
if ( $pay_once ) { | |
update_user_meta( $user_id, 'affiliate_paid', 'yes' ); | |
} | |
} | |
protected function get_value( $membership ) { | |
$reward = $membership->get_custom_data( 'aff_reward_value' ); | |
$reward = max( 0, intval( $reward ) ); | |
$reward = (float) $reward / 100; | |
return $reward; | |
} | |
protected function get_type( $membership ) { | |
$available_types = array( 'inv', 'mem', 'abs' ); | |
$type = $membership->get_custom_data( 'aff_reward_type' ); | |
if ( ! in_array( $type, $available_types ) ) { | |
$type = 'abs'; | |
} | |
return $type; | |
} | |
public function maybe_set_schedule() { | |
if ( ! wp_next_scheduled( self::$schedule_hook ) ) { | |
wp_schedule_event( current_time( 'timestamp' ), 'daily', self::$schedule_hook ); | |
} | |
} | |
} | |
if ( ! function_exists( 'wpmudev_aff_ms_balance_delay' ) ) { | |
function wpmudev_aff_ms_balance_delay(){ | |
return WPMUDEV_Aff_MS_Balance_Delay::get_instance(); | |
}; | |
add_action( 'plugins_loaded', 'wpmudev_aff_ms_balance_delay', 10 ); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment