PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 2.0.6
Tutor LMS – eLearning and online course solution v2.0.6
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 / WooCommerce.php
tutor / classes Last commit date
Addons.php 4 years ago Admin.php 4 years ago Ajax.php 4 years ago Announcements.php 4 years ago Assets.php 4 years ago Backend_Page_Trait.php 4 years ago Course.php 4 years ago Course_Filter.php 4 years ago Course_List.php 4 years ago Course_Settings_Tabs.php 4 years ago Course_Widget.php 4 years ago Custom_Validation.php 4 years ago Dashboard.php 4 years ago FormHandler.php 4 years ago Frontend.php 4 years ago Gutenberg.php 4 years ago Input.php 4 years ago Instructor.php 4 years ago Instructors_List.php 4 years ago Lesson.php 4 years ago Options_V2.php 4 years ago Post_types.php 4 years ago Private_Course_Access.php 4 years ago Q_and_A.php 4 years ago Question_Answers_List.php 4 years ago Quiz.php 4 years ago Quiz_Attempts_List.php 4 years ago RestAPI.php 4 years ago Reviews.php 4 years ago Rewrite_Rules.php 4 years ago Shortcode.php 4 years ago Student.php 4 years ago Students_List.php 4 years ago Taxonomies.php 4 years ago Template.php 4 years ago Theme_Compatibility.php 5 years ago Tools.php 4 years ago Tools_V2.php 4 years ago Tutor.php 4 years ago TutorEDD.php 4 years ago Tutor_Base.php 5 years ago Tutor_List_Table.php 4 years ago Tutor_Setup.php 4 years ago Upgrader.php 4 years ago User.php 4 years ago Utils.php 4 years ago Video_Stream.php 4 years ago Withdraw.php 4 years ago Withdraw_Requests_List.php 4 years ago WooCommerce.php 4 years ago
WooCommerce.php
655 lines
1 <?php
2
3 /**
4 * Created by PhpStorm.
5 * User: themeum
6 * Date: 1/10/18
7 * Time: 3:01 PM
8 */
9
10 namespace TUTOR;
11
12 if ( ! defined( 'ABSPATH' ) ) {
13 exit;
14 }
15
16 class WooCommerce extends Tutor_Base {
17
18 public function __construct() {
19 parent::__construct();
20
21 // Add option settings
22 add_filter( 'tutor_monetization_options', array( $this, 'tutor_monetization_options' ) );
23
24 $monetize_by = tutor_utils()->get_option( 'monetize_by' );
25 if ( $monetize_by !== 'wc' ) {
26 return;
27 }
28
29 add_filter( 'tutor/options/attr', array( $this, 'add_options' ) );
30
31 /**
32 * Is Course Purchasable
33 */
34 add_filter( 'is_course_purchasable', array( $this, 'is_course_purchasable' ), 10, 2 );
35 add_filter( 'get_tutor_course_price', array( $this, 'get_tutor_course_price' ), 10, 2 );
36 add_filter( 'tutor_course_sell_by', array( $this, 'tutor_course_sell_by' ) );
37
38 add_filter( 'product_type_options', array( $this, 'add_tutor_type_in_wc_product' ) );
39
40 add_action( 'add_meta_boxes', array( $this, 'register_meta_box' ) );
41 add_action( 'save_post_' . $this->course_post_type, array( $this, 'save_course_meta' ) );
42 add_action( 'save_post_product', array( $this, 'save_wc_product_meta' ) );
43
44 add_action( 'tutor_course/single/before/enroll', 'wc_print_notices' );
45
46 /**
47 * After place new order
48 */
49 add_action( 'woocommerce_new_order', array( $this, 'course_placing_order_from_admin' ), 10, 3 );
50 add_action( 'woocommerce_new_order_item', array( $this, 'course_placing_order_from_customer' ), 10, 3 );
51
52 /**
53 * Order Status Hook
54 *
55 * Remove course from active courses if an order is cancelled or refunded
56 */
57 add_action( 'woocommerce_order_status_changed', array( $this, 'enrolled_courses_status_change' ), 10, 3 );
58
59 /**
60 * Add Earning Data
61 */
62 add_action( 'woocommerce_new_order_item', array( $this, 'add_earning_data' ), 10, 3 );
63 add_action( 'woocommerce_order_status_changed', array( $this, 'add_earning_data_status_change' ), 10, 3 );
64
65 /**
66 * WC Print Notices After Enroll
67 *
68 * @since v.1.3.5
69 */
70 if ( tutor_utils()->has_wc() ) {
71 add_action( 'tutor_course/single/before/inner-wrap', 'wc_print_notices', 10 );
72 add_action( 'tutor_course/single/enrolled/before/inner-wrap', 'wc_print_notices', 10 );
73 }
74
75 /**
76 * Manage WooCommerce plugin dependency
77 *
78 * @since v.1.7.8
79 */
80 $woocommerce_path = dirname( dirname( __DIR__ ) ) . DIRECTORY_SEPARATOR . 'woocommerce' . DIRECTORY_SEPARATOR . 'woocommerce.php';
81 register_deactivation_hook( $woocommerce_path, array( $this, 'disable_tutor_monetization' ) );
82 /**
83 * Redirect student on enrolled courses after course
84 * enrolment complete
85 *
86 * @since 1.9.0
87 */
88 add_action( 'woocommerce_thankyou', array( $this, 'redirect_to_enrolled_courses' ) );
89
90 /**
91 * Change woo commerce cart product link if it is tutor product
92 */
93 add_filter( 'woocommerce_cart_item_permalink', array( $this, 'tutor_update_product_url' ), 10, 2 );
94 add_filter( 'woocommerce_order_item_permalink', array( $this, 'filter_order_item_permalink_callback' ), 10, 3 );
95
96 }
97
98 function filter_order_item_permalink_callback( $product_permalink, $item, $order ) {
99
100 // For product variations
101 if ( $item->get_variation_id() > 0 ) {
102 $product = $item->get_product();
103
104 $is_visible = $product && $product->is_visible();
105
106 // Get the instance of the parent variable product Object
107 $parent_product = wc_get_product( $item->get_product_id() );
108
109 // Return the parent product permalink (if product is visible)
110 return $is_visible ? $parent_product->get_permalink() : '';
111 }
112
113 $course_id = $this->get_post_id_by_meta_key_and_value( '_tutor_course_product_id', $item->get_product_id() );
114
115 return get_permalink( $course_id );
116 }
117
118 public function get_post_id_by_meta_key_and_value( $key, $value ) {
119 global $wpdb;
120 $meta = $wpdb->get_results( 'SELECT * FROM `' . $wpdb->postmeta . "` WHERE meta_key='" . esc_sql( $key ) . "' AND meta_value='" . esc_sql( $value ) . "'" );
121 if ( is_array( $meta ) && ! empty( $meta ) && isset( $meta[0] ) ) {
122 $meta = $meta[0];
123 }
124 if ( is_object( $meta ) ) {
125 return $meta->post_id;
126 } else {
127 return false;
128 }
129 }
130
131 public function is_course_purchasable( $bool, $course_id ) {
132 if ( ! tutor_utils()->has_wc() ) {
133 return false;
134 }
135
136 $course_id = tutor_utils()->get_post_id( $course_id );
137 $has_product_id = get_post_meta( $course_id, '_tutor_course_product_id', true );
138 if ( $has_product_id ) {
139 return true;
140 }
141 return false;
142 }
143
144 public function get_tutor_course_price( $price, $course_id ) {
145 $price = null;
146
147 if ( tutor_utils()->is_course_purchasable( $course_id ) ) {
148 if ( tutor_utils()->has_wc() ) {
149 $product_id = tutor_utils()->get_course_product_id( $course_id );
150 $product = wc_get_product( $product_id );
151
152 if ( $product ) {
153 ob_start();
154 ?>
155 <div class="price">
156 <?php echo $product->get_price_html(); ?>
157 </div>
158 <?php
159 return ob_get_clean();
160 }
161 }
162 }
163
164 return $price;
165 }
166
167 public function tutor_course_sell_by() {
168 return 'woocommerce';
169 }
170
171 public function add_tutor_type_in_wc_product( $types ) {
172 $types['tutor_product'] = array(
173 'id' => '_tutor_product',
174 'wrapper_class' => 'show_if_simple',
175 'label' => __( 'For Tutor', 'tutor' ),
176 'description' => __( 'This checkmark ensure that you will sell a specif course via this product.', 'tutor' ),
177 'default' => 'no',
178 );
179
180 return $types;
181 }
182
183 /**
184 * @param $post_ID
185 *
186 * Save course meta for attaching product
187 */
188 public function save_course_meta( $post_ID ) {
189 $product_id = (int) tutor_utils()->avalue_dot( '_tutor_course_product_id', $_POST, 0 );
190 if ( $product_id === -1 ) {
191 delete_post_meta( $post_ID, '_tutor_course_product_id' );
192 } elseif ( $product_id ) {
193 update_post_meta( $post_ID, '_tutor_course_product_id', $product_id );
194 // Mark product for woocommerce
195 update_post_meta( $product_id, '_virtual', 'yes' );
196 update_post_meta( $product_id, '_tutor_product', 'yes' );
197 }
198 }
199
200 public function register_meta_box() {
201 tutor_meta_box_wrapper( 'tutor-attach-product', __( 'Add Product', 'tutor' ), array( $this, 'course_add_product_metabox' ), $this->course_post_type, 'advanced', 'high', 'tutor-admin-post-meta' );
202 }
203
204 public function course_add_product_metabox() {
205 include tutor()->path . 'views/metabox/course-add-product-metabox.php';
206 }
207
208 public function save_wc_product_meta( $post_ID ) {
209 $is_tutor_product = sanitize_text_field( tutor_utils()->avalue_dot( '_tutor_product', $_POST ) );
210 if ( $is_tutor_product === 'on' ) {
211 update_post_meta( $post_ID, '_tutor_product', 'yes' );
212 } else {
213 delete_post_meta( $post_ID, '_tutor_product' );
214 }
215 }
216
217 /**
218 *
219 * Take enrolled course action based on order status change
220 */
221 public function enrolled_courses_status_change( $order_id, $status_from, $status_to ) {
222 if ( ! tutor_utils()->is_tutor_order( $order_id ) ) {
223 return;
224 }
225 global $wpdb;
226 // Get order & monetize data for auto complete.
227 $order = wc_get_order( $order_id );
228 $order_data = is_object( $order ) && method_exists( $order, 'get_data' ) ? $order->get_data() : array();
229 $payment_method = isset( $order_data['payment_method'] ) ? $order_data['payment_method'] : '';
230
231 $monetize_by = tutor_utils()->get_option( 'monetize_by' );
232 $should_auto_complete = tutor_utils()->get_option( 'tutor_woocommerce_order_auto_complete' );
233
234 $is_enabled_auto_complete = 'wc' === $monetize_by && $should_auto_complete ? true : false;
235 $enrolled_ids_with_course = $this->get_course_enrolled_ids_by_order_id( $order_id );
236
237 if ( $enrolled_ids_with_course ) {
238 $enrolled_ids = wp_list_pluck( $enrolled_ids_with_course, 'enrolled_id' );
239
240 if ( is_array( $enrolled_ids ) && count( $enrolled_ids ) ) {
241 foreach ( $enrolled_ids as $enrolled_id ) {
242 /**
243 * If order status is processing and payment is not cash on
244 * delivery then mark enrollment as completed.
245 *
246 * Note: Order status processing simply mean customer have done
247 * payment.
248 *
249 * @since v2.0.5
250 */
251 if ( ! is_admin() && 'processing' === $status_to && $is_enabled_auto_complete && 'cod' !== $payment_method ) {
252 tutor_utils()->course_enrol_status_change( $enrolled_id, 'completed' );
253 // Mark complete only from client side.
254 $mark_completed = self::mark_order_complete( $order_id );
255 if ( $mark_completed ) {
256 $user_id = get_post_field( 'post_author', $enrolled_id );
257 $course_id = get_post_field( 'post_parent', $enrolled_id );
258 do_action( 'tutor_after_enrolled', $course_id, $user_id, $enrolled_id );
259 }
260 } else {
261 tutor_utils()->course_enrol_status_change( $enrolled_id, $status_to );
262 }
263 // Invoke enrolled hook
264 if ( $status_to == 'completed' ) {
265 $user_id = get_post_field( 'post_author', $enrolled_id );
266 $course_id = get_post_field( 'post_parent', $enrolled_id );
267 do_action( 'tutor_after_enrolled', $course_id, $user_id, $enrolled_id );
268 }
269 }
270 }
271 }
272 }
273
274 /**
275 * @param $order_id
276 *
277 * @return array|bool
278 */
279 public function get_course_enrolled_ids_by_order_id( $order_id ) {
280 global $wpdb;
281 // Getting all of courses ids within this order
282
283 $courses_ids = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->postmeta} WHERE post_id = %d AND meta_key LIKE '_tutor_order_for_course_id_%' ", $order_id ) );
284
285 if ( is_array( $courses_ids ) && count( $courses_ids ) ) {
286 $course_enrolled_by_order = array();
287 foreach ( $courses_ids as $courses_id ) {
288 $course_id = str_replace( '_tutor_order_for_course_id_', '', $courses_id->meta_key );
289 // array(order_id => array('course_id' => $course_id, 'enrolled_id' => enrolled_id, 'order_id' => $courses_id->post_id))
290 $course_enrolled_by_order[] = array(
291 'course_id' => $course_id,
292 'enrolled_id' => $courses_id->meta_value,
293 'order_id' => $courses_id->post_id,
294 );
295 }
296 return $course_enrolled_by_order;
297 }
298 return false;
299 }
300
301 /**
302 * Remove course
303 *
304 * TODO: right now it's unused
305 */
306 public function remove_active_course( $order_id ) {
307 global $wpdb;
308 // Getting all of courses ids within this order
309
310 $courses_ids = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->postmeta} WHERE post_id = %d meta_key LIKE '_tutor_order_for_course_id_%' ", $order_id ) );
311 }
312
313
314 /**
315 * @param $attr
316 *
317 * @return mixed
318 *
319 * Add option for WooCommerce settings
320 */
321 public function add_options( $attr ) {
322 $attr['monetization']['blocks']['block_options']['fields'][] = array(
323 'key' => 'enable_guest_course_cart',
324 'type' => 'toggle_switch',
325 'label' => __( 'Enable Guest Mode', 'tutor' ),
326 'label_title' => __( '', 'tutor' ),
327 'default' => 'off',
328 'desc' => __( 'Allow customers to place orders without an account.', 'tutor' ),
329 );
330
331 return $attr;
332 }
333
334 /**
335 * @param $arr
336 *
337 * @return mixed
338 *
339 * Returning monetization options
340 *
341 * @since v.1.3.5
342 */
343 public function tutor_monetization_options( $arr ) {
344 $has_wc = tutor_utils()->has_wc();
345 if ( $has_wc ) {
346 $arr['wc'] = __( 'WooCommerce', 'tutor' );
347 }
348 return $arr;
349 }
350
351 /**
352 * @param $item_id
353 * @param $item
354 * @param $order_id
355 *
356 * Adding Earning Data processing WooCommerce
357 *
358 * @since v.1.1.2
359 */
360 public function add_earning_data( $item_id, $item, $order_id ) {
361
362 if ( tutor_utils()->get_option( 'monetize_by' )!='wc' ) {
363 return;
364 }
365
366 global $wpdb;
367 $item = new \WC_Order_Item_Product( $item );
368
369 $product_id = $item->get_product_id();
370 $if_has_course = tutor_utils()->product_belongs_with_course( $product_id );
371
372 if ( $if_has_course ) {
373 $course_id = $if_has_course->post_id;
374 $user_id = $wpdb->get_var( $wpdb->prepare( "SELECT post_author FROM {$wpdb->posts} WHERE ID = %d ", $course_id ) );
375 $order_status = $wpdb->get_var( $wpdb->prepare( "SELECT post_status from {$wpdb->posts} where ID = %d ", $order_id ) );
376
377 /**
378 * Return here if already added this product from this order
379 *
380 * @since v1.9.7
381 */
382 $exist_count = (int) $wpdb->get_var(
383 $wpdb->prepare(
384 "SELECT COUNT(earning_id)
385 FROM {$wpdb->prefix}tutor_earnings
386 WHERE course_id=%d
387 AND order_id=%d
388 AND user_id=%d",
389 $course_id,
390 $order_id,
391 $user_id
392 )
393 );
394
395 if ( $exist_count > 0 ) {
396 return;
397 }
398
399 $total_price = $item->get_total();
400
401 $fees_deduct_data = array();
402 $tutor_earning_fees = tutor_utils()->get_option( 'fee_amount_type' );
403 $enable_fees_deducting = tutor_utils()->get_option( 'enable_fees_deducting' );
404
405 $course_price_grand_total = $total_price;
406
407 // Deduct predefined amount (percent or fixed)
408 if ( $enable_fees_deducting ) {
409 $fees_name = tutor_utils()->get_option( 'fees_name', '' );
410 $fees_amount = (int) tutor_utils()->avalue_dot( 'fees_amount', $tutor_earning_fees );
411 $fees_type = tutor_utils()->avalue_dot( 'fees_type', $tutor_earning_fees );
412
413 if ( $fees_amount > 0 ) {
414 if ( $fees_type === 'percent' ) {
415 $fees_amount = ( $total_price * $fees_amount ) / 100;
416 }
417
418 $course_price_grand_total = $total_price - $fees_amount;
419 }
420
421 $fees_deduct_data = array(
422 'deduct_fees_amount' => $fees_amount,
423 'deduct_fees_name' => $fees_name,
424 'deduct_fees_type' => $fees_type,
425 );
426 }
427
428 // Distribute amount between admin and instructor
429 $sharing_enabled = tutor_utils()->get_option( 'enable_revenue_sharing' );
430 $instructor_rate = $sharing_enabled ? tutor_utils()->get_option( 'earning_instructor_commission' ) : 0;
431 $admin_rate = $sharing_enabled ? tutor_utils()->get_option( 'earning_admin_commission' ) : 100;
432 $commission_type = 'percent';
433 $instructor_amount = $instructor_rate > 0 ? (( $course_price_grand_total * $instructor_rate ) / 100) : 0;
434 $admin_amount = $admin_rate > 0 ? (( $course_price_grand_total * $admin_rate ) / 100) : 0;
435
436 // (Use Pro Filter - Start)
437 // The response must be same array structure.
438 // Do not change used variable names here, or change in both of here and pro plugin
439 $pro_arg = array(
440 'user_id' => $user_id,
441 'instructor_rate' => $instructor_rate,
442 'admin_rate' => $admin_rate,
443 'instructor_amount' => $instructor_amount,
444 'admin_amount' => $admin_amount,
445 'course_price_grand_total' => $course_price_grand_total,
446 'commission_type' => $commission_type,
447 );
448 $pro_calculation = apply_filters( 'tutor_pro_earning_calculator', $pro_arg );
449 extract( $pro_calculation );
450 // (Use Pro Filter - End)
451
452 // Prepare insertable earning data
453 $earning_data = array(
454 'user_id' => $user_id,
455 'course_id' => $course_id,
456 'order_id' => $order_id,
457 'order_status' => $order_status,
458 'course_price_total' => $total_price,
459 'course_price_grand_total' => $course_price_grand_total,
460
461 'instructor_amount' => $instructor_amount,
462 'instructor_rate' => $instructor_rate,
463 'admin_amount' => $admin_amount,
464 'admin_rate' => $admin_rate,
465
466 'commission_type' => $commission_type,
467 'process_by' => 'woocommerce',
468 'created_at' => date( 'Y-m-d H:i:s', tutor_time() ),
469 );
470 $earning_data = apply_filters( 'tutor_new_earning_data', array_merge( $earning_data, $fees_deduct_data ) );
471
472 $wpdb->insert( $wpdb->prefix . 'tutor_earnings', $earning_data );
473 }
474 }
475
476 /**
477 * @param $order_id
478 * @param $status_from
479 * @param $status_to
480 *
481 * Change Earning data status
482 *
483 * @since v.1.1.2
484 */
485 public function add_earning_data_status_change( $order_id, $status_from, $status_to ) {
486 if ( ! tutor_utils()->is_tutor_order( $order_id ) ) {
487 return;
488 }
489 global $wpdb;
490
491 $is_earning_data = (int) $wpdb->get_var( $wpdb->prepare(
492 "SELECT COUNT(earning_id)
493 FROM {$wpdb->prefix}tutor_earnings
494 WHERE order_id = %d ",
495 $order_id
496 ) );
497
498 if ( $is_earning_data ) {
499 $wpdb->update(
500 $wpdb->prefix . 'tutor_earnings',
501 array( 'order_status' => $status_to ),
502 array( 'order_id' => $order_id )
503 );
504 }
505 }
506
507 /**
508 * Course placing order from admin
509 *
510 * @param $order_id
511 * @since v.1.6.7
512 */
513 public function course_placing_order_from_admin( $order_id ) {
514 if ( ! is_admin() ) {
515 return;
516 }
517
518 $order = wc_get_order( $order_id );
519 foreach ( $order->get_items() as $item ) {
520 $product_id = $item->get_product_id();
521 $if_has_course = tutor_utils()->product_belongs_with_course( $product_id );
522 if ( $if_has_course ) {
523 $course_id = $if_has_course->post_id;
524 $customer_id = $order->get_customer_id();
525 tutor_utils()->do_enroll( $course_id, $order_id, $customer_id );
526 }
527 }
528 }
529
530 /**
531 * Course placing order from customer
532 *
533 * @param $order_id
534 * @since v.1.6.7
535 */
536 public function course_placing_order_from_customer( $item_id, $item, $order_id ) {
537 if ( is_admin() ) {
538 return;
539 }
540
541 $item = new \WC_Order_Item_Product( $item );
542 $product_id = $item->get_product_id();
543 $if_has_course = tutor_utils()->product_belongs_with_course( $product_id );
544
545 if ( $if_has_course ) {
546 $course_id = $if_has_course->post_id;
547 tutor_utils()->do_enroll( $course_id, $order_id );
548 }
549 }
550
551 /**
552 * Disable course monetization on woocommerce deactivation
553 *
554 * @since v.1.7.8
555 */
556 public function disable_tutor_monetization() {
557 tutor_utils()->update_option( 'monetize_by', 'free' );
558 update_option( 'tutor_show_woocommerce_notice', true );
559 }
560
561 /**
562 * Redirect student on enrolled courses after course
563 * enrolment complete if course is purchasable
564 *
565 * @param $order_id | int
566 * @since 1.9.0
567 */
568 public function redirect_to_enrolled_courses( $order_id ) {
569 if ( ! tutor_utils()->get_option( 'wc_automatic_order_complete_redirect_to_courses' ) ) {
570 // Since 1.9.1
571 return;
572 }
573
574 // get woo order details
575 $order = wc_get_order( $order_id );
576 $tutor_product = false;
577 $url = tutor_utils()->tutor_dashboard_url() . 'enrolled-courses/';
578
579 foreach ( $order->get_items() as $item ) {
580 $product_id = $item->get_product_id();
581 // check if product associated with tutor course
582 $if_has_course = tutor_utils()->product_belongs_with_course( $product_id );
583 if ( $if_has_course ) {
584 $tutor_product = true;
585 }
586 }
587
588 // if tutor product & order status completed
589 if ( $order->has_status( 'completed' ) && $tutor_product ) {
590 wp_safe_redirect( $url );
591 exit;
592 }
593 }
594
595 /**
596 * Change product url on cart page if product is tutor course
597 *
598 * @since 1.9.8
599 */
600 function tutor_update_product_url( $permalink, $cart_item ) {
601
602 $woo_product_id = $cart_item['product_id'];
603 $product_meta = get_post_meta( $woo_product_id );
604
605 if ( isset( $product_meta['_tutor_product'] ) && $product_meta['_tutor_product'][0] ) {
606
607 global $wpdb;
608 $table = $wpdb->base_prefix . 'postmeta';
609 $post_id = $wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM {$table} WHERE meta_key = '_tutor_course_product_id' AND meta_value = %d ", $woo_product_id ) );
610
611 if ( $post_id ) {
612 $data = get_post_permalink( $post_id );
613 return $data;
614 }
615 }
616 }
617
618 /**
619 * Mark woocommerce order as complete only from the
620 * client side.
621 *
622 * @since v2.0.5
623 *
624 * @param integer $order_id
625 *
626 * @return boolean
627 */
628 public static function mark_order_complete( int $order_id ): bool {
629 if ( is_admin() ) {
630 return false;
631 }
632 global $wpdb;
633 $update = $wpdb->update(
634 $wpdb->posts,
635 array( 'post_status' => 'wc-completed' ),
636 array( 'ID' => $order_id )
637 );
638 return (bool) $update;
639 }
640 }
641
642
643 add_action(
644 'admin_notices',
645 function() {
646
647 $show = get_option( 'tutor_show_woocommerce_notice' ) && tutor_utils()->get_option( 'monetize_by', 'free' ) == 'free';
648
649 if ( $show ) {
650 $message = __( 'Since WooCommerce is disabled, your monetized courses have been set to free. Please make sure to enable Tutor LMS monetization if you decide to re-enable WooCommerce.', 'tutor' );
651 echo '<div class="notice notice-error"><p>' . $message . '</p></div>';
652 }
653 }
654 );
655