PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 4.0.0
Tutor LMS – eLearning and online course solution v4.0.0
4.0.0 3.9.15 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 22 hours ago Admin.php 22 hours ago Ajax.php 22 hours ago Announcements.php 22 hours ago Assets.php 22 hours ago Backend_Page_Trait.php 1 year ago BaseController.php 1 year ago Config.php 22 hours ago Container.php 11 months ago Course.php 22 hours ago Course_Embed.php 3 years ago Course_Filter.php 22 hours ago Course_List.php 22 hours ago Course_Settings_Tabs.php 22 hours ago Course_Widget.php 1 year ago Custom_Validation.php 22 hours ago Dashboard.php 22 hours ago Earnings.php 9 months ago FormHandler.php 22 hours ago Frontend.php 22 hours ago Gutenberg.php 1 year ago Icon.php 22 hours ago Input.php 22 hours ago Instructor.php 22 hours ago Instructors_List.php 22 hours ago Lesson.php 22 hours ago Options_V2.php 22 hours ago Permalink.php 22 hours ago Post_types.php 2 days ago Private_Course_Access.php 22 hours ago Q_And_A.php 22 hours ago Question_Answers_List.php 11 months ago Quiz.php 22 hours ago QuizBuilder.php 22 hours ago Quiz_Attempts_List.php 22 hours ago RestAPI.php 2 years ago Reviews.php 22 hours ago Rewrite_Rules.php 2 years ago SampleCourse.php 22 hours ago Shortcode.php 22 hours ago Singleton.php 1 year ago Student.php 22 hours ago Students_List.php 1 year ago Taxonomies.php 1 year ago Template.php 22 hours ago Theme_Compatibility.php 3 years ago Tools.php 1 year ago Tools_V2.php 4 weeks ago Tutor.php 22 hours ago TutorEDD.php 22 hours ago Tutor_Base.php 2 years ago Tutor_Setup.php 22 hours ago Upgrader.php 22 hours ago User.php 22 hours ago UserPreference.php 22 hours ago Utils.php 22 hours ago Video_Stream.php 3 years ago WhatsNew.php 10 months ago Withdraw.php 22 hours ago Withdraw_Requests_List.php 11 months ago WooCommerce.php 22 hours ago
Withdraw.php
356 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 use Tutor\Traits\JsonResponse;
16
17 if ( ! defined( 'ABSPATH' ) ) {
18 exit;
19 }
20
21 /**
22 * Withdraw class
23 *
24 * @since 1.0.0
25 */
26 class Withdraw {
27 use JsonResponse;
28
29 /**
30 * Withdraw method
31 *
32 * @since 1.0.0
33 *
34 * @var mixed
35 */
36 public $withdraw_methods;
37
38 /**
39 * Register hooks
40 *
41 * @since 1.0.0
42 */
43 public function __construct() {
44 add_action( 'wp_ajax_tutor_save_withdraw_account', array( $this, 'tutor_save_withdraw_account' ) );
45 add_action( 'wp_ajax_tutor_make_an_withdraw', array( $this, 'tutor_make_an_withdraw' ) );
46 add_filter( 'tutor_withdrawal_methods_all', array( $this, 'withdraw_methods_all' ) );
47 add_filter( 'tutor_withdrawal_methods_available', array( $this, 'withdraw_methods_available' ) );
48 }
49
50 /**
51 * Available withdraw methods
52 *
53 * @since 1.0.0
54 *
55 * @return array
56 */
57 public function withdraw_methods_all() {
58
59 $this->migrate_withdrawal_method_data();
60
61 $methods = array(
62 'bank_transfer_withdraw' => array(
63 'method_name' => __( 'Bank Transfer', 'tutor' ),
64 'image' => tutor()->url . 'assets/images/payment-bank.png',
65 'desc' => __( 'Get your payment directly into your bank account', 'tutor' ),
66
67 'form_fields' => array(
68 'account_name' => array(
69 'type' => 'text',
70 'label' => __( 'Account Name', 'tutor' ),
71 ),
72 'account_number' => array(
73 'type' => 'text',
74 'label' => __( 'Account Number', 'tutor' ),
75 ),
76 'bank_name' => array(
77 'type' => 'text',
78 'label' => __( 'Bank Name', 'tutor' ),
79 ),
80 'iban' => array(
81 'type' => 'text',
82 'label' => __( 'IBAN', 'tutor' ),
83 ),
84 'swift' => array(
85 'type' => 'text',
86 'label' => __( 'BIC / SWIFT', 'tutor' ),
87 ),
88
89 ),
90 ),
91
92 'echeck_withdraw' => array(
93 'method_name' => __( 'E-Check', 'tutor' ),
94 'image' => tutor()->url . 'assets/images/payment-echeck.png',
95 'form_fields' => array(
96 'physical_address' => array(
97 'type' => 'text',
98 'label' => __( 'Your Physical Address', 'tutor' ),
99 'desc' => __( 'We will send you an E-Check to this address directly.', 'tutor' ),
100 ),
101 ),
102 ),
103
104 'paypal_withdraw' => array(
105 'method_name' => __( 'PayPal', 'tutor' ),
106 'image' => tutor()->url . 'assets/images/payment-paypal.png',
107 'form_fields' => array(
108 'paypal_email' => array(
109 'type' => 'email',
110 'label' => __( 'PayPal E-Mail Address', 'tutor' ),
111 'desc' => __( 'We will use this email address to send the money to your Paypal account', 'tutor' ),
112 ),
113
114 ),
115 ),
116 );
117
118 $saved_options = (array) get_option( 'tutor_option', array() );
119 $withdrawal_payment_methods = $saved_options['tutor_withdrawal_methods'] ?? array();
120 foreach ( $methods as $key => $method ) {
121 $methods[ $key ]['enabled'] = in_array( $key, $withdrawal_payment_methods, true );
122 }
123
124 return apply_filters( 'tutor_withdraw_methods', $methods );
125 }
126
127 /**
128 * Withdraw method's tab
129 *
130 * @return void
131 */
132 private function migrate_withdrawal_method_data() {
133 $old_data = get_option( 'tutor_withdraw_options', null );
134
135 if ( ! $old_data ) {
136 // Return if already migrated.
137 return;
138 }
139
140 $withdraw_options = (array) maybe_unserialize( $old_data );
141 $new_methods_array = array();
142
143 foreach ( $withdraw_options as $key => $option ) {
144 if ( is_array( $option ) ) {
145
146 // Set enable state.
147 if ( isset( $option['enabled'] ) ) {
148 $option['enabled'] ? $new_methods_array[] = $key : 0;
149 }
150
151 // Set instruction.
152 if ( isset( $option['instruction'] ) ) {
153 tutor_utils()->update_option( 'tutor_' . $key . '_instruction', $option['instruction'] );
154 }
155 }
156 }
157
158 // Update new.
159 tutor_utils()->update_option( 'tutor_withdrawal_methods', $new_methods_array );
160
161 // Delete old.
162 delete_option( 'tutor_withdraw_options' );
163 }
164
165 /**
166 * Return only enabled methods
167 *
168 * @since 1.0.0
169 *
170 * @return mixed|array
171 */
172 public function withdraw_methods_available() {
173 $methods = $this->withdraw_methods_all();
174 $withdraw_options = tutor_utils()->get_option( 'tutor_withdrawal_methods', array() );
175
176 foreach ( $methods as $method_id => $method ) {
177 if ( ! in_array( $method_id, $withdraw_options ) ) {
178 // Remove the unavailable methods from array.
179 unset( $methods[ $method_id ] );
180 }
181 }
182
183 return $methods;
184 }
185
186 /**
187 * Save Withdraw Method Data
188 *
189 * @since 1.2.0
190 *
191 * @return void send wp_json response
192 */
193 public function tutor_save_withdraw_account() {
194 // Checking nonce.
195 tutor_utils()->checking_nonce();
196
197 //phpcs:disable WordPress.Security.NonceVerification.Missing -- nonce already verified
198 $user_id = get_current_user_id();
199 $method = sanitize_text_field( tutor_utils()->avalue_dot( 'tutor_selected_withdraw_method', $_POST ) );
200 if ( ! $method ) {
201 wp_send_json_error();
202 }
203
204 $method_data = tutor_utils()->avalue_dot( 'withdraw_method_field.' . $method, $_POST );
205 $available_withdraw_method = $this->withdraw_methods_all();
206
207 if ( tutor_utils()->count( $method_data ) ) {
208 $saved_data = array();
209 $saved_data['withdraw_method_key'] = $method;
210 $saved_data['withdraw_method_name'] = tutor_utils()->avalue_dot( $method . '.method_name', $available_withdraw_method );
211
212 foreach ( $method_data as $input_name => $value ) {
213 $saved_data[ $input_name ]['value'] = esc_sql( sanitize_text_field( $value ) );
214 $saved_data[ $input_name ]['label'] = tutor_utils()->avalue_dot( $method . ".form_fields.{$input_name}.label", $available_withdraw_method );
215 }
216
217 update_user_meta( $user_id, '_tutor_withdraw_method_data', $saved_data );
218 update_user_meta( $user_id, '_tutor_withdraw_selected_method', $method );
219 update_user_meta( $user_id, '_tutor_withdraw_method_data_' . $method, $saved_data );
220 }
221
222 $msg = apply_filters( 'tutor_withdraw_method_set_success_msg', __( 'Withdrawal information saved!', 'tutor' ) );
223 wp_send_json_success( array( 'msg' => $msg ) );
224 }
225
226 /**
227 * Handle withdraw request form submit.
228 *
229 * @since 1.0.0
230 *
231 * @return void
232 *
233 * @throws Exception If any validation fails.
234 */
235 public function tutor_make_an_withdraw() {
236 global $wpdb;
237
238 tutor_utils()->checking_nonce();
239
240 $user_id = get_current_user_id();
241 if ( ! tutor_utils()->is_instructor( $user_id ) ) {
242 wp_send_json_error( array( 'msg' => tutor_utils()->error_message() ) );
243 }
244
245 $lock_name = 'tutor_withdraw_lock_' . $user_id;
246 $locked = $wpdb->get_var( $wpdb->prepare( 'SELECT GET_LOCK(%s, 10)', $lock_name ) );
247
248 if ( 1 !== (int) $locked ) {
249 wp_send_json_error(
250 array(
251 'msg' => __( 'Another withdrawal request is in progress. Please try again.', 'tutor' ),
252 )
253 );
254 }
255
256 try {
257 $withdraw_amount = (float) Input::post( 'amount' );
258 $earning_summary = WithdrawModel::get_withdraw_summary( $user_id );
259 $min_withdraw = (float) tutor_utils()->get_option( 'min_withdraw_amount' );
260
261 if ( ( $earning_summary->total_pending + $withdraw_amount ) > $earning_summary->available_for_withdraw ) {
262 throw new Exception(
263 wp_sprintf(
264 /* translators: 1: total pending withdraw request 2: available for withdraw */
265 __( "You have total %1\$s pending withdraw request. You can't make more than %2\$s withdraw request at a time", 'tutor' ),
266 $earning_summary->total_pending,
267 $earning_summary->available_for_withdraw
268 )
269 );
270 }
271
272 $saved_withdraw_account = WithdrawModel::get_user_withdraw_method();
273 $formatted_min_withdraw_amount = tutor_utils()->tutor_price( $min_withdraw );
274
275 if ( ! tutor_utils()->count( $saved_withdraw_account ) ) {
276 $no_withdraw_method = apply_filters( 'tutor_no_withdraw_method_msg', __( 'Please save withdraw method ', 'tutor' ) );
277 throw new Exception( $no_withdraw_method );
278 }
279
280 if ( ( ! is_numeric( $withdraw_amount ) && ! is_float( $withdraw_amount ) ) || $withdraw_amount < $min_withdraw ) {
281 /* translators: 1: strong tag start 2: min withdrawal amount 3: strong tag end */
282 $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>' ) );
283 throw new Exception( $required_min_withdraw );
284 }
285
286 if ( $earning_summary->available_for_withdraw < $withdraw_amount ) {
287 $insufficient_balence = apply_filters( 'tutor_withdraw_insufficient_balance_msg', __( 'Insufficient balance.', 'tutor' ) );
288 throw new Exception( $insufficient_balence );
289 }
290
291 $date = gmdate( 'Y-m-d H:i:s', tutor_time() );
292
293 $withdraw_data = apply_filters(
294 'tutor_pre_withdraw_data',
295 array(
296 'user_id' => $user_id,
297 'amount' => $withdraw_amount,
298 'method_data' => maybe_serialize( $saved_withdraw_account ),
299 'status' => 'pending',
300 'created_at' => $date,
301 )
302 );
303
304 do_action( 'tutor_insert_withdraw_before', $withdraw_data );
305
306 $inserted = $wpdb->insert( $wpdb->prefix . 'tutor_withdraws', $withdraw_data );
307 if ( false === $inserted ) {
308 throw new Exception( __( 'Unable to process withdrawal request. Please try again.', 'tutor' ) );
309 }
310
311 $withdraw_id = $wpdb->insert_id;
312
313 do_action( 'tutor_insert_withdraw_after', $withdraw_id, $withdraw_data );
314
315 /**
316 * Getting earning and balance data again
317 */
318 $earning = WithdrawModel::get_withdraw_summary( $user_id );
319 $new_available_balance = tutor_utils()->tutor_price( $earning->available_for_withdraw );
320
321 do_action( 'tutor_withdraw_after' );
322
323 $response = array(
324 'msg' => apply_filters( 'tutor_withdraw_successful_msg', __( 'Withdrawal Request Sent!', 'tutor' ) ),
325 'available_balance' => $new_available_balance,
326 );
327
328 } catch ( Exception $e ) {
329
330 $response = array(
331 'error' => true,
332 'msg' => $e->getMessage(),
333 );
334
335 } finally {
336
337 $wpdb->query(
338 $wpdb->prepare(
339 'SELECT RELEASE_LOCK(%s)',
340 $lock_name
341 )
342 );
343 }
344
345 if ( ! empty( $response['error'] ) ) {
346 wp_send_json_error(
347 array(
348 'msg' => $response['msg'],
349 )
350 );
351 }
352
353 wp_send_json_success( $response );
354 }
355 }
356