settings = Data::instance();
$this->query = QueryDB::instance();
add_shortcode( 'affi_my_affiliate_account', [ $this, 'affi_my_affiliate_account' ] );
// add_action( 'init', [ $this, 'init_endpoints' ] );
add_action( 'init', [ $this, 'tracking_visits' ] );
if ( $this->settings->get_param( 'share_link_button' ) ) {
add_filter( 'woocommerce_loop_add_to_cart_link', array(
$this,
'woocommerce_loop_add_to_cart_link',
), 99, 2 );
add_action( 'woocommerce_after_add_to_cart_form', array( $this, 'woocommerce_after_add_to_cart_form' ) );
}
if ( $this->settings->get_param( 'payment_request' ) ) {
add_action( 'wp_ajax_affi_user_request_payout', [ $this, 'affi_user_request_payout' ] );
}
/*Add AFFI to menu my account page*/
add_filter( 'woocommerce_get_query_vars', array( $this, 'affi_woocommerce_get_query_vars' ), PHP_INT_MAX, 1 );
add_action( 'woocommerce_account_affi-affiliate_endpoint', array( $this, 'affi_show_function_my_account' ), PHP_INT_MAX, 1 );
if ( $this->settings->get_param( 'dashboard_account' ) ) {
$c_user_id = get_current_user_id();
$c_active_aff = false;
if ( $c_user_id ) {
$c_affiliate_data = $this->query->get_affiliate_by_user_id( $c_user_id );
if ( $c_affiliate_data && isset( $c_affiliate_data['status'] ) && 'approved' == $c_affiliate_data['status'] ) {
$c_active_aff = true;
}
}
if ( $c_active_aff ) {
// add_action( 'init', array( $this, 'affi_register_new_endpoint_my_account' ) );
add_filter( 'woocommerce_account_menu_items', array( $this, 'affi_add_link_to_my_account_menu' ), PHP_INT_MAX, 1 );
}
}
add_action( 'wp_ajax_affi_account_user_update_payment', [ $this, 'affi_account_user_update_payment' ] );
// add_action( 'wp_ajax_affi_account_payout_list', [ $this, 'affi_account_payout_list' ] );
add_action( 'wp_ajax_affi_user_get_notification_detail', [ $this, 'affi_user_get_notification_detail' ] );
add_action( 'wp_ajax_affi_filter_products', [ $this, 'affi_filter_products' ] );
// $baseAffiliate = new BaseAffiliate();
$referralsOrder = new ReferralsOrder();
}
public function affi_woocommerce_get_query_vars( $query ) {
$query['affi-affiliate'] = 'affi-affiliate';
return $query;
}
public function affi_add_link_to_my_account_menu( $items ) {
$items['affi-affiliate'] = esc_html__( 'AFFI Affiliate', 'affi-affiliate-marketing-for-woo' );
return $items;
}
/* public function affi_register_new_endpoint_my_account() {
$structure = get_option( 'permalink_structure' );
if ( $structure !== '/%postname%/' ) {
global $wp_rewrite;
$wp_rewrite->set_permalink_structure( '/%postname%/' );
add_rewrite_endpoint( 'affi-affiliate', EP_PAGES );
// $wp_rewrite->set_permalink_structure( $structure );
} else {
add_rewrite_endpoint( 'affi-affiliate', EP_PAGES );
}
}*/
function affi_show_function_my_account() {
echo do_shortcode( '[affi_my_affiliate_account]' );
}
public function affi_my_affiliate_account( $params ) {
ob_start();
$atts = shortcode_atts( [
'is_my_account' => false,
'payout_per_page' => '',
'transaction_per_page' => ''
], $params );
villatheme_get_template(
"my-account.php",
[
'is_my_account' => $atts['is_my_account'],
'payout_per_page' => $atts['payout_per_page'],
'transaction_per_page' => $atts['transaction_per_page'],
],
'',
AffiEnv::get( 'templates_dir' ) . 'my-account/'
);
self::shortcode_enqueue_script();
return ob_get_clean();
}
public function shortcode_enqueue_script() {
$suffix = defined( 'WP_DEBUG' ) && WP_DEBUG ? '' : '.min';
wp_register_style( 'affi-affi_my_affiliate_account-style', AffiEnv::get( 'css_url' ) . 'affi_my_affiliate_account' . $suffix . '.css', '', AffiEnv::get( 'version' ) );
wp_register_style( 'affi-affi-account-icon', AffiEnv::get( 'libs_url' ) . 'affi-icon.min.css', '', AffiEnv::get( 'version' ) );
wp_enqueue_style( 'affi-affi_my_affiliate_account-style', AffiEnv::get( 'css_url' ) . 'affi_my_affiliate_account' . $suffix . '.css', '', AffiEnv::get( 'version' ) );
wp_enqueue_style( 'affi-affi-account-icon', AffiEnv::get( 'libs_url' ) . 'affi-icon.min.css', '', AffiEnv::get( 'version' ) );
wp_enqueue_script( 'affi_my_affiliate_account', AffiEnv::get( 'js_url' ) . 'affi_my_affiliate_account' . $suffix . '.js', '', AffiEnv::get( 'version' ), true );// phpcs:ignore WordPress.WP.EnqueuedResourceParameters.NotInFooter
wp_enqueue_script( 'affi-chart', AffiEnv::get( 'libs_url' ) . 'chart.min.js', '', '4.4.1', true );// phpcs:ignore WordPress.WP.EnqueuedResourceParameters.NotInFooter
$localize = [
'ajaxUrl' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce( 'affi_security' ),
'isRTL' => is_rtl(),
'currency' => get_woocommerce_currency_symbol(),
'total_text' => esc_html__( 'Total', 'affi-affiliate-marketing-for-woo' ),
'time_text' => esc_html__( 'Time', 'affi-affiliate-marketing-for-woo' ),
'visit' => esc_html__( 'Visit', 'affi-affiliate-marketing-for-woo' ),
'count' => esc_html__( 'Order count', 'affi-affiliate-marketing-for-woo' ),
'total' => esc_html__( 'Order total', 'affi-affiliate-marketing-for-woo' ),
'o_balance' => esc_html__( 'Outstanding balance', 'affi-affiliate-marketing-for-woo' ),
'balance' => esc_html__( 'Balance', 'affi-affiliate-marketing-for-woo' ),
't_count' => esc_html__( 'Count', 'affi-affiliate-marketing-for-woo' ),
't_value' => esc_html__( 'Value', 'affi-affiliate-marketing-for-woo' ),
];
wp_localize_script( 'affi_my_affiliate_account', 'affiParams', $localize );
}
public function get_endpoints() {
return apply_filters( 'affi_affiliate_endpoints', [
'my-affiliate-account' => 'my-affiliate-account'
] );
}
public function tracking_visits() {
$tracking_object = new TrackingVisits();
}
public function init_endpoints() {
// $endpoints = $this->get_endpoints();
// global $wp_rewrite;
// $wp_rewrite->set_permalink_structure( '/%postname%/' );
//
// if ( ! empty( $endpoints ) && is_array( $endpoints ) ) {
// foreach ( $endpoints as $ep_k => $endpoint ) {
// if ( ! empty( $endpoint ) ) {
// add_rewrite_endpoint( $endpoint, EP_PERMALINK | EP_PAGES );
// }
// }
// }
}
public function woocommerce_loop_add_to_cart_link( $html, $product ) {
if ( ! $product ) {
return $html;
}
$aff_param = self::get_affiliate_params();
if ( ! $aff_param ) {
return $html;
}
$product_link = $product->get_permalink();
$product_link_param = add_query_arg( $this->settings->get_param( 'base_prefix' ), $aff_param, $product_link );
ob_start();
?>
isset( $class ) ? $class : '',
'affi_link' => $product_link_param,
'affi_text' => $this->settings->get_param( 'share_button_text' ),
'affi_copy' => esc_html__( 'Copied', 'affi-affiliate-marketing-for-woo' ),
], '', AffiEnv::get( 'templates_dir' ) );
if ( $this->settings->get_param( 'enable_loop_product' ) ) {
$social_share_enable = $this->settings->get_param( 'social_share' ) ?? [];
$social_share_prefix_url = $this->settings->get_social_prefix_url();
?>
$social_url . urlencode( $product_link_param ),
'affi_product_url' => $product_link,
'affi_class_icon' => 'social_' . $share_icon,
], '', AffiEnv::get( 'templates_dir' ) );
}
}
?>
ID;
$product = wc_get_product( $product_id );
$aff_param = self::get_affiliate_params();
if ( ! $aff_param ) {
return;
}
$product_link = $product->get_permalink();
$product_link_param = add_query_arg( $this->settings->get_param( 'base_prefix' ), $aff_param, $product_link );
ob_start();
?>
isset( $class ) ? $class : '',
'affi_link' => $product_link_param,
'affi_text' => $this->settings->get_param( 'share_button_text' ),
'affi_copy' => esc_html__( 'Copied', 'affi-affiliate-marketing-for-woo' ),
], '', AffiEnv::get( 'templates_dir' ) );
$social_share_prefix_url = $this->settings->get_social_prefix_url();
$social_share_enable = $this->settings->get_param( 'social_share' ) ?? [];
?>
$social_url . urlencode( $product_link_param ),
'affi_product_url' => $product_link,
'affi_class_icon' => 'social_' . $share_icon,
], '', AffiEnv::get( 'templates_dir' ) );
}
}
?>
exists() ) {
return '';
}
$user_id = $user_data->ID;
} else {
$user_data = get_userdata( (int) $user_id );
if ( ! $user_data ) {
return '';
}
}
$is_affiliate = $this->query->get_affiliate_id_by_user_id( $user_id );
if ( ! $is_affiliate ) {
return '';
}
if ( $this->settings->get_param( 'affiliate_link_format' ) == 'user_id' ) {
$aff_param = $is_affiliate;
} else {
$aff_param = ! empty( $user_data->user_login ) ? $user_data->user_login : $this->query->get_username_by_affiliate_id( $is_affiliate );
}
return $aff_param;
}
public function affi_account_user_update_payment() {
check_ajax_referer( 'affi_security', 'nonce' );
$user_id = get_current_user_id();
if ( ! affi_current_user_owns_affiliate( $user_id ) ) {
wp_send_json_error();
}
$payment_info = isset( $_POST['payment_info'] ) ? affi_sanitize_payment_info_for_storage( wp_unslash( $_POST['payment_info'] ) ) : '';// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
$insert_id = $this->query->update_affiliates_payment_info_by_user_id( $user_id, $payment_info );
wp_send_json( $insert_id );
}
public function affi_user_get_notification_detail() {
check_ajax_referer( 'affi_security', 'nonce' );
if ( ! is_user_logged_in() ) {
wp_send_json( array() );
}
$notify_id = isset( $_POST['id'] ) ? absint( wp_unslash( $_POST['id'] ) ) : 0;
$row_data = $this->query->get_user_notification( $notify_id );
if ( empty( $row_data['user_id'] ) || (int) $row_data['user_id'] !== get_current_user_id() ) {
wp_send_json( array() );
}
wp_send_json( $row_data );
}
public function affi_filter_products() {
check_ajax_referer( 'affi_security', 'nonce' );
$user_id = isset( $_POST['user'] ) ? absint( wp_unslash( $_POST['user'] ) ) : 0;
$aff_id = isset( $_POST['affiliate'] ) ? absint( wp_unslash( $_POST['affiliate'] ) ) : 0;
if ( (int) $user_id !== get_current_user_id() || ! affi_current_user_owns_affiliate( 0, $aff_id ) ) {
wp_send_json( array( 'products' => '', 'paging' => '' ) );
}
$page = isset( $_POST['page'] ) ? absint( wc_clean( wp_unslash( $_POST['page'] ) ) ) : 1;// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
$category = isset( $_POST['category'] ) ? sanitize_text_field( wp_unslash( $_POST['category'] ) ) : '';
$key_word = isset( $_POST['key'] ) ? sanitize_text_field( wp_unslash( $_POST['key'] ) ) : '';
$o_data = $this->affi_load_product_list( $user_id, $aff_id, $key_word, $category, $page );
wp_send_json( $o_data );
wp_die();
}
public function affi_load_product_list( $user_id, $aff_id, $key_word, $category, $page ) {
$per_page = intval( $this->settings->get_param( 'affi_page_items' ) );
$is_link_title = $this->settings->get_param( 'search_title_link' );
if ( empty( $per_page ) || $per_page < 1 ) {
$per_page = 30;
}
$items_data['per_page'] = $per_page;
$items_data['offset'] = $per_page * ( $page - 1 );
$items_data['af_cat'] = $category;
$items_data['key_word'] = $key_word;
$rank_rate = $this->query->get_order_affiliate_data( $aff_id );
$i_product_ids = $this->affi_search_product( $items_data );
$items_data['per_page'] = - 1;
$items_data['offset'] = '';
$c_product_ids = (int) $this->affi_search_product( $items_data );
if ( $i_product_ids ) {
$page_wrap = intval( $page * $per_page );
$page_end = $page_wrap > $c_product_ids ? $c_product_ids : $page_wrap;
$page_start = $page_wrap - $per_page;
$prefix_link = Data::instance()->get_param( 'base_prefix' );
ob_start();
foreach ( $i_product_ids as $i_id ) {
$w_product = wc_get_product( $i_id );
if ( ! $w_product ) {
continue;
}
$p_link = $w_product->get_permalink();
$param_link = Frontend::instance()->get_affiliate_params();
$promote_link = add_query_arg( $prefix_link, $param_link, $p_link );
$p_price = $w_product->get_price();
$p_earn = self::product_affiliate_rate( $rank_rate, $w_product );
$price_html = wc_price( $p_price );
?>
get_image( $this->settings->get_param( 'search_popup_image_size' ) ) ); ?>
get_rating_count() ) && $this->settings->get_param( 'search_view_ratting' ) ) { ?>
get_average_rating() ) ); ?>
settings->get_param( 'search_view_stock' ) ) { ?>
settings->get_param( 'search_view_description' ) ) { ?>
get_short_description() ); ?>
$page - 2 ) {
?>
...
$page + 2 ) {
continue;
}
if ( $p < $page + 2 ) {
?>
...
'', 'paging' => '' ];
}
function affi_search_product( $arg_input = [] ) {
$cat = isset( $arg_input['af_cat'] ) ? $arg_input['af_cat'] : '';
$tag = isset( $arg_input['af_tag'] ) ? $arg_input['af_tag'] : '';
$sort = isset( $arg_input['af_sort'] ) ? $arg_input['af_sort'] : 'date';
$order = isset( $arg_input['af_order'] ) ? $arg_input['af_order'] : '';
$key = isset( $arg_input['key_word'] ) ? $arg_input['key_word'] : '';
$per_page = isset( $arg_input['per_page'] ) ? $arg_input['per_page'] : - 1;
$offset = isset( $arg_input['offset'] ) ? $arg_input['offset'] : 0;
$arg = array(
'post_status' => 'publish',
'post_type' => 'product',
'posts_per_page' => $per_page,
'offset' => $offset,
's' => $key
);
$tax_arr = [];
if ( ! empty( $cat ) ) {
$tax_arr[] = [
'taxonomy' => 'product_cat',
'field' => 'term_id',
'terms' => $cat,
];
}
if ( ! empty( $tag ) ) {
$tax_arr[] = [
'taxonomy' => 'product_tag',
'field' => 'term_id',
'terms' => $tag,
];
}
if ( ! empty( $tax_arr ) ) {
$arg['tax_query'] = $tax_arr;// phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query
}
switch ( $sort ) {
case 'date':
$arg['orderby'] = array(
'date' => $order,
'menu_order' => 'ASC',
);
break;
case 'ratting':
$arg['orderby'] = 'meta_value_num';
$arg['meta_key'] = '_wc_average_rating';// phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
$arg['order'] = $order;
break;
case 'price':
$arg['orderby'] = 'meta_value_num';
$arg['meta_key'] = '_price';// phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
$arg['order'] = $order;
break;
default:
$arg['orderby'] = 'title';
$arg['order'] = $order;
break;
}
$the_query = new WP_Query( $arg );
if ( $per_page == - 1 ) {
$founded_count = $the_query->found_posts;
return $the_query->post_count;
}
$found_products = array();
if ( $the_query->have_posts() ) {
$s_product_ids = $the_query->posts;
foreach ( $s_product_ids as $s_index => $s_product_object ) {
if ( ! is_object( $s_product_object ) || empty( $s_product_object ) || ! property_exists( $s_product_object, 'ID' ) ) {
continue;
}
$s_product_id = $s_product_object->ID;
if ( is_array( $s_product_id ) || is_object( $s_product_id ) || empty( $s_product_id ) ) {
continue;
}
$found_products[] = $s_product_id;
}
return $found_products;
}
wp_reset_postdata();
return null;
}
public function product_affiliate_rate( $aff_rate, $product ) {
$g_r_type = $this->settings->get_param( 'commission_type' );
$g_r_rate = floatval( $this->settings->get_param( 'commission_rate' ) );
$p_price = $product->get_price();
if ( wc_prices_include_tax() ) {
$r_price = $this->settings->get_param( 'commission_tax' ) ? (float) wc_get_price_excluding_tax( $product ) : (float) $p_price;
} else {
$r_price = $this->settings->get_param( 'commission_tax' ) ? (float) $p_price : (float) wc_get_price_including_tax( $product );
}
if ( empty( $aff_rate ) ) {
if ( ! empty( $g_r_rate ) ) {
if ( $g_r_type == 'fixed' ) {
return floatval( $g_r_rate );
} else {
return ( $r_price * $g_r_rate ) / 100;
}
}
return 0;
} else {
if ( $aff_rate['rate_type'] == 'fixed' ) {
$rank_amount = floatval( $aff_rate['rate'] );
} else {
$rank_amount = ( $r_price * $aff_rate['rate'] ) / 100;
}
if ( ! empty( $g_r_rate ) ) {
if ( $g_r_type == 'fixed' ) {
return floatval( $g_r_rate ) + $rank_amount;
} else {
return ( ( $r_price * $g_r_rate ) / 100 ) + $rank_amount;
}
} else {
return $rank_amount;
}
}
return 0;
}
public function affi_user_request_payout() {
check_ajax_referer( 'affi_security', 'nonce' );
$user_id = get_current_user_id();
if ( ! affi_current_user_owns_affiliate( $user_id ) ) {
wp_send_json_error();
}
if ( ! $this->settings->get_param( 'payment_request' ) ) {
wp_send_json_error();
}
$payout_price_raw = isset( $_REQUEST['payout_price'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['payout_price'] ) ) : '';
$description = isset( $_REQUEST['description'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['description'] ) ) : '';
$aff_info = $this->query->get_affiliate_by_user_id( $user_id );
if ( ! is_array( $aff_info ) || empty( $aff_info['status'] ) || 'approved' !== $aff_info['status'] ) {
wp_send_json_error();
}
if ( ! is_numeric( $payout_price_raw ) ) {
wp_send_json_error();
}
$payout_price = (float) $payout_price_raw;
if ( ! is_finite( $payout_price ) || $payout_price <= 0 ) {
wp_send_json_error();
}
$payment_fee = (float) $this->settings->get_param( 'payment_fee' );
// Free UI uses payment_fee as minimum; amount must be higher than the fee when fee > 0.
if ( $payment_fee > 0 && $payout_price <= $payment_fee ) {
wp_send_json_error();
}
global $wpdb;
$lock_name = 'affi_payout_req_' . absint( $user_id );
// Serialize check+insert per affiliate so concurrent requests cannot over-commit available.
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
$got_lock = $wpdb->get_var( $wpdb->prepare( 'SELECT GET_LOCK(%s, %d)', $lock_name, 10 ) );
if ( '1' !== (string) $got_lock ) {
wp_send_json_error();
}
$insert_id = false;
try {
$aff_info = $this->query->get_affiliate_by_user_id( $user_id );
if ( ! is_array( $aff_info ) || empty( $aff_info['status'] ) || 'approved' !== $aff_info['status'] ) {
wp_send_json_error();
}
$earning = isset( $aff_info['earning'] ) ? (float) $aff_info['earning'] : 0.0;
$balance = isset( $aff_info['balance'] ) ? (float) $aff_info['balance'] : 0.0;
$pending_amount = $this->query->get_pending_payout_amount_by_user( $user_id );
$available_for_new = $earning - $balance - $pending_amount;
if ( $payout_price > $available_for_new ) {
wp_send_json_error();
}
$payment_info = isset( $aff_info['payment_info'] ) ? $aff_info['payment_info'] : '';
$insert_id = $this->query->insert_user_request_payout( [
'user_id' => $user_id,
'transaction_id' => \AffiAffiliate\Inc\QueryDB::generate_payout_transaction_id( $user_id ),
'amount' => $payout_price,
'type' => 'user',
'payment' => $payment_info,
'fee' => $payment_fee,
'status' => 'pending',
'description' => $description,
'date_created' => current_time( 'U' ),
] );
} finally {
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
$wpdb->get_var( $wpdb->prepare( 'SELECT RELEASE_LOCK(%s)', $lock_name ) );
}
if ( ! $insert_id ) {
wp_send_json_error();
}
wp_send_json( $insert_id );
}
}