PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 3.9.14
Tutor LMS – eLearning and online course solution v3.9.14
3.9.14 3.9.13 3.9.12 3.9.11 trunk 1.0.0 1.0.0-alpha 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.2.0 1.2.1 1.2.11 1.2.12 1.2.13 1.2.20 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 1.7.6 1.7.7 1.7.8 1.7.9 1.8.0 1.8.1 1.8.10 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9.0 1.9.1 1.9.10 1.9.11 1.9.12 1.9.13 1.9.14 1.9.15 1.9.16 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.1 2.0.10 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1.0 2.1.1 2.1.10 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.3.0 2.4.0 2.5.0 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 3.0.0 3.0.1 3.0.2 3.1.0 3.2.0 3.2.1 3.2.2 3.2.3 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.7.0 3.7.1 3.7.2 3.7.3 3.7.4 3.8.0 3.8.1 3.8.2 3.8.3 3.9.0 3.9.1 3.9.10 3.9.2 3.9.3 3.9.4 3.9.5 3.9.6 3.9.7 3.9.8 3.9.9
tutor / classes / Withdraw.php
tutor / classes Last commit date
Addons.php 11 months ago Admin.php 2 months ago Ajax.php 9 months ago Announcements.php 1 year ago Assets.php 2 months ago Backend_Page_Trait.php 1 year ago BaseController.php 1 year ago Config.php 11 months ago Container.php 11 months ago Course.php 2 months ago Course_Embed.php 3 years ago Course_Filter.php 1 year ago Course_List.php 5 months ago Course_Settings_Tabs.php 1 year ago Course_Widget.php 1 year ago Custom_Validation.php 3 years ago Dashboard.php 1 year ago Earnings.php 9 months ago FormHandler.php 2 years ago Frontend.php 1 year ago Gutenberg.php 1 year ago Icon.php 8 months ago Input.php 1 year ago Instructor.php 2 months ago Instructors_List.php 2 months ago Lesson.php 2 weeks ago Options_V2.php 7 months ago Permalink.php 2 years ago Post_types.php 1 year ago Private_Course_Access.php 1 year ago Q_And_A.php 10 months ago Question_Answers_List.php 11 months ago Quiz.php 2 weeks ago QuizBuilder.php 2 days ago Quiz_Attempts_List.php 9 months ago RestAPI.php 2 years ago Reviews.php 9 months ago Rewrite_Rules.php 2 years ago Shortcode.php 9 months ago Singleton.php 1 year ago Student.php 2 months ago Students_List.php 1 year ago Taxonomies.php 1 year ago Template.php 9 months ago Theme_Compatibility.php 3 years ago Tools.php 1 year ago Tools_V2.php 3 weeks ago Tutor.php 2 months ago TutorEDD.php 1 year ago Tutor_Base.php 2 years ago Tutor_Setup.php 8 months ago Upgrader.php 9 months ago User.php 4 months ago Utils.php 2 days ago Video_Stream.php 3 years ago WhatsNew.php 9 months ago Withdraw.php 2 days ago Withdraw_Requests_List.php 11 months ago WooCommerce.php 2 days ago
Withdraw.php
354 lines
1 <?php
2 /**
3 * Withdraw class
4 *
5 * @package Tutor\Withdraw
6 * @author Themeum <support@themeum.com>
7 * @link https://themeum.com
8 * @since 1.0.0
9 */
10
11 namespace TUTOR;
12
13 use Exception;
14 use Tutor\Models\WithdrawModel;
15
16 if ( ! defined( 'ABSPATH' ) ) {
17 exit;
18 }
19
20 /**
21 * Withdraw class
22 *
23 * @since 1.0.0
24 */
25 class Withdraw {
26
27 /**
28 * Withdraw method
29 *
30 * @since 1.0.0
31 *
32 * @var mixed
33 */
34 public $withdraw_methods;
35
36 /**
37 * Register hooks
38 *
39 * @since 1.0.0
40 */
41 public function __construct() {
42 add_action( 'wp_ajax_tutor_save_withdraw_account', array( $this, 'tutor_save_withdraw_account' ) );
43 add_action( 'wp_ajax_tutor_make_an_withdraw', array( $this, 'tutor_make_an_withdraw' ) );
44 add_filter( 'tutor_withdrawal_methods_all', array( $this, 'withdraw_methods_all' ) );
45 add_filter( 'tutor_withdrawal_methods_available', array( $this, 'withdraw_methods_available' ) );
46 }
47
48 /**
49 * Available withdraw methods
50 *
51 * @since 1.0.0
52 *
53 * @return array
54 */
55 public function withdraw_methods_all() {
56
57 $this->migrate_withdrawal_method_data();
58
59 $methods = array(
60 'bank_transfer_withdraw' => array(
61 'method_name' => __( 'Bank Transfer', 'tutor' ),
62 'image' => tutor()->url . 'assets/images/payment-bank.png',
63 'desc' => __( 'Get your payment directly into your bank account', 'tutor' ),
64
65 'form_fields' => array(
66 'account_name' => array(
67 'type' => 'text',
68 'label' => __( 'Account Name', 'tutor' ),
69 ),
70 'account_number' => array(
71 'type' => 'text',
72 'label' => __( 'Account Number', 'tutor' ),
73 ),
74 'bank_name' => array(
75 'type' => 'text',
76 'label' => __( 'Bank Name', 'tutor' ),
77 ),
78 'iban' => array(
79 'type' => 'text',
80 'label' => __( 'IBAN', 'tutor' ),
81 ),
82 'swift' => array(
83 'type' => 'text',
84 'label' => __( 'BIC / SWIFT', 'tutor' ),
85 ),
86
87 ),
88 ),
89
90 'echeck_withdraw' => array(
91 'method_name' => __( 'E-Check', 'tutor' ),
92 'image' => tutor()->url . 'assets/images/payment-echeck.png',
93 'form_fields' => array(
94 'physical_address' => array(
95 'type' => 'text',
96 'label' => __( 'Your Physical Address', 'tutor' ),
97 'desc' => __( 'We will send you an E-Check to this address directly.', 'tutor' ),
98 ),
99 ),
100 ),
101
102 'paypal_withdraw' => array(
103 'method_name' => __( 'PayPal', 'tutor' ),
104 'image' => tutor()->url . 'assets/images/payment-paypal.png',
105 'form_fields' => array(
106 'paypal_email' => array(
107 'type' => 'email',
108 'label' => __( 'PayPal E-Mail Address', 'tutor' ),
109 'desc' => __( 'We will use this email address to send the money to your Paypal account', 'tutor' ),
110 ),
111
112 ),
113 ),
114 );
115
116 $saved_options = (array) get_option( 'tutor_option', array() );
117 $withdrawal_payment_methods = $saved_options['tutor_withdrawal_methods'] ?? array();
118 foreach ( $methods as $key => $method ) {
119 $methods[ $key ]['enabled'] = in_array( $key, $withdrawal_payment_methods, true );
120 }
121
122 return apply_filters( 'tutor_withdraw_methods', $methods );
123 }
124
125 /**
126 * Withdraw method's tab
127 *
128 * @return void
129 */
130 private function migrate_withdrawal_method_data() {
131 $old_data = get_option( 'tutor_withdraw_options', null );
132
133 if ( ! $old_data ) {
134 // Return if already migrated.
135 return;
136 }
137
138 $withdraw_options = (array) maybe_unserialize( $old_data );
139 $new_methods_array = array();
140
141 foreach ( $withdraw_options as $key => $option ) {
142 if ( is_array( $option ) ) {
143
144 // Set enable state.
145 if ( isset( $option['enabled'] ) ) {
146 $option['enabled'] ? $new_methods_array[] = $key : 0;
147 }
148
149 // Set instruction.
150 if ( isset( $option['instruction'] ) ) {
151 tutor_utils()->update_option( 'tutor_' . $key . '_instruction', $option['instruction'] );
152 }
153 }
154 }
155
156 // Update new.
157 tutor_utils()->update_option( 'tutor_withdrawal_methods', $new_methods_array );
158
159 // Delete old.
160 delete_option( 'tutor_withdraw_options' );
161 }
162
163 /**
164 * Return only enabled methods
165 *
166 * @since 1.0.0
167 *
168 * @return mixed|array
169 */
170 public function withdraw_methods_available() {
171 $methods = $this->withdraw_methods_all();
172 $withdraw_options = tutor_utils()->get_option( 'tutor_withdrawal_methods', array() );
173
174 foreach ( $methods as $method_id => $method ) {
175 if ( ! in_array( $method_id, $withdraw_options ) ) {
176 // Remove the unavailable methods from array.
177 unset( $methods[ $method_id ] );
178 }
179 }
180
181 return $methods;
182 }
183
184 /**
185 * Save Withdraw Method Data
186 *
187 * @since 1.2.0
188 *
189 * @return void send wp_json response
190 */
191 public function tutor_save_withdraw_account() {
192 // Checking nonce.
193 tutor_utils()->checking_nonce();
194
195 //phpcs:disable WordPress.Security.NonceVerification.Missing -- nonce already verified
196 $user_id = get_current_user_id();
197 $method = sanitize_text_field( tutor_utils()->avalue_dot( 'tutor_selected_withdraw_method', $_POST ) );
198 if ( ! $method ) {
199 wp_send_json_error();
200 }
201
202 $method_data = tutor_utils()->avalue_dot( 'withdraw_method_field.' . $method, $_POST );
203 $available_withdraw_method = $this->withdraw_methods_all();
204
205 if ( tutor_utils()->count( $method_data ) ) {
206 $saved_data = array();
207 $saved_data['withdraw_method_key'] = $method;
208 $saved_data['withdraw_method_name'] = tutor_utils()->avalue_dot( $method . '.method_name', $available_withdraw_method );
209
210 foreach ( $method_data as $input_name => $value ) {
211 $saved_data[ $input_name ]['value'] = esc_sql( sanitize_text_field( $value ) );
212 $saved_data[ $input_name ]['label'] = tutor_utils()->avalue_dot( $method . ".form_fields.{$input_name}.label", $available_withdraw_method );
213 }
214
215 update_user_meta( $user_id, '_tutor_withdraw_method_data', $saved_data );
216 update_user_meta( $user_id, '_tutor_withdraw_selected_method', $method );
217 update_user_meta( $user_id, '_tutor_withdraw_method_data_' . $method, $saved_data );
218 }
219
220 $msg = apply_filters( 'tutor_withdraw_method_set_success_msg', __( 'Withdrawal information saved!', 'tutor' ) );
221 wp_send_json_success( array( 'msg' => $msg ) );
222 }
223
224 /**
225 * Handle withdraw request form submit.
226 *
227 * @since 1.0.0
228 *
229 * @return void
230 *
231 * @throws Exception If any validation fails.
232 */
233 public function tutor_make_an_withdraw() {
234 global $wpdb;
235
236 tutor_utils()->checking_nonce();
237
238 $user_id = get_current_user_id();
239 if ( ! tutor_utils()->is_instructor( $user_id ) ) {
240 wp_send_json_error( array( 'msg' => tutor_utils()->error_message() ) );
241 }
242
243 $lock_name = 'tutor_withdraw_lock_' . $user_id;
244 $locked = $wpdb->get_var( $wpdb->prepare( 'SELECT GET_LOCK(%s, 10)', $lock_name ) );
245
246 if ( 1 !== (int) $locked ) {
247 wp_send_json_error(
248 array(
249 'msg' => __( 'Another withdrawal request is in progress. Please try again.', 'tutor' ),
250 )
251 );
252 }
253
254 try {
255 $withdraw_amount = (float) Input::post( 'tutor_withdraw_amount' );
256 $earning_summary = WithdrawModel::get_withdraw_summary( $user_id );
257 $min_withdraw = (float) tutor_utils()->get_option( 'min_withdraw_amount' );
258
259 if ( ( $earning_summary->total_pending + $withdraw_amount ) > $earning_summary->available_for_withdraw ) {
260 throw new Exception(
261 wp_sprintf(
262 /* translators: 1: total pending withdraw request 2: available for withdraw */
263 __( "You have total %1\$s pending withdraw request. You can't make more than %2\$s withdraw request at a time", 'tutor' ),
264 $earning_summary->total_pending,
265 $earning_summary->available_for_withdraw
266 )
267 );
268 }
269
270 $saved_withdraw_account = WithdrawModel::get_user_withdraw_method();
271 $formatted_min_withdraw_amount = tutor_utils()->tutor_price( $min_withdraw );
272
273 if ( ! tutor_utils()->count( $saved_withdraw_account ) ) {
274 $no_withdraw_method = apply_filters( 'tutor_no_withdraw_method_msg', __( 'Please save withdraw method ', 'tutor' ) );
275 throw new Exception( $no_withdraw_method );
276 }
277
278 if ( ( ! is_numeric( $withdraw_amount ) && ! is_float( $withdraw_amount ) ) || $withdraw_amount < $min_withdraw ) {
279 /* translators: 1: strong tag start 2: min withdrawal amount 3: strong tag end */
280 $required_min_withdraw = apply_filters( 'tutor_required_min_amount_msg', sprintf( __( 'Minimum withdrawal amount is %1$s %2$s %3$s ', 'tutor' ), '<strong>', $formatted_min_withdraw_amount, '</strong>' ) );
281 throw new Exception( $required_min_withdraw );
282 }
283
284 if ( $earning_summary->available_for_withdraw < $withdraw_amount ) {
285 $insufficient_balence = apply_filters( 'tutor_withdraw_insufficient_balance_msg', __( 'Insufficient balance.', 'tutor' ) );
286 throw new Exception( $insufficient_balence );
287 }
288
289 $date = gmdate( 'Y-m-d H:i:s', tutor_time() );
290
291 $withdraw_data = apply_filters(
292 'tutor_pre_withdraw_data',
293 array(
294 'user_id' => $user_id,
295 'amount' => $withdraw_amount,
296 'method_data' => maybe_serialize( $saved_withdraw_account ),
297 'status' => 'pending',
298 'created_at' => $date,
299 )
300 );
301
302 do_action( 'tutor_insert_withdraw_before', $withdraw_data );
303
304 $inserted = $wpdb->insert( $wpdb->prefix . 'tutor_withdraws', $withdraw_data );
305 if ( false === $inserted ) {
306 throw new Exception( __( 'Unable to process withdrawal request. Please try again.', 'tutor' ) );
307 }
308
309 $withdraw_id = $wpdb->insert_id;
310
311 do_action( 'tutor_insert_withdraw_after', $withdraw_id, $withdraw_data );
312
313 /**
314 * Getting earning and balance data again
315 */
316 $earning = WithdrawModel::get_withdraw_summary( $user_id );
317 $new_available_balance = tutor_utils()->tutor_price( $earning->available_for_withdraw );
318
319 do_action( 'tutor_withdraw_after' );
320
321 $response = array(
322 'msg' => apply_filters( 'tutor_withdraw_successful_msg', __( 'Withdrawal Request Sent!', 'tutor' ) ),
323 'available_balance' => $new_available_balance,
324 );
325
326 } catch ( Exception $e ) {
327
328 $response = array(
329 'error' => true,
330 'msg' => $e->getMessage(),
331 );
332
333 } finally {
334
335 $wpdb->query(
336 $wpdb->prepare(
337 'SELECT RELEASE_LOCK(%s)',
338 $lock_name
339 )
340 );
341 }
342
343 if ( ! empty( $response['error'] ) ) {
344 wp_send_json_error(
345 array(
346 'msg' => $response['msg'],
347 )
348 );
349 }
350
351 wp_send_json_success( $response );
352 }
353 }
354