PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 1.9.3
Tutor LMS – eLearning and online course solution v1.9.3
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 5 years ago Admin.php 5 years ago Ajax.php 5 years ago Assets.php 5 years ago Course.php 5 years ago Course_Filter.php 5 years ago Course_Settings_Tabs.php 5 years ago Course_Widget.php 5 years ago Custom_Validation.php 5 years ago Dashboard.php 5 years ago Email.php 5 years ago FormHandler.php 5 years ago Frontend.php 5 years ago Gutenberg.php 5 years ago Instructor.php 5 years ago Instructors_List.php 5 years ago Lesson.php 5 years ago Options.php 5 years ago Post_types.php 5 years ago Private_Course_Access.php 5 years ago Q_and_A.php 5 years ago Question_Answers_List.php 5 years ago Quiz.php 5 years ago Quiz_Attempts_List.php 5 years ago RestAPI.php 5 years ago Rewrite_Rules.php 5 years ago Shortcode.php 5 years ago Student.php 5 years ago Students_List.php 5 years ago Taxonomies.php 5 years ago Template.php 5 years ago Theme_Compatibility.php 5 years ago Tools.php 5 years ago Tutor.php 5 years ago TutorEDD.php 5 years ago Tutor_Base.php 5 years ago Tutor_List_Table.php 5 years ago Tutor_Setup.php 5 years ago Upgrader.php 5 years ago User.php 5 years ago Utils.php 5 years ago Video_Stream.php 5 years ago Withdraw.php 5 years ago Withdraw_Requests_List.php 5 years ago WooCommerce.php 5 years ago
WooCommerce.php
545 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 class WooCommerce extends Tutor_Base {
16
17 public function __construct() {
18 parent::__construct();
19
20 add_action('tutor_options_before_woocommerce', array($this, 'notice_before_option'));
21
22 //Add option settings
23 add_filter('tutor_monetization_options', array($this, 'tutor_monetization_options'));
24 add_filter('tutor/options/attr', array($this, 'add_options'));
25
26 $monetize_by = tutils()->get_option('monetize_by');
27 if ($monetize_by !== 'wc') {
28 return;
29 }
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 * @since v.1.3.5
68 */
69 if (tutils()->has_wc()) {
70 add_action('tutor_course/single/before/inner-wrap', 'wc_print_notices', 10);
71 add_action('tutor_course/single/enrolled/before/inner-wrap', 'wc_print_notices', 10);
72 }
73
74 /**
75 * Manage WooCommerce plugin dependency
76 * @since v.1.7.8
77 */
78 $woocommerce_path = dirname(dirname(__DIR__)) . DIRECTORY_SEPARATOR . 'woocommerce' . DIRECTORY_SEPARATOR . 'woocommerce.php';
79 register_deactivation_hook( $woocommerce_path, array($this, 'disable_tutor_monetization') );
80 /**
81 * Redirect student on enrolled courses after course
82 * enrollment complete
83 * @since 1.9.0
84 */
85 add_action( 'woocommerce_thankyou', array($this, 'redirect_to_enrolled_courses') );
86 }
87
88 public function notice_before_option() {
89 $has_wc = tutor_utils()->has_wc();
90 if ($has_wc) {
91 return;
92 }
93
94 ob_start();
95 ?>
96 <div class="tutor-notice-warning">
97 <p>
98 <?php _e(' Seems like you don’t have WooCommerce plugin installed on your site. In order to use this functionality, you need to have the
99 WooCommerce plugin installed. Get back on this page after installing the plugin and enable the following feature to start selling
100 courses with Tutor.', 'tutor'); ?>
101 </p>
102 <p><?php _e('This notice will disappear after activating <strong>WooCommerce</strong>', 'tutor'); ?></p>
103 </div>
104 <?php
105 echo ob_get_clean();
106 }
107
108 public function is_course_purchasable($bool, $course_id) {
109 if (!tutor_utils()->has_wc()) {
110 return false;
111 }
112
113 $course_id = tutor_utils()->get_post_id($course_id);
114 $has_product_id = get_post_meta($course_id, '_tutor_course_product_id', true);
115 if ($has_product_id) {
116 return true;
117 }
118 return false;
119 }
120
121 public function get_tutor_course_price($price, $course_id) {
122 $price = null;
123
124 if (tutor_utils()->is_course_purchasable($course_id)) {
125 if (tutor_utils()->has_wc()) {
126 $product_id = tutor_utils()->get_course_product_id($course_id);
127 $product = wc_get_product($product_id);
128
129 if ($product) {
130 ob_start();
131 ?>
132 <div class="price">
133 <?php echo $product->get_price_html(); ?>
134 </div>
135 <?php
136 return ob_get_clean();
137 }
138 }
139 }
140
141 return $price;
142 }
143
144 public function tutor_course_sell_by() {
145 return 'woocommerce';
146 }
147
148 public function add_tutor_type_in_wc_product($types) {
149 $types['tutor_product'] = array(
150 'id' => '_tutor_product',
151 'wrapper_class' => 'show_if_simple',
152 'label' => __('For Tutor', 'tutor'),
153 'description' => __('This checkmark ensure that you will sell a specif course via this product.', 'tutor'),
154 'default' => 'no',
155 );
156
157 return $types;
158 }
159
160 public function register_meta_box() {
161 add_meta_box('tutor-attach-product', __('Add Product', 'tutor'), array($this, 'course_add_product_metabox'), $this->course_post_type, 'advanced', 'high');
162 }
163
164 public function course_add_product_metabox() {
165 include tutor()->path . 'views/metabox/course-add-product-metabox.php';
166 }
167
168 /**
169 * @param $post_ID
170 *
171 * Save course meta for attaching product
172 */
173 public function save_course_meta($post_ID) {
174 $product_id = (int)sanitize_text_field( tutor_utils()->avalue_dot('_tutor_course_product_id', $_POST, 0) ) ;
175
176 if ($product_id === -1) {
177 delete_post_meta($post_ID, '_tutor_course_product_id');
178 } else if ($product_id) {
179 update_post_meta($post_ID, '_tutor_course_product_id', $product_id);
180 //Mark product for woocommerce
181 update_post_meta($product_id, '_virtual', 'yes');
182 update_post_meta($product_id, '_tutor_product', 'yes');
183 }
184 }
185
186 public function save_wc_product_meta($post_ID) {
187 $is_tutor_product = sanitize_text_field( tutor_utils()->avalue_dot('_tutor_product', $_POST) );
188 if ($is_tutor_product === 'on') {
189 update_post_meta($post_ID, '_tutor_product', 'yes');
190 } else {
191 delete_post_meta($post_ID, '_tutor_product');
192 }
193 }
194
195 /**
196 *
197 * Take enrolled course action based on order status change
198 */
199 public function enrolled_courses_status_change($order_id, $status_from, $status_to) {
200 if (!tutor_utils()->is_tutor_order($order_id)) {
201 return;
202 }
203 global $wpdb;
204
205 $enrolled_ids_with_course = $this->get_course_enrolled_ids_by_order_id($order_id);
206
207 if ($enrolled_ids_with_course) {
208 $enrolled_ids = wp_list_pluck($enrolled_ids_with_course, 'enrolled_id');
209
210 if (is_array($enrolled_ids) && count($enrolled_ids)) {
211 foreach ($enrolled_ids as $enrolled_id) {
212
213 tutils()->course_enrol_status_change($enrolled_id, $status_to);
214
215 // Invoke enrolled hook
216 if($status_to == 'completed'){
217 $user_id = get_post_field('post_author', $enrolled_id);
218 $course_id = get_post_field('post_parent', $enrolled_id);
219 do_action('tutor_after_enrolled', $course_id, $user_id, $enrolled_id);
220 }
221 }
222 }
223 }
224 }
225
226 /**
227 * @param $order_id
228 *
229 * @return array|bool
230 */
231 public function get_course_enrolled_ids_by_order_id($order_id) {
232 global $wpdb;
233 //Getting all of courses ids within this order
234
235 $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));
236
237 if (is_array($courses_ids) && count($courses_ids)) {
238 $course_enrolled_by_order = array();
239 foreach ($courses_ids as $courses_id) {
240 $course_id = str_replace('_tutor_order_for_course_id_', '', $courses_id->meta_key);
241 //array(order_id => array('course_id' => $course_id, 'enrolled_id' => enrolled_id, 'order_id' => $courses_id->post_id))
242 $course_enrolled_by_order[] = array('course_id' => $course_id, 'enrolled_id' => $courses_id->meta_value, 'order_id' => $courses_id->post_id);
243 }
244 return $course_enrolled_by_order;
245 }
246 return false;
247 }
248
249 /**
250 * Remove course
251 *
252 * TODO: right now it's unused
253 */
254 public function remove_active_course($order_id) {
255 global $wpdb;
256 //Getting all of courses ids within this order
257
258 $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));
259 }
260
261
262 /**
263 * @param $attr
264 *
265 * @return mixed
266 *
267 * Add option for WooCommerce settings
268 */
269 public function add_options($attr) {
270
271 $attr['woocommerce'] = array(
272 'label' => __('WooCommerce', 'tutor'),
273
274 'sections' => array(
275 'general' => array(
276 'label' => __('General', 'tutor'),
277 'desc' => __('WooCommerce Settings', 'tutor'),
278 'fields' => array(
279 /*'enable_course_sell_by_woocommerce' => array(
280 'type' => 'checkbox',
281 'label' => __('Enable / Disable', 'tutor'),
282 'label_title' => __('Enable WooComerce to sell course', 'tutor'),
283 'desc' => __('By integrating WooCommerce, you can sell your course', 'tutor'),
284 ),*/
285 'enable_guest_course_cart' => array(
286 'type' => 'checkbox',
287 'label' => __('Enable / Disable', 'tutor'),
288 'label_title' => __('Enable add to cart feature for guest users', 'tutor'),
289 'desc' => __('Enabling this will let an unregistered user purchase any course from the Course Details page. Head over to Documentation to know how to configure this setting.', 'tutor'),
290 ),
291 ),
292 ),
293 ),
294 );
295
296 return $attr;
297 }
298
299 /**
300 * @param $arr
301 *
302 * @return mixed
303 *
304 * Returning monetization options
305 *
306 * @since v.1.3.5
307 */
308 public function tutor_monetization_options($arr) {
309 $has_wc = tutils()->has_wc();
310 if ($has_wc) {
311 $arr['wc'] = __('WooCommerce', 'tutor');
312 }
313 return $arr;
314 }
315
316 /**
317 * @param $item_id
318 * @param $item
319 * @param $order_id
320 *
321 * Adding Earning Data processing WooCommerce
322 *
323 * @since v.1.1.2
324 */
325 public function add_earning_data($item_id, $item, $order_id) {
326 global $wpdb;
327 $item = new \WC_Order_Item_Product($item);
328
329 $product_id = $item->get_product_id();
330 $if_has_course = tutor_utils()->product_belongs_with_course($product_id);
331
332 if ($if_has_course) {
333
334 $enable_tutor_earning = tutor_utils()->get_option('enable_tutor_earning');
335 if (!$enable_tutor_earning) {
336 return;
337 }
338
339 $course_id = $if_has_course->post_id;
340 $user_id = $wpdb->get_var($wpdb->prepare("SELECT post_author FROM {$wpdb->posts} WHERE ID = %d ", $course_id));
341 $order_status = $wpdb->get_var($wpdb->prepare("SELECT post_status from {$wpdb->posts} where ID = %d ", $order_id));
342
343 $total_price = $item->get_total();
344
345 $fees_deduct_data = array();
346 $tutor_earning_fees = tutor_utils()->get_option('tutor_earning_fees');
347 $enable_fees_deducting = tutor_utils()->avalue_dot('enable_fees_deducting', $tutor_earning_fees);
348
349 $course_price_grand_total = $total_price;
350
351 if ($enable_fees_deducting) {
352 $fees_name = tutor_utils()->avalue_dot('fees_name', $tutor_earning_fees);
353 $fees_amount = (int) tutor_utils()->avalue_dot('fees_amount', $tutor_earning_fees);
354 $fees_type = tutor_utils()->avalue_dot('fees_type', $tutor_earning_fees);
355
356 if ($fees_amount > 0) {
357 if ($fees_type === 'percent') {
358 $fees_amount = ($total_price * $fees_amount) / 100;
359 }
360
361 /*
362 if ( $fees_type === 'fixed' ) {
363 $course_price_grand_total = $total_price - $fees_amount;
364 }*/
365
366 $course_price_grand_total = $total_price - $fees_amount;
367 }
368
369 $fees_deduct_data = array(
370 'deduct_fees_amount' => $fees_amount,
371 'deduct_fees_name' => $fees_name,
372 'deduct_fees_type' => $fees_type,
373 );
374 }
375
376 $instructor_rate = tutor_utils()->get_option('earning_instructor_commission');
377 $admin_rate = tutor_utils()->get_option('earning_admin_commission');
378
379 $instructor_amount = 0;
380 if ($instructor_rate > 0) {
381 $instructor_amount = ($course_price_grand_total * $instructor_rate) / 100;
382 }
383
384 $admin_amount = 0;
385 if ($admin_rate > 0) {
386 $admin_amount = ($course_price_grand_total * $admin_rate) / 100;
387 }
388
389 $commission_type = 'percent';
390
391 // (Use Pro Filter - Start)
392 // The response must be same array structure.
393 // Do not change used variable names here, or change in both of here and pro plugin
394 $pro_arg = [
395 'user_id' => $user_id,
396 'instructor_rate' => $instructor_rate,
397 'admin_rate' => $admin_rate,
398 'instructor_amount' => $instructor_amount,
399 'admin_amount' => $admin_amount,
400 'course_price_grand_total' => $course_price_grand_total,
401 'commission_type' => $commission_type
402 ];
403 $pro_calculation = apply_filters('tutor_pro_earning_calculator', $pro_arg);
404 extract($pro_calculation);
405 // (Use Pro Filter - End)
406
407 $earning_data = array(
408 'user_id' => $user_id,
409 'course_id' => $course_id,
410 'order_id' => $order_id,
411 'order_status' => $order_status,
412 'course_price_total' => $total_price,
413 'course_price_grand_total' => $course_price_grand_total,
414
415 'instructor_amount' => $instructor_amount,
416 'instructor_rate' => $instructor_rate,
417 'admin_amount' => $admin_amount,
418 'admin_rate' => $admin_rate,
419
420 'commission_type' => $commission_type,
421 'process_by' => 'woocommerce',
422 'created_at' => date('Y-m-d H:i:s', tutor_time()),
423 );
424 $earning_data = apply_filters('tutor_new_earning_data', array_merge($earning_data, $fees_deduct_data));
425
426 $wpdb->insert($wpdb->prefix . 'tutor_earnings', $earning_data);
427 }
428 }
429
430 /**
431 * @param $order_id
432 * @param $status_from
433 * @param $status_to
434 *
435 * Change Earning data status
436 *
437 * @since v.1.1.2
438 */
439 public function add_earning_data_status_change($order_id, $status_from, $status_to) {
440 if (!tutor_utils()->is_tutor_order($order_id)) {
441 return;
442 }
443 global $wpdb;
444
445 $is_earning_data = (int) $wpdb->get_var($wpdb->prepare("SELECT COUNT(earning_id) FROM {$wpdb->prefix}tutor_earnings WHERE order_id = %d ", $order_id));
446 if ($is_earning_data) {
447 $wpdb->update($wpdb->prefix . 'tutor_earnings', array('order_status' => $status_to), array('order_id' => $order_id));
448 }
449 }
450
451 /**
452 * Course placing order from admin
453 *
454 * @param $order_id
455 * @since v.1.6.7
456 */
457 public function course_placing_order_from_admin($order_id) {
458 if (!is_admin()) {
459 return;
460 }
461
462 $order = wc_get_order( $order_id );
463 foreach ($order->get_items() as $item) {
464 $product_id = $item->get_product_id();
465 $if_has_course = tutor_utils()->product_belongs_with_course($product_id);
466 if ($if_has_course) {
467 $course_id = $if_has_course->post_id;
468 $customer_id = $order->get_customer_id();
469 tutor_utils()->do_enroll($course_id, $order_id, $customer_id);
470 }
471 }
472 }
473
474 /**
475 * Course placing order from customer
476 *
477 * @param $order_id
478 * @since v.1.6.7
479 */
480 public function course_placing_order_from_customer($item_id, $item, $order_id) {
481 if (is_admin()) {
482 return;
483 }
484
485 $item = new \WC_Order_Item_Product($item);
486 $product_id = $item->get_product_id();
487 $if_has_course = tutor_utils()->product_belongs_with_course($product_id);
488
489 if ($if_has_course){
490 $course_id = $if_has_course->post_id;
491 tutor_utils()->do_enroll($course_id, $order_id);
492 }
493 }
494
495 /**
496 * Disable course monetization on woocommerce deactivation
497 * @since v.1.7.8
498 */
499 public function disable_tutor_monetization() {
500 tutils()->update_option('monetize_by', 'free');
501 update_option('tutor_show_woocommerce_notice', true);
502 }
503
504 /**
505 * Redirect student on enrolled courses after course
506 * enrollment complete if course is purchasable
507 * @param $order_id | int
508 * @since 1.9.0
509 */
510 public function redirect_to_enrolled_courses( $order_id ) {
511 if(!tutils()->get_option( 'wc_automatic_order_complete_redirect_to_courses' )) {
512 // Since 1.9.1
513 return;
514 }
515
516 //get woo order details
517 $order = wc_get_order( $order_id );
518 $tutor_product = false;
519 $url = tutor_utils()->tutor_dashboard_url().'enrolled-courses/';
520 foreach ($order->get_items() as $item) {
521 $product_id = $item->get_product_id();
522 //check if product associated with tutor course
523 $if_has_course = tutor_utils()->product_belongs_with_course($product_id);
524 if( $if_has_course ) {
525 $tutor_product = true;
526 }
527 }
528 //if tutor product & order status completed
529 if ( $order->has_status( 'completed' ) && $tutor_product ) {
530 wp_safe_redirect( $url );
531 exit;
532 }
533 }
534 }
535
536
537 add_action('admin_notices', function() {
538
539 $show = get_option( 'tutor_show_woocommerce_notice' ) && tutils()->get_option('monetize_by', 'free')=='free';
540
541 if($show) {
542 $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');
543 echo '<div class="notice notice-error"><p>' . $message . '</p></div>';
544 }
545 });