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