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