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