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