PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / trunk
Tutor LMS – eLearning and online course solution vtrunk
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 / Tutor.php
tutor / classes Last commit date
Addons.php 11 months ago Admin.php 2 months ago Ajax.php 9 months ago Announcements.php 1 year ago Assets.php 2 months ago Backend_Page_Trait.php 1 year ago BaseController.php 1 year ago Config.php 11 months ago Container.php 11 months ago Course.php 2 months ago Course_Embed.php 3 years ago Course_Filter.php 1 year ago Course_List.php 5 months ago Course_Settings_Tabs.php 1 year ago Course_Widget.php 1 year ago Custom_Validation.php 3 years ago Dashboard.php 1 year ago Earnings.php 9 months ago FormHandler.php 2 years ago Frontend.php 1 year ago Gutenberg.php 1 year ago Icon.php 8 months ago Input.php 1 year ago Instructor.php 2 months ago Instructors_List.php 2 months ago Lesson.php 2 weeks ago Options_V2.php 7 months ago Permalink.php 2 years ago Post_types.php 1 year ago Private_Course_Access.php 1 year ago Q_And_A.php 10 months ago Question_Answers_List.php 11 months ago Quiz.php 2 weeks ago QuizBuilder.php 2 days ago Quiz_Attempts_List.php 9 months ago RestAPI.php 2 years ago Reviews.php 9 months ago Rewrite_Rules.php 2 years ago Shortcode.php 9 months ago Singleton.php 1 year ago Student.php 2 months ago Students_List.php 1 year ago Taxonomies.php 1 year ago Template.php 9 months ago Theme_Compatibility.php 3 years ago Tools.php 1 year ago Tools_V2.php 3 weeks ago Tutor.php 2 months ago TutorEDD.php 1 year ago Tutor_Base.php 2 years ago Tutor_Setup.php 8 months ago Upgrader.php 9 months ago User.php 4 months ago Utils.php 2 days ago Video_Stream.php 3 years ago WhatsNew.php 9 months ago Withdraw.php 2 days ago Withdraw_Requests_List.php 11 months ago WooCommerce.php 2 days ago
Tutor.php
1422 lines
1 <?php
2 /**
3 * Initialize all the dependency classes
4 *
5 * @package Tutor
6 * @author Themeum <support@themeum.com>
7 * @link https://themeum.com
8 * @since 1.0.0
9 */
10
11 namespace TUTOR;
12
13 use Tutor\Models\CourseModel;
14 use Tutor\Ecommerce\Ecommerce;
15 use Tutor\Helpers\QueryHelper;
16 use Tutor\Migrations\Migration;
17
18 if ( ! defined( 'ABSPATH' ) ) {
19 exit;
20 }
21
22 /**
23 * Tutor final class
24 *
25 * @since 1.0.0
26 */
27 final class Tutor extends Singleton {
28 /**
29 * Tutor version
30 *
31 * @since 1.0.0
32 *
33 * @var string
34 */
35 public $version = TUTOR_VERSION;
36
37 /**
38 * Plugin dir path
39 *
40 * @since 1.0.0
41 *
42 * @var string
43 */
44 public $path;
45
46 /**
47 * Plugin dir path
48 *
49 * @since 1.0.0
50 *
51 * @var string
52 */
53 public $url;
54
55 /**
56 * Plugin dir name
57 *
58 * @since 1.0.0
59 *
60 * @var string
61 */
62 public $basename;
63
64 /**
65 * Utils class object
66 *
67 * @since 1.1.0
68 *
69 * @var object
70 */
71 public $utils;
72
73 /**
74 * Admin class object
75 *
76 * @since 1.1.0
77 *
78 * @var object
79 */
80 public $admin;
81
82 /**
83 * Ajax class object
84 *
85 * @since 1.1.0
86 *
87 * @var object
88 */
89 public $ajax;
90
91 /**
92 * Options class object
93 *
94 * @since 1.1.0
95 *
96 * @var object
97 */
98 public $options;
99
100 /**
101 * Short code class object
102 *
103 * @since 1.1.0
104 *
105 * @var object
106 */
107 public $shortcode;
108
109 /**
110 * Addons class object
111 *
112 * @since 1.1.0
113 *
114 * @var object
115 */
116 private $addons;
117
118 /**
119 * PostType class object
120 *
121 * @since 1.1.0
122 *
123 * @var object
124 */
125 private $post_types;
126
127 /**
128 * Taxonomies class object
129 *
130 * @since 1.1.0
131 *
132 * @var object
133 */
134 private $taxonomies;
135
136 /**
137 * Assets class object
138 *
139 * @since 1.1.0
140 *
141 * @var object
142 */
143 private $assets;
144
145 /**
146 * Course class object
147 *
148 * @since 1.1.0
149 *
150 * @var object
151 */
152 private $course;
153
154 /**
155 * Lesson class object
156 *
157 * @since 1.1.0
158 *
159 * @var object
160 */
161 public $lesson;
162
163 /**
164 * Rewrite_Rules class object
165 *
166 * @since 1.1.0
167 *
168 * @var object
169 */
170 private $rewrite_rules;
171
172 /**
173 * Template class object
174 *
175 * @since 1.1.0
176 *
177 * @var object
178 */
179 private $template;
180
181 /**
182 * Instructor class object
183 *
184 * @since 1.1.0
185 *
186 * @var object
187 */
188 private $instructor;
189
190 /**
191 * Student class object
192 *
193 * @since 1.1.0
194 *
195 * @var object
196 */
197 private $student;
198
199 /**
200 * Q_And_A class object
201 *
202 * @since 1.1.0
203 *
204 * @var object
205 */
206 private $q_and_a;
207
208 /**
209 * Quiz class object
210 *
211 * @since 1.1.0
212 *
213 * @var object
214 */
215 private $quiz;
216
217 /**
218 * Tools class object
219 *
220 * @since 1.1.0
221 *
222 * @var object
223 */
224 private $tools;
225
226 /**
227 * User class object
228 *
229 * @since 1.1.0
230 *
231 * @var object
232 */
233 private $user;
234
235 /**
236 * Theme_Compatibility class object
237 *
238 * @since 1.1.0
239 *
240 * @var object
241 */
242 private $theme_compatibility;
243
244 /**
245 * Gutenberg class object
246 *
247 * @since 1.1.0
248 *
249 * @var object
250 */
251 private $gutenberg;
252
253 /**
254 * Course_Settings_Tabs class object
255 *
256 * @since 1.1.0
257 *
258 * @var object
259 */
260 private $course_settings_tabs;
261
262 /**
263 * Withdraw class object
264 *
265 * @since 1.1.0
266 *
267 * @var object
268 */
269 private $withdraw;
270
271 /**
272 * Course_Widget class object
273 *
274 * @since 1.1.0
275 *
276 * @var object
277 */
278 private $course_widget;
279
280 /**
281 * Upgrader class object
282 *
283 * @since 1.1.0
284 *
285 * @var object
286 */
287 private $upgrader;
288
289 /**
290 * Dashboard class object
291 *
292 * @since 1.1.0
293 *
294 * @var object
295 */
296 private $dashboard;
297
298 /**
299 * FormHandler class object
300 *
301 * @since 1.1.0
302 *
303 * @var object
304 */
305 private $form_handler;
306
307 /**
308 * Frontend class object
309 *
310 * @since 1.1.0
311 *
312 * @var object
313 */
314 private $frontend;
315
316 /**
317 * Email property
318 *
319 * @since 1.1.0
320 *
321 * @var object
322 */
323 private $email;
324
325 /**
326 * WooCommerce integration class object
327 *
328 * @since 1.1.0
329 *
330 * @var object
331 */
332 private $woocommerce;
333
334 /**
335 * Tutor_EDD class object
336 *
337 * @since 1.1.0
338 *
339 * @var object
340 */
341 private $edd;
342
343 /**
344 * Announcement
345 *
346 * @since 2.0.0
347 *
348 * @var object
349 */
350 public $announcements;
351
352 /**
353 * Reviews class object
354 *
355 * @since 1.1.0
356 *
357 * @var object
358 */
359 private $reviews;
360
361 /**
362 * Withdraw_List class object
363 *
364 * @since 1.1.0
365 *
366 * @var object
367 */
368 public $withdraw_list;
369
370 /**
371 * Student_List class object
372 *
373 * @since 1.1.0
374 *
375 * @var object
376 */
377 public $student_list;
378
379 /**
380 * Instructor_List class object
381 *
382 * @since 1.1.0
383 *
384 * @var object
385 */
386 public $instructor_list;
387
388 /**
389 * Course List
390 *
391 * @var Course_List
392 *
393 * @since 2.0.0
394 */
395 public $course_list;
396
397 //phpcs:disable
398 public $q_and_a_list;
399 public $q_attempt;
400 public $rest_api;
401 public $setup;
402 public $private_course_access;
403 public $course_filter;
404 //phpcs:enable
405
406 /**
407 * Course Embed
408 *
409 * @var $course_embed
410 *
411 * @since 2.1.0
412 */
413 private $course_embed;
414
415 /**
416 * Rest Authentication
417 *
418 * @var $rest_auth
419 *
420 * @since 2.1.0
421 */
422 private $rest_auth;
423
424 /**
425 * Permalink
426 *
427 * @var Permalink
428 */
429 private $permalink;
430
431 /**
432 * Initialize props & other dependencies
433 *
434 * @since 1.0.0
435 */
436 public function __construct() {
437
438 $this->path = plugin_dir_path( TUTOR_FILE );
439 $this->url = plugin_dir_url( TUTOR_FILE );
440 $this->basename = plugin_basename( TUTOR_FILE );
441
442 /**
443 * Adding Tutor Database table to $wpdb;
444 *
445 * @since 1.4.2
446 */
447 global $wpdb;
448 $wpdb->tutor_earnings = $wpdb->prefix . 'tutor_earnings';
449 $wpdb->tutor_gradebooks = $wpdb->prefix . 'tutor_gradebooks';
450 $wpdb->tutor_gradebooks_results = $wpdb->prefix . 'tutor_gradebooks_results';
451 $wpdb->tutor_quiz_attempts = $wpdb->prefix . 'tutor_quiz_attempts';
452 $wpdb->tutor_quiz_attempt_answers = $wpdb->prefix . 'tutor_quiz_attempt_answers';
453 $wpdb->tutor_quiz_questions = $wpdb->prefix . 'tutor_quiz_questions';
454 $wpdb->tutor_quiz_question_answers = $wpdb->prefix . 'tutor_quiz_question_answers';
455 $wpdb->tutor_withdraws = $wpdb->prefix . 'tutor_withdraws';
456 $wpdb->tutor_email_queue = $wpdb->prefix . 'tutor_email_queue';
457 $wpdb->tutor_order_items = $wpdb->prefix . 'tutor_order_items';
458 $wpdb->tutor_orders = $wpdb->prefix . 'tutor_orders';
459 $wpdb->tutor_ordermeta = $wpdb->prefix . 'tutor_ordermeta';
460 $wpdb->tutor_subscription_plan_items = $wpdb->prefix . 'tutor_subscription_plan_items';
461 $wpdb->tutor_subscription_plans = $wpdb->prefix . 'tutor_subscription_plans';
462 $wpdb->tutor_subscriptions = $wpdb->prefix . 'tutor_subscriptions';
463 $wpdb->tutor_subscriptionmeta = $wpdb->prefix . 'tutor_subscriptionmeta';
464 $wpdb->tutor_order_itemmeta = $wpdb->prefix . 'tutor_order_itemmeta';
465
466 /**
467 * Changing default wp doing ajax return based on tutor ajax action
468 */
469 add_filter( 'wp_doing_ajax', array( $this, 'wp_doing_ajax' ) );
470
471 /**
472 * Include Files
473 */
474 $this->includes();
475
476 do_action( 'tutor_before_load' );
477
478 $this->addons = new Addons();
479 $this->post_types = new Post_types();
480 $this->taxonomies = new Taxonomies();
481 $this->assets = new Assets();
482 $this->admin = new Admin();
483 $this->ajax = new Ajax();
484 $this->options = new Options_V2();
485 $this->shortcode = new Shortcode();
486 $this->course = new Course();
487 $this->lesson = new Lesson();
488 $this->rewrite_rules = new Rewrite_Rules();
489 $this->template = new Template();
490 $this->instructor = new Instructor();
491 $this->student = new Student();
492 $this->q_and_a = new Q_And_A();
493 $this->q_and_a_list = new Question_Answers_List();
494 $this->q_attempt = new Quiz_Attempts_List();
495 $this->quiz = new Quiz();
496 $this->tools = new Tools();
497 $this->user = new User();
498 $this->theme_compatibility = new Theme_Compatibility();
499 $this->gutenberg = new Gutenberg();
500 $this->course_settings_tabs = new Course_Settings_Tabs();
501 $this->withdraw = new Withdraw();
502 $this->upgrader = new Upgrader();
503 $this->dashboard = new Dashboard();
504 $this->form_handler = new FormHandler();
505 $this->frontend = new Frontend();
506 $this->rest_api = new RestAPI();
507 $this->setup = new Tutor_Setup();
508 $this->private_course_access = new Private_Course_Access();
509 $this->course_filter = new Course_Filter();
510 $this->permalink = new Permalink();
511
512 // Integrations.
513 $this->woocommerce = new WooCommerce();
514 $this->edd = new TutorEDD();
515
516 /**
517 * Init obj
518 *
519 * @since 2.0.0
520 */
521 $this->announcements = new Announcements();
522 $this->course_list = new Course_List();
523 $this->reviews = new Reviews();
524 $this->withdraw_list = new Withdraw_Requests_List();
525 $this->student_list = new Students_List();
526 $this->instructor_list = new Instructors_List();
527 $this->course_embed = new Course_Embed();
528 $this->rest_auth = new RestAuth();
529
530 /**
531 * New Course Builder.
532 *
533 * @since 3.0.0
534 */
535 new QuizBuilder();
536
537 /**
538 * Tutor native e-commerce
539 *
540 * @since 3.0.0
541 */
542 new Ecommerce();
543
544 /**
545 * Data migrations
546 *
547 * @since 3.8.0
548 */
549 new Migration();
550
551 /**
552 * Run Method
553 *
554 * @since 1.2.0
555 */
556 $this->run();
557
558 do_action( 'tutor_loaded' );
559
560 add_action( 'init', array( $this, 'init_action' ) );
561
562 /**
563 * Check activated plugin
564 *
565 * @since 1.5.7
566 */
567
568 add_action( 'activated_plugin', array( $this, 'activated_tutor' ), 10, 2 );
569
570 /**
571 * Redirect to setup page
572 *
573 * @since 2.8.0
574 */
575 add_action( 'admin_init', array( $this, 'redirect_to_setup_page' ) );
576 }
577
578 /**
579 * Check activated plugin
580 *
581 * @since 1.5.7
582 *
583 * @param mixed $plugin plugin.
584 * @param mixed $network_wide network wide.
585 *
586 * @return void
587 */
588 public function activated_tutor( $plugin, $network_wide = null ) {
589 if ( tutor()->basename === $plugin ) {
590 $this->redirect_to_setup_page();
591 }
592 }
593
594 /**
595 * Redirect to setup page
596 *
597 * @since 2.8.0
598 *
599 * @return void
600 */
601 public function redirect_to_setup_page() {
602 if ( ( ! get_option( 'tutor_wizard' ) ) && version_compare( TUTOR_VERSION, '1.5.6', '>' ) ) {
603 if ( ! wp_doing_ajax() ) {
604 update_option( 'tutor_wizard', 'active' );
605 $is_wp_cli = defined( 'WP_CLI' ) && WP_CLI;
606 if ( ! $is_wp_cli ) {
607 wp_safe_redirect( admin_url( 'admin.php?page=tutor-setup' ) );
608 }
609 exit;
610 }
611 }
612 }
613
614 /**
615 * Include utility functions
616 *
617 * @return void
618 */
619 public function includes() {
620 $tutor_path = plugin_dir_path( TUTOR_FILE );
621
622 include $tutor_path . 'includes/tutor-general-functions.php';
623 include $tutor_path . 'includes/tutor-template-functions.php';
624 include $tutor_path . 'includes/tutor-template-hook.php';
625 include $tutor_path . 'includes/translate-text.php';
626 include $tutor_path . 'includes/country.php';
627 include $tutor_path . 'includes/ecommerce-functions.php';
628
629 if ( ! function_exists( 'is_plugin_active' ) ) {
630 require_once ABSPATH . 'wp-admin/includes/plugin.php';
631 }
632
633 // Only kirki latest has class KirkiMain.
634 $is_kirki_active = \is_plugin_active( 'kirki-pro/kirki-pro.php' ) && class_exists( 'KirkiProMain' );
635
636 if ( $is_kirki_active ) {
637 $tutor_kirki_path = $tutor_path . 'includes/kirki/kirki.php';
638 if ( file_exists( $tutor_kirki_path ) ) {
639 include $tutor_kirki_path;
640 }
641 } else {
642 $is_droip_active = \is_plugin_active( 'droip/droip.php' );
643 $tutor_droip_path = $tutor_path . 'includes/droip/droip.php';
644 if ( $is_droip_active && file_exists( $tutor_droip_path ) ) {
645 include $tutor_droip_path;
646 }
647 }
648
649 }
650
651 /**
652 * Providing hooks
653 *
654 * @return void
655 */
656 public function run() {
657 do_action( 'tutor_before_run' );
658 do_action( 'tutor_after_run' );
659 }
660
661 /**
662 * Tutor Action Via do_action
663 *
664 * @since 1.2.14
665 */
666 public function init_action() {
667 $tutor_action = Input::sanitize_request_data( 'tutor_action' );
668 if ( '' !== $tutor_action ) {
669 do_action( 'tutor_action_' . $tutor_action );
670 }
671 }
672
673 /**
674 * Do some task during plugin activation
675 */
676 public static function tutor_activate() {
677 $version = get_option( 'tutor_version' );
678 if ( ! function_exists( 'tutor_time' ) ) {
679 include tutor()->path . 'includes/tutor-general-functions.php';
680 }
681
682 // Create Database.
683 self::create_database();
684
685 // Save Option.
686 if ( ! $version ) {
687
688 $options = self::default_options();
689 update_option( 'tutor_option', $options );
690
691 // Rewrite Flush.
692 Permalink::set_permalink_flag();
693 self::manage_tutor_roles_and_permissions();
694
695 // Save initial Page.
696 self::save_data();
697 update_option( 'tutor_version', TUTOR_VERSION );
698 }
699
700 // Set Schedule.
701 if ( ! wp_next_scheduled( 'tutor_once_in_day_run_schedule' ) ) {
702 wp_schedule_event( tutor_time(), 'twicedaily', 'tutor_once_in_day_run_schedule' );
703 }
704
705 /**
706 * Backward Compatibility for version < 1.2.0
707 */
708 if ( version_compare( get_option( 'tutor_version' ), '1.2.0', '<' ) ) {
709 /**
710 * Creating New Database
711 */
712 self::create_withdraw_database();
713 // Update the tutor version.
714 update_option( 'tutor_version', '1.2.0' );
715 // Rewrite Flush.
716 Permalink::set_permalink_flag();
717 }
718
719 /**
720 * Backward Compatibility to < 1.3.1 for make course plural
721 */
722 if ( version_compare( get_option( 'tutor_version' ), '1.3.1', '<' ) ) {
723 global $wpdb;
724
725 if ( ! get_option( 'is_course_post_type_updated' ) ) {
726 $wpdb->update( $wpdb->posts, array( 'post_type' => tutor()->course_post_type ), array( 'post_type' => 'course' ) );
727 update_option( 'is_course_post_type_updated', true );
728 update_option( 'tutor_version', '1.3.1' );
729 Permalink::set_permalink_flag();
730 }
731 }
732
733 /**
734 * Save First activation Time
735 */
736 $first_activation_date = get_option( 'tutor_first_activation_time' );
737 if ( ! $first_activation_date ) {
738 update_option( 'tutor_first_activation_time', tutor_time() );
739 }
740 }
741
742 /**
743 * Run task on deactivation
744 *
745 * @since 1.0.0
746 *
747 * @return void
748 */
749 public static function tutor_deactivation() {
750 wp_clear_scheduled_hook( 'tutor_once_in_day_run_schedule' );
751 }
752
753 /**
754 * Create database
755 *
756 * @return void
757 */
758 public static function create_database() {
759 global $wpdb;
760
761 $charset_collate = $wpdb->get_charset_collate();
762
763 /**
764 * Table SQL
765 *
766 * {$wpdb->prefix}tutor_quiz_attempts
767 * {$wpdb->prefix}tutor_quiz_attempt_answers
768 * {$wpdb->prefix}tutor_quiz_questions
769 * {$wpdb->prefix}tutor_quiz_question_answers
770 * {$wpdb->prefix}tutor_earnings
771 * {$wpdb->prefix}tutor_withdraws
772 *
773 * @since 1.0.0
774 */
775 $quiz_attempts_sql = "CREATE TABLE {$wpdb->prefix}tutor_quiz_attempts (
776 attempt_id bigint(20) NOT NULL AUTO_INCREMENT,
777 course_id bigint(20) DEFAULT NULL,
778 quiz_id bigint(20) DEFAULT NULL,
779 user_id bigint(20) DEFAULT NULL,
780 total_questions int(11) DEFAULT NULL,
781 total_answered_questions int(11) DEFAULT NULL,
782 total_marks decimal(9,2) DEFAULT NULL,
783 earned_marks decimal(9,2) DEFAULT NULL,
784 attempt_info text,
785 attempt_status varchar(50) DEFAULT NULL,
786 attempt_ip varchar(250) DEFAULT NULL,
787 attempt_started_at datetime DEFAULT NULL,
788 attempt_ended_at datetime DEFAULT NULL,
789 is_manually_reviewed int(1) DEFAULT NULL,
790 manually_reviewed_at datetime DEFAULT NULL,
791 result varchar(10) DEFAULT NULL,
792 PRIMARY KEY (attempt_id),
793 INDEX (course_id),
794 INDEX (quiz_id),
795 INDEX (user_id),
796 INDEX (result)
797 ) $charset_collate;";
798
799 $quiz_attempt_answers = "CREATE TABLE {$wpdb->prefix}tutor_quiz_attempt_answers (
800 attempt_answer_id bigint(20) NOT NULL AUTO_INCREMENT,
801 user_id bigint(20) DEFAULT NULL,
802 quiz_id bigint(20) DEFAULT NULL,
803 question_id bigint(20) DEFAULT NULL,
804 quiz_attempt_id bigint(20) DEFAULT NULL,
805 given_answer longtext,
806 question_mark decimal(8,2) DEFAULT NULL,
807 achieved_mark decimal(8,2) DEFAULT NULL,
808 minus_mark decimal(8,2) DEFAULT NULL,
809 is_correct tinyint(4) DEFAULT NULL,
810 PRIMARY KEY (attempt_answer_id)
811 ) $charset_collate;";
812
813 $tutor_quiz_questions = "CREATE TABLE {$wpdb->prefix}tutor_quiz_questions (
814 question_id bigint(20) NOT NULL AUTO_INCREMENT,
815 quiz_id bigint(20) DEFAULT NULL,
816 question_title text,
817 question_description longtext,
818 answer_explanation longtext DEFAULT '',
819 question_type varchar(50) DEFAULT NULL,
820 question_mark decimal(9,2) DEFAULT NULL,
821 question_settings longtext,
822 question_order int(11) DEFAULT NULL,
823 PRIMARY KEY (question_id)
824 ) $charset_collate;";
825
826 $tutor_quiz_question_answers = "CREATE TABLE {$wpdb->prefix}tutor_quiz_question_answers (
827 answer_id bigint(20) NOT NULL AUTO_INCREMENT,
828 belongs_question_id bigint(20) DEFAULT NULL,
829 belongs_question_type varchar(250) DEFAULT NULL,
830 answer_title text,
831 is_correct tinyint(4) DEFAULT NULL,
832 image_id bigint(20) DEFAULT NULL,
833 answer_two_gap_match text,
834 answer_view_format varchar(250) DEFAULT NULL,
835 answer_settings text,
836 answer_order int(11) DEFAULT '0',
837 PRIMARY KEY (answer_id)
838 ) $charset_collate;";
839
840 $earning_table = "CREATE TABLE IF NOT EXISTS {$wpdb->prefix}tutor_earnings (
841 earning_id bigint(20) NOT NULL AUTO_INCREMENT,
842 user_id bigint(20) DEFAULT NULL,
843 course_id bigint(20) DEFAULT NULL,
844 order_id bigint(20) DEFAULT NULL,
845 order_status varchar(50) DEFAULT NULL,
846 course_price_total decimal(16,2) DEFAULT NULL,
847 course_price_grand_total decimal(16,2) DEFAULT NULL,
848 instructor_amount decimal(16,2) DEFAULT NULL,
849 instructor_rate decimal(16,2) DEFAULT NULL,
850 admin_amount decimal(16,2) DEFAULT NULL,
851 admin_rate decimal(16,2) DEFAULT NULL,
852 commission_type varchar(20) DEFAULT NULL,
853 deduct_fees_amount decimal(16,2) DEFAULT NULL,
854 deduct_fees_name varchar(250) DEFAULT NULL,
855 deduct_fees_type varchar(20) DEFAULT NULL,
856 process_by varchar(20) DEFAULT NULL,
857 created_at datetime DEFAULT NULL,
858 PRIMARY KEY (earning_id),
859 INDEX (user_id),
860 INDEX (course_id),
861 INDEX (order_id),
862 INDEX (process_by)
863 ) $charset_collate;";
864
865 $withdraw_table = "CREATE TABLE IF NOT EXISTS {$wpdb->prefix}tutor_withdraws (
866 withdraw_id bigint(20) NOT NULL AUTO_INCREMENT,
867 user_id bigint(20) DEFAULT NULL,
868 amount decimal(16,2) DEFAULT NULL,
869 method_data text DEFAULT NULL,
870 status varchar(50) DEFAULT NULL,
871 updated_at datetime DEFAULT NULL,
872 created_at datetime DEFAULT NULL,
873 PRIMARY KEY (withdraw_id)
874 ) $charset_collate;";
875
876 $orders_table = "CREATE TABLE {$wpdb->prefix}tutor_orders (
877 id BIGINT(20) UNSIGNED AUTO_INCREMENT,
878 parent_id BIGINT(20) UNSIGNED DEFAULT 0, -- for subscription order, store subscription record id
879 transaction_id VARCHAR(255) COMMENT 'Transaction id from payment gateway',
880 user_id BIGINT(20) UNSIGNED NOT NULL,
881 order_type VARCHAR(50) NOT NULL, -- single_order, subscription
882 order_status VARCHAR(50) NOT NULL,
883 payment_status VARCHAR(50) NOT NULL,
884 subtotal_price DECIMAL(13, 2) NOT NULL, -- price calculation based on course sale price
885 pre_tax_price DECIMAL(13, 2) NOT NULL, -- total price before adding tax
886 tax_type VARCHAR(50),
887 tax_rate DECIMAL(13, 2) COMMENT 'Tax percentage',
888 tax_amount DECIMAL(13, 2),
889 total_price DECIMAL(13, 2) NOT NULL, -- final price
890 net_payment DECIMAL(13, 2) NOT NULL, -- calculated price if any refund is done else same as total_price
891 coupon_code VARCHAR(255),
892 coupon_amount DECIMAL(13, 2),
893 discount_type ENUM('percentage', 'flat') DEFAULT NULL,
894 discount_amount DECIMAL(13, 2),
895 discount_reason TEXT,
896 fees DECIMAL(13, 2), -- payment gateway fees
897 earnings DECIMAL(13, 2), -- net earning
898 refund_amount DECIMAL(13, 2), -- Refund amount
899 payment_method VARCHAR(255),
900 payment_payloads LONGTEXT,
901 note TEXT,
902 created_at_gmt DATETIME NOT NULL,
903 created_by BIGINT(20) UNSIGNED NOT NULL,
904 updated_at_gmt DATETIME,
905 updated_by BIGINT(20) UNSIGNED NOT NULL,
906 PRIMARY KEY (id),
907 KEY user_id (user_id),
908 KEY order_type (order_type),
909 KEY payment_status (payment_status),
910 KEY order_status (order_status),
911 KEY transaction_id (transaction_id)
912 ) $charset_collate;";
913
914 $order_meta_table = "CREATE TABLE {$wpdb->prefix}tutor_ordermeta (
915 id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
916 order_id BIGINT(20) UNSIGNED NOT NULL,
917 meta_key VARCHAR(255) NOT NULL,
918 meta_value LONGTEXT NOT NULL,
919 created_at_gmt DATETIME NOT NULL,
920 created_by BIGINT(20) UNSIGNED NOT NULL,
921 updated_at_gmt DATETIME,
922 updated_by BIGINT(20) UNSIGNED NOT NULL,
923 PRIMARY KEY (id),
924 KEY order_id (order_id),
925 KEY meta_key (meta_key),
926 CONSTRAINT fk_tutor_ordermeta_order_id FOREIGN KEY (order_id) REFERENCES {$wpdb->prefix}tutor_orders(id) ON DELETE CASCADE
927 ) $charset_collate;";
928
929 $order_items_table = "CREATE TABLE {$wpdb->prefix}tutor_order_items (
930 id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
931 order_id BIGINT(20) UNSIGNED NOT NULL,
932 item_id BIGINT(20) UNSIGNED NOT NULL, -- course id/plan id
933 regular_price DECIMAL(13, 2) NOT NULL, -- course regular price
934 sale_price VARCHAR(13) DEFAULT NULL, -- course sale price
935 discount_price VARCHAR(13) DEFAULT NULL, -- course discount price
936 coupon_code VARCHAR(255) DEFAULT NULL, -- coupon code
937 PRIMARY KEY (id),
938 KEY order_id (order_id),
939 KEY item_id (item_id),
940 CONSTRAINT fk_tutor_order_item_order_id FOREIGN KEY (order_id) REFERENCES {$wpdb->prefix}tutor_orders(id) ON DELETE CASCADE
941 ) $charset_collate;";
942
943 $coupons_table = "CREATE TABLE {$wpdb->prefix}tutor_coupons (
944 id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
945 coupon_status VARCHAR(50),
946 coupon_type VARCHAR(100) DEFAULT 'code', -- coupon type 'code' or 'automatic'
947 coupon_code VARCHAR(50) NOT NULL,
948 coupon_title VARCHAR(255) NOT NULL,
949 coupon_description TEXT,
950 discount_type ENUM('percentage', 'flat') NOT NULL,
951 discount_amount DECIMAL(13, 2) NOT NULL,
952 applies_to VARCHAR(100) DEFAULT 'all_courses_and_bundles', -- possible values 'all_courses_and_bundles', 'all_courses', 'all_bundles', 'specific_courses', 'specific_bundles', 'specific_category'
953 total_usage_limit INT(10) UNSIGNED DEFAULT NULL, -- null for unlimited usage
954 per_user_usage_limit TINYINT(4) UNSIGNED DEFAULT NULL, -- null for unlimited usage
955 purchase_requirement VARCHAR(50) DEFAULT 'no_minimum', -- possible values 'no_minimum', 'minimum_purchase', 'minimum_quantity'
956 purchase_requirement_value DECIMAL(13, 2),
957 start_date_gmt DATETIME NOT NULL,
958 expire_date_gmt DATETIME DEFAULT NULL,
959 created_at_gmt DATETIME NOT NULL,
960 created_by BIGINT(20) UNSIGNED NOT NULL,
961 updated_at_gmt DATETIME,
962 updated_by BIGINT(20) UNSIGNED NOT NULL,
963 PRIMARY KEY (id),
964 UNIQUE KEY coupon_code (coupon_code),
965 KEY start_date_gmt (start_date_gmt),
966 KEY expire_date_gmt (expire_date_gmt)
967 ) $charset_collate;";
968
969 $coupon_applications_table = "CREATE TABLE {$wpdb->prefix}tutor_coupon_applications (
970 coupon_code VARCHAR(50) NOT NULL,
971 reference_id BIGINT(20) UNSIGNED NOT NULL,
972 KEY coupon_code (coupon_code),
973 KEY reference_id (reference_id),
974 CONSTRAINT fk_tutor_coupon_application_coupon_code FOREIGN KEY (coupon_code) REFERENCES {$wpdb->prefix}tutor_coupons(coupon_code) ON DELETE CASCADE
975 ) $charset_collate;";
976
977 $coupon_usage_table = "CREATE TABLE {$wpdb->prefix}tutor_coupon_usages (
978 id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
979 coupon_code VARCHAR(50) NOT NULL,
980 user_id BIGINT(20) UNSIGNED NOT NULL,
981 PRIMARY KEY (id),
982 KEY coupon_code (coupon_code),
983 KEY user_id (user_id),
984 CONSTRAINT fk_tutor_coupon_usage_coupon_code FOREIGN KEY (coupon_code) REFERENCES {$wpdb->prefix}tutor_coupons(coupon_code) ON DELETE CASCADE,
985 CONSTRAINT fk_tutor_coupon_usage_user_id FOREIGN KEY (user_id) REFERENCES {$wpdb->prefix}users(ID) ON DELETE CASCADE
986 ) $charset_collate;";
987
988 $cart_table = "CREATE TABLE {$wpdb->prefix}tutor_carts (
989 id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
990 user_id BIGINT(20) UNSIGNED DEFAULT NULL,
991 coupon_code VARCHAR(50) DEFAULT NULL,
992 created_at_gmt DATETIME NOT NULL,
993 updated_at_gmt DATETIME,
994 PRIMARY KEY (id),
995 KEY user_id (user_id),
996 KEY coupon_code (coupon_code),
997 CONSTRAINT fk_tutor_cart_user_id FOREIGN KEY (user_id) REFERENCES {$wpdb->prefix}users(ID) ON DELETE CASCADE
998 ) $charset_collate;";
999
1000 $cart_items_table = "CREATE TABLE {$wpdb->prefix}tutor_cart_items (
1001 id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
1002 cart_id BIGINT(20) UNSIGNED NOT NULL,
1003 course_id BIGINT(20) UNSIGNED NOT NULL,
1004 PRIMARY KEY (id),
1005 KEY cart_id (cart_id),
1006 KEY course_id (course_id),
1007 CONSTRAINT fk_tutor_cart_item_cart_id FOREIGN KEY (cart_id) REFERENCES {$wpdb->prefix}tutor_carts(id) ON DELETE CASCADE,
1008 CONSTRAINT fk_tutor_cart_item_course_id FOREIGN KEY (course_id) REFERENCES {$wpdb->prefix}posts(ID) ON DELETE CASCADE
1009 ) $charset_collate;";
1010
1011 $customer_table = "CREATE TABLE {$wpdb->prefix}tutor_customers (
1012 id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
1013 user_id BIGINT(20) UNSIGNED DEFAULT NULL,
1014 billing_first_name VARCHAR(255) NOT NULL,
1015 billing_last_name VARCHAR(255) NOT NULL,
1016 billing_email VARCHAR(255) NOT NULL,
1017 billing_phone VARCHAR(20) NOT NULL,
1018 billing_zip_code VARCHAR(20) NOT NULL,
1019 billing_address TEXT NOT NULL,
1020 billing_country VARCHAR(100) NOT NULL,
1021 billing_state VARCHAR(100) NOT NULL,
1022 billing_city VARCHAR(100) NOT NULL,
1023 PRIMARY KEY (id),
1024 KEY user_id (user_id),
1025 KEY billing_email (billing_email)
1026 ) $charset_collate;";
1027
1028 require_once ABSPATH . 'wp-admin/includes/upgrade.php';
1029 dbDelta( $quiz_attempts_sql );
1030 dbDelta( $quiz_attempt_answers );
1031 dbDelta( $tutor_quiz_questions );
1032 dbDelta( $tutor_quiz_question_answers );
1033 dbDelta( $earning_table );
1034 dbDelta( $withdraw_table );
1035 dbDelta( $orders_table );
1036 dbDelta( $order_meta_table );
1037 dbDelta( $order_items_table );
1038 dbDelta( $coupons_table );
1039 dbDelta( $coupon_applications_table );
1040 dbDelta( $coupon_usage_table );
1041 dbDelta( $cart_table );
1042 dbDelta( $cart_items_table );
1043 dbDelta( $customer_table );
1044 }
1045
1046 /**
1047 * Manage tutor roles & permission
1048 *
1049 * @return void
1050 */
1051 public static function manage_tutor_roles_and_permissions() {
1052 /**
1053 * Add role for instructor
1054 */
1055 $instructor_role = tutor()->instructor_role;
1056
1057 remove_role( $instructor_role );
1058 add_role( $instructor_role, __( 'Tutor Instructor', 'tutor' ), array() );
1059
1060 $custom_post_type_permission = array(
1061 // Manage Instructor.
1062 'manage_tutor_instructor',
1063
1064 // Tutor Posts Type Permission.
1065 'edit_tutor_course',
1066 'read_tutor_course',
1067 'delete_tutor_course',
1068 'delete_tutor_courses',
1069 'edit_tutor_courses',
1070 'edit_others_tutor_courses',
1071 'read_private_tutor_courses',
1072 'edit_tutor_courses',
1073
1074 'edit_tutor_lesson',
1075 'read_tutor_lesson',
1076 'delete_tutor_lesson',
1077 'delete_tutor_lessons',
1078 'edit_tutor_lessons',
1079 'edit_others_tutor_lessons',
1080 'read_private_tutor_lessons',
1081 'edit_tutor_lessons',
1082 'publish_tutor_lessons',
1083
1084 'edit_tutor_quiz',
1085 'read_tutor_quiz',
1086 'delete_tutor_quiz',
1087 'delete_tutor_quizzes',
1088 'edit_tutor_quizzes',
1089 'edit_others_tutor_quizzes',
1090 'read_private_tutor_quizzes',
1091 'edit_tutor_quizzes',
1092 'publish_tutor_quizzes',
1093
1094 'edit_tutor_question',
1095 'read_tutor_question',
1096 'delete_tutor_question',
1097 'delete_tutor_questions',
1098 'edit_tutor_questions',
1099 'edit_others_tutor_questions',
1100 'publish_tutor_questions',
1101 'read_private_tutor_questions',
1102 'edit_tutor_questions',
1103 );
1104
1105 $instructor = get_role( $instructor_role );
1106 if ( $instructor ) {
1107 $instructor_cap = array(
1108 'edit_posts',
1109 'read',
1110 'upload_files',
1111 );
1112
1113 $instructor_cap = array_merge( $instructor_cap, $custom_post_type_permission );
1114
1115 $can_publish_course = (bool) tutor_utils()->get_option( 'instructor_can_publish_course' );
1116 if ( $can_publish_course ) {
1117 $instructor_cap[] = 'publish_tutor_courses';
1118 }
1119
1120 foreach ( $instructor_cap as $cap ) {
1121 $instructor->add_cap( $cap );
1122 }
1123 }
1124
1125 $administrator = get_role( 'administrator' );
1126 if ( $administrator ) {
1127
1128 $administrator_cap = array(
1129 'manage_tutor',
1130 );
1131 $administrator_cap = array_merge( $administrator_cap, $custom_post_type_permission );
1132 $administrator_cap[] = 'publish_tutor_courses';
1133
1134 foreach ( $administrator_cap as $cap ) {
1135 $administrator->add_cap( $cap );
1136 }
1137 }
1138
1139 /**
1140 * Add Instructor role to administrator
1141 */
1142 if ( current_user_can( 'administrator' ) ) {
1143 tutor_utils()->add_instructor_role( get_current_user_id() );
1144 }
1145 }
1146
1147 /**
1148 * On plugin activate save initial data
1149 * Like: generate tutor pages
1150 *
1151 * @since 1.0.0
1152 *
1153 * @return void
1154 */
1155 public static function save_data() {
1156
1157 $student_dashboard_args = array(
1158 'post_title' => __( 'Dashboard', 'tutor' ),
1159 'post_content' => '',
1160 'post_type' => 'page',
1161 'post_status' => 'publish',
1162 );
1163 $student_dashboard_page_id = wp_insert_post( $student_dashboard_args );
1164 tutor_utils()->update_option( 'tutor_dashboard_page_id', $student_dashboard_page_id );
1165
1166 $student_registration_args = array(
1167 'post_title' => __( 'Student Registration', 'tutor' ),
1168 'post_content' => '[tutor_student_registration_form]',
1169 'post_type' => 'page',
1170 'post_status' => 'publish',
1171 );
1172 $student_register_page_id = wp_insert_post( $student_registration_args );
1173 tutor_utils()->update_option( 'student_register_page', $student_register_page_id );
1174
1175 $instructor_registration_args = array(
1176 'post_title' => __( 'Instructor Registration', 'tutor' ),
1177 'post_content' => '[tutor_instructor_registration_form]',
1178 'post_type' => 'page',
1179 'post_status' => 'publish',
1180 );
1181 $instructor_registration_id = wp_insert_post( $instructor_registration_args );
1182 tutor_utils()->update_option( 'instructor_register_page', $instructor_registration_id );
1183 }
1184
1185 /**
1186 * Default options
1187 *
1188 * @since 1.0.0
1189 *
1190 * @since 3.4.1 Supported video sources added
1191 *
1192 * @return array
1193 */
1194 public static function default_options() {
1195 $options = array(
1196 'pagination_per_page' => '20',
1197 'course_allow_upload_private_files' => '1',
1198 'display_course_instructors' => '1',
1199 'enable_q_and_a_on_course' => '1',
1200 'courses_col_per_row' => '3',
1201 'courses_per_page' => '12',
1202 'course_permalink_base' => 'courses',
1203 'lesson_permalink_base' => 'lessons',
1204 'quiz_when_time_expires' => 'autosubmit',
1205 'quiz_attempts_allowed' => '10',
1206 'quiz_grade_method' => 'highest_grade',
1207 'enable_public_profile' => '1',
1208 'email_to_students' =>
1209 array(
1210 'quiz_completed' => '1',
1211 'completed_course' => '1',
1212 ),
1213 'email_to_instructors' =>
1214 array(
1215 'a_student_enrolled_in_course' => '1',
1216 'a_student_completed_course' => '1',
1217 'a_student_completed_lesson' => '1',
1218 'a_student_placed_question' => '1',
1219 ),
1220 'email_from_name' => get_option( 'blogname' ),
1221 'email_from_address' => get_option( 'admin_email' ),
1222 'email_footer_text' => '',
1223 'earning_admin_commission' => '20',
1224 'earning_instructor_commission' => '80',
1225 'color_preset_type' => 'default',
1226
1227 // Default options for tutor ecommerce.
1228 'monetize_by' => Ecommerce::MONETIZE_BY,
1229 'currency_code' => 'USD',
1230 'currency_position' => 'left',
1231 'thousand_separator' => ',',
1232 'decimal_separator' => '.',
1233 'number_of_decimals' => '2',
1234 'is_coupon_applicable' => 'on',
1235 'supported_video_sources' => array(
1236 'html5',
1237 'external_url',
1238 'youtube',
1239 'vimeo',
1240 'embedded',
1241 'shortcode',
1242 ),
1243 );
1244
1245 return $options;
1246 }
1247
1248
1249 /**
1250 * Create withdraw database
1251 *
1252 * @since 1.2.0
1253 */
1254 public static function create_withdraw_database() {
1255 global $wpdb;
1256
1257 $charset_collate = $wpdb->get_charset_collate();
1258
1259 /**
1260 * Table SQL
1261 *
1262 * {$wpdb->prefix}tutor_earnings
1263 * {$wpdb->prefix}tutor_withdraws
1264 *
1265 * @since 1.2.0
1266 */
1267
1268 $earning_table = "CREATE TABLE IF NOT EXISTS {$wpdb->prefix}tutor_earnings (
1269 earning_id bigint(20) NOT NULL AUTO_INCREMENT,
1270 user_id bigint(20) DEFAULT NULL,
1271 course_id bigint(20) DEFAULT NULL,
1272 order_id bigint(20) DEFAULT NULL,
1273 order_status varchar(50) DEFAULT NULL,
1274 course_price_total decimal(16,2) DEFAULT NULL,
1275 course_price_grand_total decimal(16,2) DEFAULT NULL,
1276 instructor_amount decimal(16,2) DEFAULT NULL,
1277 instructor_rate decimal(16,2) DEFAULT NULL,
1278 admin_amount decimal(16,2) DEFAULT NULL,
1279 admin_rate decimal(16,2) DEFAULT NULL,
1280 commission_type varchar(20) DEFAULT NULL,
1281 deduct_fees_amount decimal(16,2) DEFAULT NULL,
1282 deduct_fees_name varchar(250) DEFAULT NULL,
1283 deduct_fees_type varchar(20) DEFAULT NULL,
1284 process_by varchar(20) DEFAULT NULL,
1285 created_at datetime DEFAULT NULL,
1286 PRIMARY KEY (earning_id)
1287 ) $charset_collate;";
1288
1289 $withdraw_table = "CREATE TABLE IF NOT EXISTS {$wpdb->prefix}tutor_withdraws (
1290 withdraw_id bigint(20) NOT NULL AUTO_INCREMENT,
1291 user_id bigint(20) DEFAULT NULL,
1292 amount decimal(16,2) DEFAULT NULL,
1293 method_data text DEFAULT NULL,
1294 status varchar(50) DEFAULT NULL,
1295 updated_at datetime DEFAULT NULL,
1296 created_at datetime DEFAULT NULL,
1297 PRIMARY KEY (withdraw_id)
1298 ) $charset_collate;";
1299
1300 require_once ABSPATH . 'wp-admin/includes/upgrade.php';
1301 dbDelta( $earning_table );
1302 dbDelta( $withdraw_table );
1303
1304 /**
1305 * Setting previous dashboard to new dashboard
1306 */
1307 $previous_dashboard_page_id = (int) tutor_utils()->get_option( 'student_dashboard' );
1308 tutor_utils()->update_option( 'tutor_dashboard_page_id', $previous_dashboard_page_id );
1309 }
1310
1311 /**
1312 * Filter the wp_doing_ajax from tutor requests to get advanced
1313 * advantages from Tutor
1314 *
1315 * @since 1.3.4
1316 *
1317 * @param bool $bool default value.
1318 *
1319 * @return bool
1320 */
1321 public function wp_doing_ajax( $bool ) {
1322 // Don't use Input::has helper to avoid conflict.
1323 if ( isset( $_REQUEST['tutor_ajax_action'] ) ) {
1324 return true;
1325 }
1326 return $bool;
1327 }
1328
1329 /**
1330 * Handle plugin un-installation
1331 *
1332 * @since 2.6.2
1333 *
1334 * @return void
1335 */
1336 public static function tutor_uninstall() {
1337 self::erase_tutor_data();
1338 }
1339
1340 /**
1341 * Erase tutor data
1342 *
1343 * @since 2.6.2
1344 *
1345 * @return void
1346 */
1347 public static function erase_tutor_data() {
1348 global $wpdb;
1349
1350 $is_erase_data = tutor_utils()->get_option( 'delete_on_uninstall' );
1351 // Deleting Data.
1352
1353 if ( $is_erase_data ) {
1354 /**
1355 * Deleting Post Type, Meta Data, taxonomy
1356 */
1357 $course_post_type = tutor()->course_post_type;
1358 $lesson_post_type = tutor()->lesson_post_type;
1359
1360 $post_types = array(
1361 $course_post_type,
1362 $lesson_post_type,
1363 'tutor_quiz',
1364 'tutor_enrolled',
1365 'topics',
1366 'tutor_enrolled',
1367 'tutor_announcements',
1368 );
1369
1370 $in_clause = QueryHelper::prepare_in_clause( $post_types );
1371 $tutor_posts = $wpdb->get_col( $wpdb->prepare( "SELECT ID from {$wpdb->posts} WHERE post_type IN({$in_clause}) ;" ) ); //phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
1372
1373 if ( is_array( $tutor_posts ) && count( $tutor_posts ) ) {
1374 foreach ( $tutor_posts as $post_id ) {
1375 // Delete categories.
1376 $terms = wp_get_object_terms( $post_id, CourseModel::COURSE_CATEGORY );
1377 foreach ( $terms as $term ) {
1378 wp_remove_object_terms( $post_id, array( $term->term_id ), CourseModel::COURSE_CATEGORY );
1379 }
1380
1381 // Delete tags if available.
1382 $terms = wp_get_object_terms( $post_id, CourseModel::COURSE_TAG );
1383 foreach ( $terms as $term ) {
1384 wp_remove_object_terms( $post_id, array( $term->term_id ), CourseModel::COURSE_TAG );
1385 }
1386
1387 // Delete All Meta.
1388 $wpdb->delete( $wpdb->postmeta, array( 'post_id' => $post_id ) );
1389 $wpdb->delete( $wpdb->posts, array( 'ID' => $post_id ) );
1390 }
1391 }
1392
1393 /**
1394 * Deleting Comments (reviews, questions, quiz_answers, etc)
1395 */
1396 $tutor_comments = $wpdb->get_col( "SELECT comment_ID from {$wpdb->comments} WHERE comment_agent = 'comment_agent' ;" );
1397 if ( is_array( $tutor_comments ) && count( $tutor_comments ) ) {
1398 $in_clause = QueryHelper::prepare_in_clause( $tutor_comments );
1399 $wpdb->query( $wpdb->prepare( "DELETE from {$wpdb->commentmeta} WHERE comment_ID in({$in_clause}) " ) ); //phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
1400 }
1401 $wpdb->delete( $wpdb->comments, array( 'comment_agent' => 'comment_agent' ) );
1402
1403 /**
1404 * Delete Options
1405 */
1406
1407 delete_option( 'tutor_option' );
1408 $wpdb->delete( $wpdb->usermeta, array( 'meta_key' => '_is_tutor_student' ) );
1409 $wpdb->delete( $wpdb->usermeta, array( 'meta_key' => '_tutor_instructor_approved' ) );
1410 $wpdb->delete( $wpdb->usermeta, array( 'meta_key' => '_tutor_instructor_status' ) );
1411 $wpdb->delete( $wpdb->usermeta, array( 'meta_key' => '_is_tutor_instructor' ) );
1412 $wpdb->query( "DELETE FROM {$wpdb->usermeta} WHERE meta_key LIKE '%_tutor_completed_lesson_id_%' " );
1413
1414 // Deleting Table.
1415 $prefix = $wpdb->prefix;
1416 //phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
1417 $wpdb->query( "DROP TABLE IF EXISTS {$prefix}tutor_quiz_attempts, {$prefix}tutor_quiz_attempt_answers, {$prefix}tutor_quiz_questions, {$prefix}tutor_quiz_question_answers, {$prefix}tutor_earnings, {$prefix}tutor_withdraws " );
1418
1419 }
1420 }
1421 }
1422