Skip to content

Instantly share code, notes, and snippets.

@wpmudev-sls
Created May 28, 2019 19:12
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/f2a3bb4c3ef9f3289d91386bb2b326e5 to your computer and use it in GitHub Desktop.
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.
<?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