File: /storage/v4513/tepnot/public_html/wp-content/plugins/dokan-pro/includes/Withdraw/Manager.php
<?php
namespace WeDevs\DokanPro\Withdraw;
use WeDevs\Dokan\Withdraw\Withdraw;
use WP_User;
/**
* Withdraw Functionality class
*
* @since 2.4
* @since 3.5.0 Automatic Withdraw Disbursement added.
*
* @author weDevs <[email protected]>
*/
class Manager {
/**
* Constructor for the Manager class
*
* Sets up all the appropriate hooks and actions
* within our plugin.
*
* @return void
*/
public function __construct() {
if ( is_user_logged_in() ) {
add_filter( 'dokan_withdraw_methods', [ $this, 'load_withdraw_method' ], 10 );
add_filter( 'dokan_vendor_payment_withdraw_methods', [ $this, 'add_description_for_skrill_method' ], 10, 2 );
add_filter( 'dokan_settings_fields', [ $this, 'withdraw_disbursement_schedule_settings' ], 10 );
add_action( 'dokan_withdraw_content_after_last_payment_section', [ $this, 'add_withdraw_schedule_section' ], 5 );
add_action( 'dokan_withdraw_content_after', [ $this, 'add_withdraw_schedule_popup_template' ], 10 );
add_action( 'dokan_before_saving_settings', [ $this, 'validate_withdraw_schedule_option' ], 30, 2 );
}
add_action( 'init', [ $this, 'set_schedules' ], 30 );
add_action( 'dokan_withdraw_quarterly_scheduler', [ $this, 'process_quarterly_schedule' ] );
add_action( 'dokan_withdraw_monthly_scheduler', [ $this, 'process_monthly_schedule' ] );
add_action( 'dokan_withdraw_biweekly_scheduler', [ $this, 'process_biweekly_schedule' ] );
add_action( 'dokan_withdraw_weekly_scheduler', [ $this, 'process_weekly_schedule' ] );
add_action( 'dokan_withdraw_individual_scheduler', [ $this, 'process_individual_schedule' ] );
add_action( 'dokan_withdraw_disbursement_announcement_scheduler', [ $this, 'process_announcement_schedule' ] );
add_action( 'dokan_withdraw_disbursement_schedule_announcement_scheduler', [ $this, 'process_schedule_change_announcement_schedule' ] );
add_action( 'update_option_timezone_string', [ $this, 'handle_timezone_change' ], 10, 3 );
add_action( 'update_option_gmt_offset', [ $this, 'handle_timezone_change' ], 10, 3 );
add_action( 'update_option_dokan_withdraw', [ $this, 'handle_schedule_change' ], 10, 3 );
add_action( 'update_option_dokan_withdraw', [ $this, 'handle_schedule_settings_change' ], 10, 3 );
add_action( 'update_option_dokan_withdraw', [ $this, 'handle_withdraw_operation_enable_disable' ], 10, 3 );
add_action( 'update_option_dokan_withdraw', [ $this, 'handle_admin_withdraw_method_change' ], 10, 3 );
add_filter( 'dokan_withdraw_manual_request_enable', [ $this, 'enable_manual_withdraw' ] );
add_filter( 'dokan_get_dashboard_nav', [ $this, 'unset_withdraw_page_menu' ] );
if ( wp_doing_ajax() ) {
add_action( 'wp_ajax_dokan_handle_withdraw_schedule_change_request', [ $this, 'handle_withdraw_schedule_change_request' ], 10 );
add_action( 'wp_ajax_dokan_handle_withdraw_schedule_remove', [ $this, 'handle_withdraw_schedule_remove_request' ], 10 );
}
add_filter( 'dokan_withdraw_method_settings_title', [ $this, 'get_heading' ], 10, 2 );
add_filter( 'dokan_withdraw_method_icon', [ $this, 'get_icon' ], 10, 2 );
add_action( 'dokan_store_profile_saved', [ $this, 'save_skrill_progress' ], 10, 2 );
add_action( 'dokan_rest_store_settings_after_update', [ $this, 'save_api_skrill_progress' ], 10, 2 );
add_filter( 'dokan_payment_settings_required_fields', [ $this, 'map_required_fields' ], 10, 3 );
add_filter( 'dokan_withdraw_withdrawable_payment_methods', [ $this, 'include_skrill_to_payment_methods' ] );
add_filter( 'dokan_withdraw_method_additional_info', [ $this, 'mask_custom_withdraw_method' ], 10, 2 );
}
/**
* Load withdraw method
*
* @since 2.4
*
* @param array $methods
*
* @return array
*/
public function load_withdraw_method( $methods ) {
$methods['skrill'] = [
'title' => __( 'Skrill', 'dokan' ),
'callback' => [ $this, 'dokan_withdraw_method_skrill' ],
'apply_charge' => true,
];
return $methods;
}
/**
* Callback for Skrill in store settings
*
* @since 2.4
*
* @global WP_User $current_user
*
* @param array $store_settings
*
* @return void
*/
public function dokan_withdraw_method_skrill( $store_settings ) {
$email = isset( $store_settings['payment']['skrill']['email'] ) ? esc_attr( $store_settings['payment']['skrill']['email'] ) : '';
ob_start();
?>
<div class="dokan-form-group">
<div class="dokan-w8">
<div class="dokan-input-group">
<span class="dokan-input-group-addon"><?php esc_html_e( 'E-mail', 'dokan' ); ?></span>
<input value="<?php echo esc_attr( $email ); ?>" name="settings[skrill][email]" class="dokan-form-control email" placeholder="[email protected]" type="text">
</div>
</div>
</div>
<?php if ( dokan_is_seller_dashboard() ) : ?>
<div class="dokan-form-group">
<div class="dokan-w8">
<input name="dokan_update_payment_settings" type="hidden">
<button class="ajax_prev disconnect dokan_payment_disconnect_btn dokan-btn dokan-btn-danger <?php echo empty( $email ) ? 'dokan-hide' : ''; ?>" type="button" name="settings[skrill][disconnect]">
<?php esc_attr_e( 'Disconnect', 'dokan' ); ?>
</button>
</div>
</div>
<?php
endif;
echo ob_get_clean();
}
/**
* Add withdraw disbursement schedule settings subsection.
*
* @since 3.5.0
*
* @param array $settings
*
* @return array
*/
public function withdraw_disbursement_schedule_settings( $settings ) {
$months = Helper::get_month_list();
$schedules = Helper::get_disbursement_schedules();
$days_of_week = Helper::get_days_of_week_list();
$week_of_month = Helper::get_weeks_of_month_list();
$week_of_month_ex_4th = wp_array_slice_assoc(
$week_of_month,
[
'1',
'2',
'3',
'L',
]
);
$settings['dokan_withdraw']['disbursement_schedule_settings'] = [
'name' => 'disbursement_schedule_settings',
'type' => 'disbursement_sub_section',
'label' => __( 'Disbursement Schedule', 'dokan' ),
'description' => __( 'Select suitable Schedule for Auto Withdraw Process for Vendors.', 'dokan' ),
'content_class' => 'sub-section-styles',
];
$settings['dokan_withdraw']['disbursement'] = [
'name' => 'disbursement',
'label' => __( 'Withdraw Disbursement', 'dokan' ),
'desc' => __( 'Select suitable Withdraw Process for Vendors', 'dokan' ),
'type' => 'disbursement_method',
'tooltip' => __( 'Admin can enable one or both and the vendor will use which is convenient for them', 'dokan' ),
'default' => [ 'manual' => 'manual' ],
'options' => [
'manual' => __( 'Manual Withdraw', 'dokan' ),
'schedule' => __( 'Schedule Disbursement', 'dokan' ),
],
'common_class' => 'withdraw_disbursement',
];
$settings['dokan_withdraw']['disbursement_schedule'] = [
'name' => 'disbursement_schedule',
'label' => __( 'Disbursement Schedule', 'dokan' ),
'desc' => __( 'Select suitable Schedule for Auto Withdraw Process for Vendors', 'dokan' ),
'type' => 'disbursement_type',
'tooltip' => __( 'Admin can enable multiple schedules, but the vendor can choose to use only one', 'dokan' ),
'default' => array_fill_keys( array_keys( $schedules ), '' ),
'options' => $schedules,
'common_class' => 'withdraw_disbursement',
];
$settings['dokan_withdraw']['quarterly_schedule'] = [
'name' => 'quarterly_schedule',
'label' => __( 'Quarterly Schedule', 'dokan' ),
'desc' => __( 'Select suitable months, weeks and day of week for Auto Withdraw Quarterly schedule execution', 'dokan' ),
'type' => 'schedule_quarterly',
'default' => [
'month' => 'march',
'week' => '1',
'days' => 'monday',
],
'options' => [
'first' => array_slice( $months, 0, 3, true ),
'second' => array_slice( $months, 3, 3, true ),
'third' => array_slice( $months, 6, 3, true ),
'fourth' => array_slice( $months, 9, 3, true ),
'week' => $week_of_month_ex_4th,
'days' => $days_of_week,
],
'common_class' => 'withdraw_disbursement',
];
$settings['dokan_withdraw']['monthly_schedule'] = [
'name' => 'monthly_schedule',
'label' => __( 'Monthly Schedule', 'dokan' ),
'desc' => __( 'Select suitable weeks and day of week for Auto Withdraw Monthly schedule execution', 'dokan' ),
'type' => 'schedule_monthly',
'default' => [
'week' => '1',
'days' => 'monday',
],
'options' => [
'week' => $week_of_month_ex_4th,
'days' => $days_of_week,
],
'common_class' => 'withdraw_disbursement',
];
$settings['dokan_withdraw']['biweekly_schedule'] = [
'name' => 'biweekly_schedule',
'label' => __( 'Biweekly Schedule', 'dokan' ),
'desc' => __( 'Select suitable week for Auto Withdraw Biweekly schedule execution', 'dokan' ),
'type' => 'schedule_biweekly',
'default' => [
'week' => '1',
'days' => 'monday',
],
'options' => [
'first' => array_slice( $week_of_month, 0, 2, true ),
'second' => array_slice( $week_of_month, 2, 2, true ),
'days' => $days_of_week,
],
'common_class' => 'withdraw_disbursement',
];
$settings['dokan_withdraw']['weekly_schedule'] = [
'name' => 'weekly_schedule',
'label' => __( 'Weekly Schedule', 'dokan' ),
'desc' => __( 'Select suitable day of the week for Auto Withdraw Weekly schedule execution', 'dokan' ),
'type' => 'schedule_weekly',
'default' => 'monday',
'options' => $days_of_week,
'common_class' => 'withdraw_disbursement',
];
return $settings;
}
/**
* Include Withdraw schedule Section on Withdraw dashboard.
*
* @since 3.5.0
*
* @return void
*/
public function add_withdraw_schedule_section() {
if ( ! Helper::is_withdraw_disbursement_enabled() ) {
return;
}
$vendor_id = dokan_get_current_user_id();
$default_method = dokan_withdraw_get_default_method( $vendor_id );
$minimum_amount_needed = Helper::get_selected_minimum_withdraw_amount( $vendor_id );
$saved_schedule = get_user_meta( $vendor_id, 'dokan_withdraw_selected_schedule', true );
$is_schedule_selected = ! empty( $saved_schedule ) && in_array( $saved_schedule, Helper::get_active_schedules(), true );
$schedule_information = __( 'Please update your withdraw schedule selection to get payment automatically.', 'dokan' );
$threshold_information = '';
if ( $is_schedule_selected ) {
$schedule_information = sprintf(
// translators: 1: Vendor's selected withdraw schedule 2: Selected scheduled day 3: Default Withdraw method, 4: Withdraw method information.
__( '<strong>%1$s</strong> <small>( next on %2$s )</small> to <strong>%3$s</strong> <small>%4$s</small>', 'dokan' ),
Helper::get_schedule_title( Helper::get_selected_schedule( $vendor_id ) ),
$this->next_scheduled_day_for_withdraw( Helper::get_selected_schedule( $vendor_id ) ),
dokan_withdraw_get_method_title( $default_method ),
dokan_withdraw_get_method_additional_info( $default_method )
);
// translators: 1: Withdraw amount threshold.
$threshold_information = ! empty( $minimum_amount_needed ) ? sprintf( __( 'Only when the balance is <strong>%1$s</strong> or more.', 'dokan' ), wc_price( $minimum_amount_needed ) ) : '';
}
dokan_pro_get_template(
'withdraw/payment-details-schedule',
[
'schedule_information' => $schedule_information,
'threshold_information' => $threshold_information,
'is_schedule_selected' => $is_schedule_selected,
]
);
}
/**
* Include Withdraw schedule popup.
*
* @since 3.5.0
*
* @return void
*/
public function add_withdraw_schedule_popup_template() {
$withdraw_schedule_data = $this->withdraw_schedule_data();
if ( empty( $withdraw_schedule_data['enabled'] ) ) {
return;
}
dokan_pro_get_template(
'withdraw/tmpl-payment-details-schedule',
$withdraw_schedule_data
);
}
/**
* Returns withdraw schedule data.
*
* @since 3.7.23
*
* @return array $schedule_data{
* @type boolean $enabled
* @type string $selected_schedule
* @type array $schedules {
* @type string next
* @type string title
* @type string description
* }
* @type array $minimum_amount_list
* @type integer $minimum_amount_selected
* @type array $reserve_balance_list
* @type integer $reserve_balance_selected
* @type string $active_methods
* @type string $default_method
* }
*/
public function withdraw_schedule_data() {
$enabled = Helper::is_withdraw_disbursement_enabled();
if ( ! $enabled ) {
return;
}
$active_schedules = Helper::get_active_schedules();
$schedules = [];
foreach ( $active_schedules as $schedule ) {
$schedules[ $schedule ] = [
'next' => $this->next_scheduled_day_for_withdraw( $schedule ),
'title' => Helper::get_schedule_title( $schedule ),
'description' => $this->get_schedule_description( $schedule ),
];
}
$active_methods = array_intersect( dokan_get_seller_active_withdraw_methods(), dokan_withdraw_get_active_methods() );
$schedule_data = [
'enabled' => $enabled,
'selected_schedule' => Helper::get_selected_schedule(),
'schedules' => $schedules,
'minimum_amount_list' => Helper::get_nearest_minimum_withdraw_amount_list( Helper::get_minimum_withdraw_amount() ),
'minimum_amount_selected' => Helper::get_selected_minimum_withdraw_amount(),
'reserve_balance_list' => Helper::get_minimum_reserve_balance_list(),
'reserve_balance_selected' => Helper::get_selected_reserve_balance(),
'active_methods' => $active_methods,
'default_method' => dokan_withdraw_get_default_method(),
'is_setup_payment_methods' => ! empty( $active_methods ),
];
return $schedule_data;
}
/**
* Get the next scheduled run day of timestamp for selected schedule.
*
* @since 3.5.0
*
* @param string $schedule_type
* @param bool $is_timestamp
*
* @return int|string
*/
public function next_scheduled_day_for_withdraw( $schedule_type, $is_timestamp = false ) {
$schedule_run_time = Helper::get_schedule_start_time( true );
$now = dokan_current_datetime();
$next_year = $now->modify( 'next year' )->format( 'Y' );
switch ( $schedule_type ) {
case 'quarterly':
$quarter_option = Helper::get_option_quarterly_schedule();
$quarter_month = $quarter_option['month'];
$quarter_day = $quarter_option['days'];
$quarter_week = Helper::get_descriptive_week_of_month( $quarter_option['week'] );
$quarter_months = Helper::get_quarterly_schedule_months( $quarter_month );
$first_quarter = dokan_current_datetime()
->modify( "{$quarter_week} {$quarter_day} of {$quarter_months[0]} this year {$schedule_run_time}" );
$second_quarter = dokan_current_datetime()
->modify( "{$quarter_week} {$quarter_day} of {$quarter_months[1]} this year {$schedule_run_time}" );
$third_quarter = dokan_current_datetime()
->modify( "{$quarter_week} {$quarter_day} of {$quarter_months[2]} this year {$schedule_run_time}" );
$fourth_quarter = dokan_current_datetime()
->modify( "{$quarter_week} {$quarter_day} of {$quarter_months[3]} this year {$schedule_run_time}" );
if ( $now->getTimestamp() < $first_quarter->getTimestamp() ) {
$date = $first_quarter;
break;
}
if ( $now->getTimestamp() < $second_quarter->getTimestamp() ) {
$date = $second_quarter;
break;
}
if ( $now->getTimestamp() < $third_quarter->getTimestamp() ) {
$date = $third_quarter;
break;
}
if ( $now->getTimestamp() < $fourth_quarter->getTimestamp() ) {
$date = $fourth_quarter;
break;
}
$date = dokan_current_datetime()
->modify( "{$quarter_week} {$quarter_day} of {$quarter_months[0]} {$next_year} {$schedule_run_time}" );
break;
case 'monthly':
$month = Helper::get_option_monthly_schedule();
$month_week = Helper::get_descriptive_week_of_month( $month['week'] );
$month_day = $month['days'];
$this_month_time = dokan_current_datetime()
->modify( "{$month_week} {$month_day} of this month {$schedule_run_time}" );
if ( $now->getTimestamp() < $this_month_time->getTimestamp() ) {
$date = $this_month_time;
break;
}
$date = dokan_current_datetime()
->modify( "{$month_week} {$month_day} of next month {$schedule_run_time}" );
break;
case 'biweekly':
$biweekly_option = Helper::get_option_biweekly_schedule();
$biweekly_week = $biweekly_option['week'];
$biweekly_day = $biweekly_option['days'];
$first_week = dokan_current_datetime()
->modify( "first {$biweekly_day} of this month" )
->modify( $schedule_run_time );
$second_week = dokan_current_datetime()
->modify( "second {$biweekly_day} of this month" )
->modify( $schedule_run_time );
if ( '1' === $biweekly_week ) {
if ( $now->getTimestamp() < $first_week->getTimestamp() ) {
$date = $first_week;
break;
}
if ( $now->getTimestamp() < $first_week->modify( '+2 weeks' )->getTimestamp() ) {
$date = $first_week->modify( '+2 weeks' );
break;
}
$date = dokan_current_datetime()
->modify( "first {$biweekly_day} of next month" )
->modify( $schedule_run_time );
break;
}
if ( $now->getTimestamp() < $second_week->getTimestamp() ) {
$date = $second_week;
break;
}
if ( $now->getTimestamp() < $second_week->modify( '+2 weeks' )->getTimestamp() ) {
$date = $second_week->modify( '+2 weeks' );
break;
}
$date = dokan_current_datetime()
->modify( "second {$biweekly_day} of next month" )
->modify( $schedule_run_time );
break;
case 'weekly':
$weekly_day = Helper::get_option_weekly_schedule();
$this_week = dokan_current_datetime()
->modify( 'this ' . $weekly_day )
->modify( $schedule_run_time );
if ( $now->getTimestamp() < $this_week->getTimestamp() ) {
$date = $this_week;
break;
}
$date = $this_week->modify( '+ 1 week' );
break;
default:
$date = $now;
}
return $is_timestamp ? $date->getTimestamp() : dokan_format_date( $date->getTimestamp() );
}
/**
* Handle Withdraw schedule change request.
*
* @since 3.5.0
*
* @return void
*/
public function handle_withdraw_schedule_change_request() {
if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_key( wp_unslash( $_POST['nonce'] ) ), 'dokan_withdraw_schedule_nonce' ) ) {
wp_send_json_error( esc_html__( 'Are you cheating?', 'dokan' ) );
}
if ( ! current_user_can( 'dokan_manage_withdraw' ) ) {
wp_send_json_error( esc_html__( 'You have no permission to do this action', 'dokan' ) );
}
$method = isset( $_POST['method'] ) ? sanitize_key( wp_unslash( $_POST['method'] ) ) : '';
if ( empty( $method ) ) {
wp_send_json_error( esc_html__( 'Please provide Withdrew method.', 'dokan' ) );
}
if ( ! in_array( $method, dokan_withdraw_get_active_methods(), true ) ) {
wp_send_json_error( esc_html__( 'Method not active.', 'dokan' ) );
}
$schedule = isset( $_POST['schedule'] ) ? sanitize_key( wp_unslash( $_POST['schedule'] ) ) : '';
if ( empty( $schedule ) ) {
wp_send_json_error( esc_html__( 'Provide a schedule to set as default.', 'dokan' ) );
}
$minimum_withdraw_amount = isset( $_POST['minimum'] ) ? floatval( sanitize_text_field( wp_unslash( $_POST['minimum'] ) ) ) : 0;
if ( $minimum_withdraw_amount < floatval( Helper::get_minimum_withdraw_amount() ) ) {
wp_send_json_error( esc_html__( 'Please check minimum withdraw balance.', 'dokan' ) );
}
$reserve_amount = isset( $_POST['reserve'] ) ? absint( wp_unslash( $_POST['reserve'] ) ) : 0;
if ( $reserve_amount < 0 ) {
wp_send_json_error( esc_html__( 'Please check reserve amount.', 'dokan' ) );
}
Helper::save_withdraw_schedule( $schedule, $minimum_withdraw_amount, $reserve_amount, $method );
wp_send_json_success( __( 'Withdraw schedule changed successfully.', 'dokan' ) );
}
/**
* Handle Withdraw schedule remove request.
*
* @since 3.7.16
*
* @return void
*/
public function handle_withdraw_schedule_remove_request() {
if ( ! isset( $_POST['security'] ) || ! wp_verify_nonce( sanitize_key( wp_unslash( $_POST['security'] ) ), 'remove-withdraw-schedule' ) ) {
wp_send_json_error( esc_html__( 'Security validation failed!', 'dokan' ) );
}
if ( ! current_user_can( 'dokan_manage_withdraw' ) ) {
wp_send_json_error( esc_html__( 'You have no permission to do this action.', 'dokan' ) );
}
update_user_meta( dokan_get_current_user_id(), 'dokan_withdraw_selected_schedule', '' );
wp_send_json_success( __( 'Withdraw schedule removed successfully.', 'dokan' ) );
}
/**
* Get the human-readable schedule timing.
*
* @since 3.5.0
*
* @param string $schedule
*
* @return string
*/
public function get_schedule_description( $schedule ) {
$quarter_option = Helper::get_option_quarterly_schedule();
$month_option = Helper::get_option_monthly_schedule();
$biweekly_option = Helper::get_option_biweekly_schedule();
$weekly_day = Helper::get_option_weekly_schedule();
$months = Helper::get_quarterly_schedule_months( $quarter_option['month'] );
$weeks = Helper::get_biweekly_schedule_weeks( $biweekly_option['week'] );
switch ( $schedule ) {
case 'quarterly':
$info = sprintf(
// translators: 1: Selected week for quarterly schedule 2: Selected week day for quarterly schedule 3: Selected month for quarterly schedule separated by comma (,).
__( 'on %1$s %2$s of %3$s', 'dokan' ),
Helper::get_descriptive_week_of_month( $quarter_option['week'] ),
Helper::get_human_readable_day_of_week( $quarter_option['days'] ),
implode( ', ', array_map( [ Helper::class, 'get_human_readable_month' ], $months ) )
);
break;
case 'monthly':
$info = sprintf(
// translators: 1: Selected week for monthly schedule. 2: Selected day of week for monthly schedule.
__( 'on %1$s %2$s of every month.', 'dokan' ),
Helper::get_descriptive_week_of_month( $month_option['week'] ),
Helper::get_human_readable_day_of_week( $month_option['days'] )
);
break;
case 'biweekly':
$info = sprintf(
// translators: 1: Selected day for biweekly schedule 2: Selected week for biweekly schedule separated by comma (,).
__( 'on %1$s of %2$s of each month', 'dokan' ),
Helper::get_human_readable_day_of_week( $biweekly_option['days'] ),
implode( ', ', array_map( [ Helper::class, 'get_human_readable_week_of_month' ], $weeks ) )
);
break;
case 'weekly':
$info = sprintf(
// translators: 1: Selected day for biweekly schedule
__( 'on %1$s of every week.', 'dokan' ),
Helper::get_human_readable_day_of_week( $weekly_day )
);
break;
default:
$info = $schedule;
}
return apply_filters( 'dokan_withdraw_disbursement_schedule_description', $info, $schedule );
}
/**
* Reschedule on some events like settings save or WP timestamp change.
*
* @since 3.5.0
*
* @return void
*/
public function reschedule() {
self::cancel_all_schedules();
$this->set_schedules();
}
/**
* Register or set admin selected schedules for withdraw.
*
* @since 3.5.0
*
* @return void
*/
public function set_schedules() {
if ( ! Helper::is_withdraw_operation_enabled() || ! Helper::is_withdraw_disbursement_enabled() ) {
return;
}
if ( Helper::is_quarterly_schedule_active() ) {
$this->set_quarterly_schedule();
}
if ( Helper::is_monthly_schedule_active() ) {
$this->set_monthly_schedule();
}
if ( Helper::is_biweekly_schedule_active() ) {
$this->set_biweekly_schedule();
}
if ( Helper::is_weekly_schedule_active() ) {
$this->set_weekly_schedule();
}
}
/**
* Set single onetime disbursement schedule for withdraw.
* It will run as soon as possible.
*
* @since 3.5.0
*
* @param array $args Schedule argument.
* @param string $group Schedule group.
*
* @return void
*/
public function set_single_disbursement_schedule( $args, $group ) {
as_enqueue_async_action( 'dokan_withdraw_individual_scheduler', $args, $group );
}
/**
* Cancel all schedules for withdraw.
*
* @since 3.5.0
*
* @return void
*/
public static function cancel_all_schedules() {
if ( function_exists( 'as_unschedule_action' ) ) {
as_unschedule_action( 'dokan_withdraw_quarterly_scheduler' );
as_unschedule_action( 'dokan_withdraw_monthly_scheduler' );
as_unschedule_action( 'dokan_withdraw_biweekly_scheduler' );
as_unschedule_action( 'dokan_withdraw_weekly_scheduler' );
}
}
/**
* Register or set quarterly schedules for withdraw.
*
* @since 3.5.0
*
* @return void
*/
public function set_quarterly_schedule() {
$quarterly = Helper::get_option_quarterly_schedule();
$starting = Helper::get_quarterly_start_month( $quarterly['month'] );
$timestamp = $this->next_scheduled_day_for_withdraw( 'quarterly', true );
$week = 'L' === $quarterly['week'] ? $quarterly['week'] : '#' . $quarterly['week'];
$schedule = Helper::get_schedule_start_time() . ' ? ' . $starting . '/3 ' . Helper::get_cron_day_of_week( $quarterly['days'] ) . $week;
if ( false === as_next_scheduled_action( 'dokan_withdraw_quarterly_scheduler' ) ) {
as_schedule_cron_action( $timestamp, $schedule, 'dokan_withdraw_quarterly_scheduler', [], 'dokan_withdraw_disbursement' );
}
}
/**
* Set monthly schedules for withdraw.
*
* @since 3.5.0
*
* @return void
*/
public function set_monthly_schedule() {
$monthly = Helper::get_option_monthly_schedule();
$timestamp = $this->next_scheduled_day_for_withdraw( 'monthly', true );
$week = ( $monthly['week'] === 'L' ) ? $monthly['week'] : '#' . $monthly['week'];
$schedule = Helper::get_schedule_start_time() . ' ? 1/1 ' . Helper::get_cron_day_of_week( $monthly['days'] ) . $week;
if ( false === as_next_scheduled_action( 'dokan_withdraw_monthly_scheduler' ) ) {
as_schedule_cron_action( $timestamp, $schedule, 'dokan_withdraw_monthly_scheduler', [], 'dokan_withdraw_disbursement' );
}
}
/**
* Set biweekly schedules for withdraw.
*
* @since 3.5.0
*
* @return void
*/
public function set_biweekly_schedule() {
$biweekly = Helper::get_option_biweekly_schedule();
$timestamp = $this->next_scheduled_day_for_withdraw( 'biweekly', true );
$schedule = Helper::get_schedule_start_time() . ( $biweekly['week'] === '1' ? ' 1-7,15-21 ' : ' 8-14,22-28 ' ) . '* ' . Helper::get_cron_day_of_week( $biweekly['days'] );
if ( false === as_next_scheduled_action( 'dokan_withdraw_biweekly_scheduler' ) ) {
as_schedule_cron_action( $timestamp, $schedule, 'dokan_withdraw_biweekly_scheduler', [], 'dokan_withdraw_disbursement' );
}
}
/**
* Set weekly schedules for withdraw.
*
* @since 3.5.0
*
* @return void
*/
public function set_weekly_schedule() {
$timestamp = $this->next_scheduled_day_for_withdraw( 'weekly', true );
$schedule = Helper::get_schedule_start_time() . ' ? * ' . Helper::get_cron_day_of_week( Helper::get_option_weekly_schedule() );
if ( false === as_next_scheduled_action( 'dokan_withdraw_weekly_scheduler' ) ) {
as_schedule_cron_action( $timestamp, $schedule, 'dokan_withdraw_weekly_scheduler', [], 'dokan_withdraw_disbursement' );
}
}
/**
* Process quarterly schedule.
*
* @since 3.5.0
*
* @return void
*/
public function process_quarterly_schedule() {
$this->process_schedule( 'quarterly' );
/**
* Action hook `dokan_withdraw_disbursement_after_quarterly_schedule`
*
* @since 3.5.0
*/
do_action( 'dokan_withdraw_disbursement_after_quarterly_schedule' );
}
/**
* Process monthly schedule.
*
* @since 3.5.0
*
* @return void
*/
public function process_monthly_schedule() {
$this->process_schedule( 'monthly' );
/**
* Action hook `dokan_withdraw_disbursement_after_monthly_schedule`
*
* @since 3.5.0
*/
do_action( 'dokan_withdraw_disbursement_after_monthly_schedule' );
}
/**
* Process biweekly schedule.
*
* @since 3.5.0
*
* @return void
*/
public function process_biweekly_schedule() {
$this->process_schedule( 'biweekly' );
/**
* Action hook `dokan_withdraw_disbursement_after_biweekly_schedule`
*
* @since 3.5.0
*/
do_action( 'dokan_withdraw_disbursement_after_biweekly_schedule' );
}
/**
* Process weekly schedule.
*
* @since 3.5.0
*
* @return void
*/
public function process_weekly_schedule() {
$this->process_schedule( 'weekly' );
/**
* Action hook `dokan_withdraw_disbursement_after_weekly_schedule`
*
* @since 3.5.0
*/
do_action( 'dokan_withdraw_disbursement_after_weekly_schedule' );
}
/**
* Process schedule.
*
* @since 3.5.0
*
* @param string $group_key
*
* @return void
*/
public function process_schedule( $group_key ) {
// @codingStandardsIgnoreStart
$args = [
'role__in' => [
'administrator',
'seller',
],
'meta_key' => 'dokan_withdraw_selected_schedule',
'meta_value' => $group_key,
'post_per_page' => - 1,
];
// @codingStandardsIgnoreEnd
$user_query = new \WP_User_Query( $args );
if ( empty( $user_query->get_results() ) ) {
return;
}
foreach ( $user_query->get_results() as $user ) {
$this->set_single_disbursement_schedule(
[
'user_id' => $user->ID,
],
'dokan_withdraw_disbursement_' . $group_key
);
}
}
/**
* Process individual onetime schedule.
*
* @since 3.5.0
*
* @param int $user_id
*
* @return void|\WP_Error
*/
public function process_individual_schedule( $user_id ) {
$default_withdraw_method = dokan_withdraw_get_default_method( $user_id );
if (
dokan()->withdraw->has_pending_request( $user_id )
|| ! dokan()->withdraw->has_withdraw_balance( $user_id )
|| ! in_array( $default_withdraw_method, dokan_withdraw_get_withdrawable_active_methods( $user_id ), true )
) {
return;
}
$vendor_total_balance = dokan()->withdraw->get_user_balance( $user_id );
$minimum_amount = dokan()->withdraw->get_withdraw_limit();
if ( empty( $vendor_total_balance ) ) {
return;
}
if ( ! empty( $minimum_amount ) && $minimum_amount > $vendor_total_balance ) {
return;
}
$vendor_minimum_amount = Helper::get_selected_minimum_withdraw_amount( $user_id );
$vendor_reserve_balance = Helper::get_selected_reserve_balance( $user_id );
$withdraw_amount = $vendor_total_balance - $vendor_reserve_balance;
if ( $withdraw_amount < $minimum_amount || $vendor_total_balance < $vendor_minimum_amount ) {
return;
}
$args = [
'user_id' => $user_id,
'amount' => $withdraw_amount,
'method' => $default_withdraw_method,
];
$validate_request = dokan()->withdraw->is_valid_approval_request( $args );
if ( is_wp_error( $validate_request ) ) {
return;
}
$data = [
'user_id' => $user_id,
'amount' => $withdraw_amount,
'status' => dokan()->withdraw->get_status_code( 'pending' ),
'method' => $default_withdraw_method,
'ip' => 'UNKNOWN',
'note' => '',
'date' => dokan_current_datetime()->format( 'Y-m-d H:i:s' ),
];
$withdraw = dokan()->withdraw->create( $data );
if ( is_wp_error( $withdraw ) ) {
return $withdraw;
}
do_action( 'dokan_after_withdraw_request', $user_id, $withdraw->get_amount(), $withdraw->get_method(), $withdraw->get_id() );
/**
* Action hook `dokan_withdraw_disbursement_after_request_create`
*
* @since 3.5.0
*
* @param Withdraw $withdraw Created Withdraw Request.
*/
do_action( 'dokan_withdraw_disbursement_after_request_create', $withdraw );
}
/**
* Process announcement schedule.
*
* @since 3.5.0
*
* @param array $options
*
* @return void
*/
public function process_announcement_schedule( $options ) {
[ $methods, $admin_id ] = $options;
// @codingStandardsIgnoreStart
$args = [
'role__in' => [
'administrator',
'seller',
],
'meta_key' => 'dokan_withdraw_default_method',
'meta_value' => array_keys( $methods ),
'meta_compare' => 'IN',
'post_per_page' => -1,
'fields' => 'ID',
];
// @codingStandardsIgnoreEnd
$user_query = new \WP_User_Query( $args );
if ( empty( $user_query->get_results() ) ) {
return;
}
$args = [
'title' => __( 'Withdraw method disabled', 'dokan' ),
'status' => 'publish',
'author' => $admin_id,
'announcement_type' => 'selected_seller',
'sender_ids' => $user_query->get_results(),
'content' => __( 'The withdraw method you have set as default is disabled by admin.', 'dokan' ),
];
dokan_pro()->announcement->manager->create_announcement( $args );
}
/**
* Process disbursement schedule change announcement schedule.
*
* @since 3.7.16
*
* @param array $options
*
* @return void
*/
public function process_schedule_change_announcement_schedule( $options ) {
[ $methods, $admin_id ] = $options;
// @codingStandardsIgnoreStart
$args = [
'role__in' => [
'administrator',
'seller',
],
'meta_key' => 'dokan_withdraw_selected_schedule',
'meta_value' => array_keys( $methods ),
'meta_compare' => 'IN',
'post_per_page' => -1,
'fields' => 'ID',
];
// @codingStandardsIgnoreEnd
$user_query = new \WP_User_Query( $args );
if ( empty( $user_query->get_results() ) ) {
return;
}
$args = [
'title' => __( 'Your preferred withdrawal schedule is disabled.', 'dokan' ),
'status' => 'publish',
'author' => $admin_id,
'announcement_type' => 'selected_seller',
'sender_ids' => $user_query->get_results(),
'content' => __( "The admin has disabled the withdrawal schedule that you had set as your preferred payment schedule. Please reschedule it from the vendor dashboard's withdrawal page.", 'dokan' ),
];
dokan_pro()->announcement->manager->create_announcement( $args );
}
/**
* Handle timezone change.
*
* @since 3.5.0
*
* @param array $old_value
* @param array $value
* @param string $option
*
* @return void
*/
public function handle_timezone_change( $old_value, $value, $option ) {
$this->reschedule();
}
/**
* Handle Schedule change.
*
* @since 3.5.0
* @since 3.7.16 Handle admin withdrawal schedule change.
*
* @param array $old_value
* @param array $value
* @param string $option
*
* @return void
*/
public function handle_schedule_change( $old_value, $value, $option ) {
if ( ! isset( $old_value['disbursement_schedule'], $value['disbursement_schedule'] ) || empty( array_diff_assoc( $old_value['disbursement_schedule'], $value['disbursement_schedule'] ) ) ) {
return;
}
$this->reschedule();
$this->handle_admin_withdraw_schedule_change( $old_value, $value, $option );
}
/**
* Handle Schedule settings change.
*
* @since 3.5.0
*
* @param array $old_value
* @param array $value
* @param string $option
*
* @return void
*/
public function handle_schedule_settings_change( $old_value, $value, $option ) {
if (
(
isset( $old_value['quarterly_schedule'], $value['quarterly_schedule'] )
&& ! empty( array_diff_assoc( $old_value['quarterly_schedule'], $value['quarterly_schedule'] ) )
)
|| (
isset( $old_value['monthly_schedule'], $value['monthly_schedule'] )
&& ! empty( array_diff_assoc( $old_value['monthly_schedule'], $value['monthly_schedule'] ) )
)
|| (
isset( $old_value['biweekly_schedule'], $value['biweekly_schedule'] )
&& ! empty( array_diff_assoc( $old_value['biweekly_schedule'], $value['biweekly_schedule'] ) )
)
|| (
isset( $old_value['weekly_schedule'], $value['weekly_schedule'] )
&& $old_value['weekly_schedule'] !== $value['weekly_schedule']
)
) {
$this->reschedule();
}
}
/**
* Handle withdraw operation enable disable.
*
* @since 3.5.0
*
* @param array $old_value
* @param array $value
* @param string $option
*
* @return void
*/
public function handle_withdraw_operation_enable_disable( $old_value, $value, $option ) {
if ( ! isset( $old_value['hide_withdraw_option'], $value['hide_withdraw_option'] ) || $old_value['hide_withdraw_option'] === $value['hide_withdraw_option'] ) {
return;
}
$this->reschedule();
}
/**
* Handle withdraw methods enable disable.
*
* @since 3.5.0
*
* @param array $old_value
* @param array $value
* @param string $option
*
* @return void
*/
public function handle_admin_withdraw_method_change( $old_value, $value, $option ) {
if (
! isset( $value['send_announcement_for_payment_change'] )
|| empty( $value['send_announcement_for_payment_change'] )
|| ! is_array( $value['send_announcement_for_payment_change'] )
) {
return;
}
as_enqueue_async_action(
'dokan_withdraw_disbursement_announcement_scheduler',
[
[
$value['send_announcement_for_payment_change'],
dokan_get_current_user_id(),
],
],
'dokan_withdraw_disbursement_announcement'
);
}
/**
* Handle withdraw disbursement schedule enable disable.
*
* @since 3.7.16
*
* @param array $old_value
* @param array $value
* @param string $option
*
* @return void
*/
public function handle_admin_withdraw_schedule_change( $old_value, $value, $option ) {
if (
empty( $value['send_announcement_for_disbursement_schedule_change'] )
|| ! is_array( $value['send_announcement_for_disbursement_schedule_change'] )
) {
return;
}
as_enqueue_async_action(
'dokan_withdraw_disbursement_schedule_announcement_scheduler',
[
[
$value['send_announcement_for_disbursement_schedule_change'],
dokan_get_current_user_id(),
],
],
'dokan_withdraw_disbursement_announcement'
);
}
/**
* Unset Seller dashboard withdraw page.
*
* @since 3.5.0
*
* @param array $urls
*
* @return array
*/
public function unset_withdraw_page_menu( $urls ) {
if ( ! Helper::is_withdraw_operation_enabled() ) {
if ( array_key_exists( 'withdraw', $urls ) ) {
unset( $urls['withdraw'] );
}
if ( array_key_exists( 'withdraw-requests', $urls ) ) {
unset( $urls['withdraw-requests'] );
}
}
return $urls;
}
/**
* Validate Withdraw Disbursement system admin settings.
*
* @since 3.5.0
*
* @param array $option_name
* @param array $option_value
*
* @return void
*/
public function validate_withdraw_schedule_option( $option_name, $option_value ) {
if ( 'dokan_withdraw' !== $option_name ) {
return;
}
if ( empty( $option_value['disbursement'] ) ) {
$errors[] = [
'name' => 'disbursement',
'error' => __( 'Here must be at least one Withdraw Disbursement system that needs to be activated.', 'dokan' ),
];
}
if ( ! empty( $errors ) ) {
wp_send_json_error(
[
'settings' => [
'name' => $option_name,
'value' => $option_value,
],
'message' => __( 'Validation error', 'dokan' ),
'errors' => $errors,
],
400
);
}
}
/**
* Disable manual withdraw system.
*
* @since 3.5.0
*
* @return bool
*/
public function enable_manual_withdraw() {
return Helper::is_manual_withdraw_enabled();
}
/**
* Save Skrill progress settings data
*
* @since 3.5.6
*
* @return void
**/
public function save_skrill_progress( $store_id, $dokan_settings ) {
if ( ! $store_id ) {
return;
}
if ( empty( $_POST['_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_POST['_wpnonce'] ), 'dokan_payment_settings_nonce' ) ) {
return;
}
if ( isset( $_POST['settings']['skrill'] ) && isset( $_POST['settings']['skrill']['email'] ) ) {
$dokan_settings['payment']['skrill'] = array(
'email' => sanitize_email( wp_unslash( $_POST['settings']['skrill']['email'] ) ),
);
update_user_meta( $store_id, 'dokan_profile_settings', $dokan_settings );
}
}
/**
* Save Skrill data.
*
* @param \WeDevs\Dokan\Vendor\Vendor $store
* @param \WP_REST_Request $request
*
* @return void
*/
public function save_api_skrill_progress( $store, $request ) {
$params = $request->get_params();
$dokan_profile_settings = $store->get_meta( 'dokan_profile_settings', true );
$upcomming_payment = $params['payment'];
$saved_payment = $dokan_profile_settings['payment'];
if ( empty( $upcomming_payment['skrill'] ) ) {
return;
}
$saved_payment['skrill'] = $upcomming_payment['skrill'] ?? [];
$dokan_profile_settings['payment'] = $saved_payment;
update_user_meta( $store->get_id(), 'dokan_profile_settings', $dokan_profile_settings );
}
/**
* Get the Withdrawal method icon
*
* @since 3.5.6
*
* @param string $method_icon
* @param string $method_key
*
* @return string
*/
public function get_icon( $method_icon, $method_key ) {
if ( 'skrill' === $method_key ) {
$method_icon = DOKAN_PRO_PLUGIN_ASSEST . '/images/skrill-withdraw-method.svg';
}
return $method_icon;
}
/**
* Get the heading for this payment's settings page
*
* @since 3.5.6
*
* @param string $heading
* @param string $slug
*
* @return string
*/
public function get_heading( $heading, $slug ) {
if ( false !== strpos( $slug, 'skrill' ) ) {
$heading = __( 'Skrill Settings', 'dokan' );
}
return $heading;
}
/**
* Maps the required fields for custom withdraw method settings.
*
* @since 3.6.1
*
* @param array $required_fields
* @param string $method_key
* @param int|string $seller_id
*
* @return array
*/
public function map_required_fields( $required_fields, $method_key, $seller_id ) {
if ( 'skrill' === $method_key ) {
$required_fields = [ 'email' ];
}
return $required_fields;
}
/**
* Include Skrill to withdrawable payment methods
*
* @since 3.7.1
*
* @param array $payment_methods
*
* @return array
*/
public function include_skrill_to_payment_methods( $payment_methods ) {
$payment_methods[] = 'skrill';
return $payment_methods;
}
/**
* Mask custom withdraw payment method.
*
* @since 3.7.27
*
* @param string $method_info Withdraw method information
* @param string $method_key Withdraw Method key
*
* @return string
*/
public function mask_custom_withdraw_method( $method_info, $method_key ) {
$no_information = __( 'No information found.', 'dokan' );
$profile_settings = get_user_meta( dokan_get_current_user_id(), 'dokan_profile_settings' );
$payment_methods = ! empty( $profile_settings[0]['payment'] ) ? $profile_settings[0]['payment'] : [];
if ( 'dokan_custom' === $method_key ) {
// translators: 1: custom payment for withdraw method.
$method_info = empty( $payment_methods[ $method_key ]['value'] ) ? $no_information : sprintf( __( '( %1$s )', 'dokan' ), dokan_mask_string( $payment_methods[ $method_key ]['value'] ) );
}
return $method_info;
}
/**
* Add description.
*
* @param $methods
* @param $gateways
*
* @return array
*/
public function add_description_for_skrill_method( $methods, $gateways ) {
if ( isset( $methods['skrill'] ) ) {
$methods['skrill']['description'] = __( 'Accept payments securely online with Skrill.', 'dokan' );
}
return $methods;
}
}