PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / trunk
Tutor LMS – eLearning and online course solution vtrunk
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 6 days 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 4 days ago Course_Embed.php 3 years ago Course_Filter.php 6 days 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 6 days 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 6 days 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 6 days ago Video_Stream.php 6 days 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
1483 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 // add_filter( 'rest_request_before_callbacks', array( $this, 'enforce_courses_privacy_rest_api' ), 10, 3 );
593 }
594
595 /**
596 * Check activated plugin
597 *
598 * @since 1.5.7
599 *
600 * @param mixed $plugin plugin.
601 * @param mixed $network_wide network wide.
602 *
603 * @return void
604 */
605 public function activated_tutor( $plugin, $network_wide = null ) {
606 if ( tutor()->basename === $plugin ) {
607 $this->redirect_to_setup_page();
608 }
609 }
610
611 /**
612 * Redirect to setup page
613 *
614 * @since 2.8.0
615 *
616 * @return void
617 */
618 public function redirect_to_setup_page() {
619 if ( ( ! get_option( 'tutor_wizard' ) ) && version_compare( TUTOR_VERSION, '1.5.6', '>' ) ) {
620 if ( ! wp_doing_ajax() ) {
621 update_option( 'tutor_wizard', 'active' );
622 $is_wp_cli = defined( 'WP_CLI' ) && WP_CLI;
623 if ( ! $is_wp_cli ) {
624 wp_safe_redirect( admin_url( 'admin.php?page=tutor-setup' ) );
625 }
626 exit;
627 }
628 }
629 }
630
631 /**
632 * Include utility functions
633 *
634 * @return void
635 */
636 public function includes() {
637 $tutor_path = plugin_dir_path( TUTOR_FILE );
638
639 include $tutor_path . 'includes/tutor-general-functions.php';
640 include $tutor_path . 'includes/tutor-template-functions.php';
641 include $tutor_path . 'includes/tutor-template-hook.php';
642 include $tutor_path . 'includes/translate-text.php';
643 include $tutor_path . 'includes/country.php';
644 include $tutor_path . 'includes/ecommerce-functions.php';
645
646 if ( ! function_exists( 'is_plugin_active' ) ) {
647 require_once ABSPATH . 'wp-admin/includes/plugin.php';
648 }
649
650 // Only kirki latest has class KirkiMain.
651 $is_kirki_active = \is_plugin_active( 'kirki-pro/kirki-pro.php' ) && class_exists( 'KirkiProMain' );
652
653 if ( $is_kirki_active ) {
654 $tutor_kirki_path = $tutor_path . 'includes/kirki/kirki.php';
655 if ( file_exists( $tutor_kirki_path ) ) {
656 include $tutor_kirki_path;
657 }
658 } else {
659 $is_droip_active = \is_plugin_active( 'droip/droip.php' );
660 $tutor_droip_path = $tutor_path . 'includes/droip/droip.php';
661 if ( $is_droip_active && file_exists( $tutor_droip_path ) ) {
662 include $tutor_droip_path;
663 }
664 }
665 }
666
667 /**
668 * Providing hooks
669 *
670 * @return void
671 */
672 public function run() {
673 do_action( 'tutor_before_run' );
674 do_action( 'tutor_after_run' );
675 }
676
677 /**
678 * Tutor Action Via do_action
679 *
680 * @since 1.2.14
681 */
682 public function init_action() {
683 $tutor_action = Input::sanitize_request_data( 'tutor_action' );
684 if ( '' !== $tutor_action ) {
685 do_action( 'tutor_action_' . $tutor_action );
686 }
687 }
688
689 /**
690 * Do some task during plugin activation
691 *
692 * @since 4.0.0 Flush rewrite rules on activation.
693 */
694 public static function tutor_activate() {
695 // Rewrite Flush.
696 Permalink::set_permalink_flag();
697
698 $version = get_option( 'tutor_version' );
699 if ( ! function_exists( 'tutor_time' ) ) {
700 include tutor()->path . 'includes/tutor-general-functions.php';
701 }
702
703 // Create Database.
704 self::create_database();
705
706 // Save Option.
707 if ( ! $version ) {
708
709 $options = self::default_options();
710 update_option( 'tutor_option', $options );
711
712 self::manage_tutor_roles_and_permissions();
713
714 // Save initial Page.
715 self::save_data();
716 update_option( 'tutor_version', TUTOR_VERSION );
717 }
718
719 // Set Schedule.
720 if ( ! wp_next_scheduled( 'tutor_once_in_day_run_schedule' ) ) {
721 wp_schedule_event( tutor_time(), 'twicedaily', 'tutor_once_in_day_run_schedule' );
722 }
723
724 /**
725 * Backward Compatibility for version < 1.2.0
726 */
727 if ( version_compare( get_option( 'tutor_version' ), '1.2.0', '<' ) ) {
728 /**
729 * Creating New Database
730 */
731 self::create_withdraw_database();
732 // Update the tutor version.
733 update_option( 'tutor_version', '1.2.0' );
734 }
735
736 /**
737 * Backward Compatibility to < 1.3.1 for make course plural
738 */
739 if ( version_compare( get_option( 'tutor_version' ), '1.3.1', '<' ) ) {
740 global $wpdb;
741
742 if ( ! get_option( 'is_course_post_type_updated' ) ) {
743 $wpdb->update( $wpdb->posts, array( 'post_type' => tutor()->course_post_type ), array( 'post_type' => 'course' ) );
744 update_option( 'is_course_post_type_updated', true );
745 update_option( 'tutor_version', '1.3.1' );
746 }
747 }
748
749 /**
750 * Save First activation Time
751 */
752 $first_activation_date = get_option( 'tutor_first_activation_time' );
753 if ( ! $first_activation_date ) {
754 update_option( 'tutor_first_activation_time', tutor_time() );
755 }
756 }
757
758 /**
759 * Run task on deactivation
760 *
761 * @since 1.0.0
762 *
763 * @return void
764 */
765 public static function tutor_deactivation() {
766 wp_clear_scheduled_hook( 'tutor_once_in_day_run_schedule' );
767 }
768
769 /**
770 * Create database
771 *
772 * @return void
773 */
774 public static function create_database() {
775 global $wpdb;
776
777 $charset_collate = $wpdb->get_charset_collate();
778
779 /**
780 * Table SQL
781 *
782 * {$wpdb->prefix}tutor_quiz_attempts
783 * {$wpdb->prefix}tutor_quiz_attempt_answers
784 * {$wpdb->prefix}tutor_quiz_questions
785 * {$wpdb->prefix}tutor_quiz_question_answers
786 * {$wpdb->prefix}tutor_earnings
787 * {$wpdb->prefix}tutor_withdraws
788 *
789 * @since 1.0.0
790 */
791 $quiz_attempts_sql = "CREATE TABLE {$wpdb->prefix}tutor_quiz_attempts (
792 attempt_id bigint(20) NOT NULL AUTO_INCREMENT,
793 course_id bigint(20) DEFAULT NULL,
794 quiz_id bigint(20) DEFAULT NULL,
795 user_id bigint(20) DEFAULT NULL,
796 total_questions int(11) DEFAULT NULL,
797 total_answered_questions int(11) DEFAULT NULL,
798 total_marks decimal(9,2) DEFAULT NULL,
799 earned_marks decimal(9,2) DEFAULT NULL,
800 attempt_info text,
801 attempt_status varchar(50) DEFAULT NULL,
802 attempt_ip varchar(250) DEFAULT NULL,
803 attempt_started_at datetime DEFAULT NULL,
804 attempt_ended_at datetime DEFAULT NULL,
805 is_manually_reviewed int(1) DEFAULT NULL,
806 manually_reviewed_at datetime DEFAULT NULL,
807 result varchar(10) DEFAULT NULL,
808 PRIMARY KEY (attempt_id),
809 INDEX (course_id),
810 INDEX (quiz_id),
811 INDEX (user_id),
812 INDEX (result)
813 ) $charset_collate;";
814
815 $quiz_attempt_answers = "CREATE TABLE {$wpdb->prefix}tutor_quiz_attempt_answers (
816 attempt_answer_id bigint(20) NOT NULL AUTO_INCREMENT,
817 user_id bigint(20) DEFAULT NULL,
818 quiz_id bigint(20) DEFAULT NULL,
819 question_id bigint(20) DEFAULT NULL,
820 quiz_attempt_id bigint(20) DEFAULT NULL,
821 given_answer longtext,
822 question_mark decimal(8,2) DEFAULT NULL,
823 achieved_mark decimal(8,2) DEFAULT NULL,
824 minus_mark decimal(8,2) DEFAULT NULL,
825 is_correct tinyint(4) DEFAULT NULL,
826 PRIMARY KEY (attempt_answer_id)
827 ) $charset_collate;";
828
829 $tutor_quiz_questions = "CREATE TABLE {$wpdb->prefix}tutor_quiz_questions (
830 question_id bigint(20) NOT NULL AUTO_INCREMENT,
831 quiz_id bigint(20) DEFAULT NULL,
832 question_title text,
833 question_description longtext,
834 answer_explanation longtext DEFAULT '',
835 question_type varchar(50) DEFAULT NULL,
836 question_mark decimal(9,2) DEFAULT NULL,
837 question_settings longtext,
838 question_order int(11) DEFAULT NULL,
839 PRIMARY KEY (question_id)
840 ) $charset_collate;";
841
842 $tutor_quiz_question_answers = "CREATE TABLE {$wpdb->prefix}tutor_quiz_question_answers (
843 answer_id bigint(20) NOT NULL AUTO_INCREMENT,
844 belongs_question_id bigint(20) DEFAULT NULL,
845 belongs_question_type varchar(250) DEFAULT NULL,
846 answer_title text,
847 is_correct tinyint(4) DEFAULT NULL,
848 image_id bigint(20) DEFAULT NULL,
849 answer_two_gap_match text,
850 answer_view_format varchar(250) DEFAULT NULL,
851 answer_settings text,
852 answer_order int(11) DEFAULT '0',
853 PRIMARY KEY (answer_id)
854 ) $charset_collate;";
855
856 $earning_table = "CREATE TABLE IF NOT EXISTS {$wpdb->prefix}tutor_earnings (
857 earning_id bigint(20) NOT NULL AUTO_INCREMENT,
858 user_id bigint(20) DEFAULT NULL,
859 course_id bigint(20) DEFAULT NULL,
860 order_id bigint(20) DEFAULT NULL,
861 order_status varchar(50) DEFAULT NULL,
862 course_price_total decimal(16,2) DEFAULT NULL,
863 course_price_grand_total decimal(16,2) DEFAULT NULL,
864 instructor_amount decimal(16,2) DEFAULT NULL,
865 instructor_rate decimal(16,2) DEFAULT NULL,
866 admin_amount decimal(16,2) DEFAULT NULL,
867 admin_rate decimal(16,2) DEFAULT NULL,
868 commission_type varchar(20) DEFAULT NULL,
869 deduct_fees_amount decimal(16,2) DEFAULT NULL,
870 deduct_fees_name varchar(250) DEFAULT NULL,
871 deduct_fees_type varchar(20) DEFAULT NULL,
872 process_by varchar(20) DEFAULT NULL,
873 created_at datetime DEFAULT NULL,
874 PRIMARY KEY (earning_id),
875 INDEX (user_id),
876 INDEX (course_id),
877 INDEX (order_id),
878 INDEX (process_by)
879 ) $charset_collate;";
880
881 $withdraw_table = "CREATE TABLE IF NOT EXISTS {$wpdb->prefix}tutor_withdraws (
882 withdraw_id bigint(20) NOT NULL AUTO_INCREMENT,
883 user_id bigint(20) DEFAULT NULL,
884 amount decimal(16,2) DEFAULT NULL,
885 method_data text DEFAULT NULL,
886 status varchar(50) DEFAULT NULL,
887 updated_at datetime DEFAULT NULL,
888 created_at datetime DEFAULT NULL,
889 PRIMARY KEY (withdraw_id)
890 ) $charset_collate;";
891
892 $orders_table = "CREATE TABLE {$wpdb->prefix}tutor_orders (
893 id BIGINT(20) UNSIGNED AUTO_INCREMENT,
894 parent_id BIGINT(20) UNSIGNED DEFAULT 0, -- for subscription order, store subscription record id
895 transaction_id VARCHAR(255) COMMENT 'Transaction id from payment gateway',
896 user_id BIGINT(20) UNSIGNED NOT NULL,
897 order_type VARCHAR(50) NOT NULL, -- single_order, subscription
898 order_status VARCHAR(50) NOT NULL,
899 payment_status VARCHAR(50) NOT NULL,
900 subtotal_price DECIMAL(13, 2) NOT NULL, -- price calculation based on course sale price
901 pre_tax_price DECIMAL(13, 2) NOT NULL, -- total price before adding tax
902 tax_type VARCHAR(50),
903 tax_rate DECIMAL(13, 2) COMMENT 'Tax percentage',
904 tax_amount DECIMAL(13, 2),
905 total_price DECIMAL(13, 2) NOT NULL, -- final price
906 net_payment DECIMAL(13, 2) NOT NULL, -- calculated price if any refund is done else same as total_price
907 coupon_code VARCHAR(255),
908 coupon_amount DECIMAL(13, 2),
909 discount_type ENUM('percentage', 'flat') DEFAULT NULL,
910 discount_amount DECIMAL(13, 2),
911 discount_reason TEXT,
912 fees DECIMAL(13, 2), -- payment gateway fees
913 earnings DECIMAL(13, 2), -- net earning
914 refund_amount DECIMAL(13, 2), -- Refund amount
915 payment_method VARCHAR(255),
916 payment_payloads LONGTEXT,
917 note TEXT,
918 created_at_gmt DATETIME NOT NULL,
919 created_by BIGINT(20) UNSIGNED NOT NULL,
920 updated_at_gmt DATETIME,
921 updated_by BIGINT(20) UNSIGNED NOT NULL,
922 PRIMARY KEY (id),
923 KEY user_id (user_id),
924 KEY order_type (order_type),
925 KEY payment_status (payment_status),
926 KEY order_status (order_status),
927 KEY transaction_id (transaction_id)
928 ) $charset_collate;";
929
930 $order_meta_table = "CREATE TABLE {$wpdb->prefix}tutor_ordermeta (
931 id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
932 order_id BIGINT(20) UNSIGNED NOT NULL,
933 meta_key VARCHAR(255) NOT NULL,
934 meta_value LONGTEXT NOT NULL,
935 created_at_gmt DATETIME NOT NULL,
936 created_by BIGINT(20) UNSIGNED NOT NULL,
937 updated_at_gmt DATETIME,
938 updated_by BIGINT(20) UNSIGNED NOT NULL,
939 PRIMARY KEY (id),
940 KEY order_id (order_id),
941 KEY meta_key (meta_key),
942 CONSTRAINT fk_tutor_ordermeta_order_id FOREIGN KEY (order_id) REFERENCES {$wpdb->prefix}tutor_orders(id) ON DELETE CASCADE
943 ) $charset_collate;";
944
945 $order_items_table = "CREATE TABLE {$wpdb->prefix}tutor_order_items (
946 id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
947 order_id BIGINT(20) UNSIGNED NOT NULL,
948 item_id BIGINT(20) UNSIGNED NOT NULL, -- course id/plan id
949 regular_price DECIMAL(13, 2) NOT NULL, -- course regular price
950 sale_price VARCHAR(13) DEFAULT NULL, -- course sale price
951 discount_price VARCHAR(13) DEFAULT NULL, -- course discount price
952 coupon_code VARCHAR(255) DEFAULT NULL, -- coupon code
953 PRIMARY KEY (id),
954 KEY order_id (order_id),
955 KEY item_id (item_id),
956 CONSTRAINT fk_tutor_order_item_order_id FOREIGN KEY (order_id) REFERENCES {$wpdb->prefix}tutor_orders(id) ON DELETE CASCADE
957 ) $charset_collate;";
958
959 $coupons_table = "CREATE TABLE {$wpdb->prefix}tutor_coupons (
960 id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
961 coupon_status VARCHAR(50),
962 coupon_type VARCHAR(100) DEFAULT 'code', -- coupon type 'code' or 'automatic'
963 coupon_code VARCHAR(50) NOT NULL,
964 coupon_title VARCHAR(255) NOT NULL,
965 coupon_description TEXT,
966 discount_type ENUM('percentage', 'flat') NOT NULL,
967 discount_amount DECIMAL(13, 2) NOT NULL,
968 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'
969 total_usage_limit INT(10) UNSIGNED DEFAULT NULL, -- null for unlimited usage
970 per_user_usage_limit TINYINT(4) UNSIGNED DEFAULT NULL, -- null for unlimited usage
971 purchase_requirement VARCHAR(50) DEFAULT 'no_minimum', -- possible values 'no_minimum', 'minimum_purchase', 'minimum_quantity'
972 purchase_requirement_value DECIMAL(13, 2),
973 start_date_gmt DATETIME NOT NULL,
974 expire_date_gmt DATETIME DEFAULT NULL,
975 created_at_gmt DATETIME NOT NULL,
976 created_by BIGINT(20) UNSIGNED NOT NULL,
977 updated_at_gmt DATETIME,
978 updated_by BIGINT(20) UNSIGNED NOT NULL,
979 PRIMARY KEY (id),
980 UNIQUE KEY coupon_code (coupon_code),
981 KEY start_date_gmt (start_date_gmt),
982 KEY expire_date_gmt (expire_date_gmt)
983 ) $charset_collate;";
984
985 $coupon_applications_table = "CREATE TABLE {$wpdb->prefix}tutor_coupon_applications (
986 coupon_code VARCHAR(50) NOT NULL,
987 reference_id BIGINT(20) UNSIGNED NOT NULL,
988 KEY coupon_code (coupon_code),
989 KEY reference_id (reference_id),
990 CONSTRAINT fk_tutor_coupon_application_coupon_code FOREIGN KEY (coupon_code) REFERENCES {$wpdb->prefix}tutor_coupons(coupon_code) ON DELETE CASCADE
991 ) $charset_collate;";
992
993 $coupon_usage_table = "CREATE TABLE {$wpdb->prefix}tutor_coupon_usages (
994 id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
995 coupon_code VARCHAR(50) NOT NULL,
996 user_id BIGINT(20) UNSIGNED NOT NULL,
997 PRIMARY KEY (id),
998 KEY coupon_code (coupon_code),
999 KEY user_id (user_id),
1000 CONSTRAINT fk_tutor_coupon_usage_coupon_code FOREIGN KEY (coupon_code) REFERENCES {$wpdb->prefix}tutor_coupons(coupon_code) ON DELETE CASCADE,
1001 CONSTRAINT fk_tutor_coupon_usage_user_id FOREIGN KEY (user_id) REFERENCES {$wpdb->prefix}users(ID) ON DELETE CASCADE
1002 ) $charset_collate;";
1003
1004 $cart_table = "CREATE TABLE {$wpdb->prefix}tutor_carts (
1005 id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
1006 user_id BIGINT(20) UNSIGNED DEFAULT NULL,
1007 coupon_code VARCHAR(50) DEFAULT NULL,
1008 created_at_gmt DATETIME NOT NULL,
1009 updated_at_gmt DATETIME,
1010 PRIMARY KEY (id),
1011 KEY user_id (user_id),
1012 KEY coupon_code (coupon_code),
1013 CONSTRAINT fk_tutor_cart_user_id FOREIGN KEY (user_id) REFERENCES {$wpdb->prefix}users(ID) ON DELETE CASCADE
1014 ) $charset_collate;";
1015
1016 $cart_items_table = "CREATE TABLE {$wpdb->prefix}tutor_cart_items (
1017 id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
1018 cart_id BIGINT(20) UNSIGNED NOT NULL,
1019 course_id BIGINT(20) UNSIGNED NOT NULL,
1020 PRIMARY KEY (id),
1021 KEY cart_id (cart_id),
1022 KEY course_id (course_id),
1023 CONSTRAINT fk_tutor_cart_item_cart_id FOREIGN KEY (cart_id) REFERENCES {$wpdb->prefix}tutor_carts(id) ON DELETE CASCADE,
1024 CONSTRAINT fk_tutor_cart_item_course_id FOREIGN KEY (course_id) REFERENCES {$wpdb->prefix}posts(ID) ON DELETE CASCADE
1025 ) $charset_collate;";
1026
1027 $customer_table = "CREATE TABLE {$wpdb->prefix}tutor_customers (
1028 id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
1029 user_id BIGINT(20) UNSIGNED DEFAULT NULL,
1030 billing_first_name VARCHAR(255) NOT NULL,
1031 billing_last_name VARCHAR(255) NOT NULL,
1032 billing_email VARCHAR(255) NOT NULL,
1033 billing_phone VARCHAR(20) NOT NULL,
1034 billing_zip_code VARCHAR(20) NOT NULL,
1035 billing_address TEXT NOT NULL,
1036 billing_country VARCHAR(100) NOT NULL,
1037 billing_state VARCHAR(100) NOT NULL,
1038 billing_city VARCHAR(100) NOT NULL,
1039 PRIMARY KEY (id),
1040 KEY user_id (user_id),
1041 KEY billing_email (billing_email)
1042 ) $charset_collate;";
1043
1044 require_once ABSPATH . 'wp-admin/includes/upgrade.php';
1045 dbDelta( $quiz_attempts_sql );
1046 dbDelta( $quiz_attempt_answers );
1047 dbDelta( $tutor_quiz_questions );
1048 dbDelta( $tutor_quiz_question_answers );
1049 dbDelta( $earning_table );
1050 dbDelta( $withdraw_table );
1051 dbDelta( $orders_table );
1052 dbDelta( $order_meta_table );
1053 dbDelta( $order_items_table );
1054 dbDelta( $coupons_table );
1055 dbDelta( $coupon_applications_table );
1056 dbDelta( $coupon_usage_table );
1057 dbDelta( $cart_table );
1058 dbDelta( $cart_items_table );
1059 dbDelta( $customer_table );
1060 }
1061
1062 /**
1063 * Manage tutor roles & permission
1064 *
1065 * @return void
1066 */
1067 public static function manage_tutor_roles_and_permissions() {
1068 /**
1069 * Add role for instructor
1070 */
1071 $instructor_role = tutor()->instructor_role;
1072
1073 remove_role( $instructor_role );
1074 add_role( $instructor_role, __( 'Tutor Instructor', 'tutor' ), array() );
1075
1076 $custom_post_type_permission = array(
1077 // Manage Instructor.
1078 'manage_tutor_instructor',
1079
1080 // Tutor Posts Type Permission.
1081 'edit_tutor_course',
1082 'read_tutor_course',
1083 'delete_tutor_course',
1084 'delete_tutor_courses',
1085 'edit_tutor_courses',
1086 'edit_tutor_courses',
1087
1088 'edit_tutor_lesson',
1089 'read_tutor_lesson',
1090 'delete_tutor_lesson',
1091 'delete_tutor_lessons',
1092 'edit_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 'edit_tutor_quizzes',
1102 'publish_tutor_quizzes',
1103
1104 'edit_tutor_question',
1105 'read_tutor_question',
1106 'delete_tutor_question',
1107 'delete_tutor_questions',
1108 'edit_tutor_questions',
1109 'publish_tutor_questions',
1110 'edit_tutor_questions',
1111 );
1112
1113 $instructor = get_role( $instructor_role );
1114 if ( $instructor ) {
1115 $instructor_cap = array(
1116 'edit_posts',
1117 'read',
1118 'upload_files',
1119 );
1120
1121 $instructor_cap = array_merge( $instructor_cap, $custom_post_type_permission );
1122
1123 $can_publish_course = (bool) tutor_utils()->get_option( 'instructor_can_publish_course' );
1124 if ( $can_publish_course ) {
1125 $instructor_cap[] = 'publish_tutor_courses';
1126 }
1127
1128 foreach ( $instructor_cap as $cap ) {
1129 $instructor->add_cap( $cap );
1130 }
1131 }
1132
1133 $administrator = get_role( 'administrator' );
1134 if ( $administrator ) {
1135
1136 $administrator_cap = array(
1137 'manage_tutor',
1138 );
1139 $administrator_cap = array_merge( $administrator_cap, $custom_post_type_permission );
1140 $administrator_cap[] = 'publish_tutor_courses';
1141
1142 foreach ( $administrator_cap as $cap ) {
1143 $administrator->add_cap( $cap );
1144 }
1145 }
1146
1147 /**
1148 * Add Instructor role to administrator
1149 */
1150 if ( current_user_can( 'administrator' ) ) {
1151 tutor_utils()->add_instructor_role( get_current_user_id() );
1152 }
1153 }
1154
1155 /**
1156 * On plugin activate save initial data
1157 * Like: generate tutor pages
1158 *
1159 * @since 1.0.0
1160 *
1161 * @return void
1162 */
1163 public static function save_data() {
1164
1165 $student_dashboard_args = array(
1166 'post_title' => __( 'Dashboard', 'tutor' ),
1167 'post_content' => '',
1168 'post_type' => 'page',
1169 'post_status' => 'publish',
1170 );
1171 $student_dashboard_page_id = wp_insert_post( $student_dashboard_args );
1172 tutor_utils()->update_option( 'tutor_dashboard_page_id', $student_dashboard_page_id );
1173
1174 $student_registration_args = array(
1175 'post_title' => __( 'Student Registration', 'tutor' ),
1176 'post_content' => '[tutor_student_registration_form]',
1177 'post_type' => 'page',
1178 'post_status' => 'publish',
1179 );
1180 $student_register_page_id = wp_insert_post( $student_registration_args );
1181 tutor_utils()->update_option( 'student_register_page', $student_register_page_id );
1182
1183 $instructor_registration_args = array(
1184 'post_title' => __( 'Instructor Registration', 'tutor' ),
1185 'post_content' => '[tutor_instructor_registration_form]',
1186 'post_type' => 'page',
1187 'post_status' => 'publish',
1188 );
1189 $instructor_registration_id = wp_insert_post( $instructor_registration_args );
1190 tutor_utils()->update_option( 'instructor_register_page', $instructor_registration_id );
1191 }
1192
1193 /**
1194 * Default options
1195 *
1196 * @since 1.0.0
1197 *
1198 * @since 3.4.1 Supported video sources added
1199 *
1200 * @return array
1201 */
1202 public static function default_options() {
1203 $options = array(
1204 'pagination_per_page' => '20',
1205 'course_allow_upload_private_files' => '1',
1206 'display_course_instructors' => '1',
1207 'enable_q_and_a_on_course' => '1',
1208 'courses_col_per_row' => '3',
1209 'courses_per_page' => '12',
1210 'course_permalink_base' => 'courses',
1211 'lesson_permalink_base' => 'lessons',
1212 'quiz_when_time_expires' => 'autosubmit',
1213 'quiz_grade_method' => 'highest_grade',
1214 'enable_public_profile' => '1',
1215 'email_to_students' =>
1216 array(
1217 'quiz_completed' => '1',
1218 'completed_course' => '1',
1219 ),
1220 'email_to_instructors' =>
1221 array(
1222 'a_student_enrolled_in_course' => '1',
1223 'a_student_completed_course' => '1',
1224 'a_student_completed_lesson' => '1',
1225 'a_student_placed_question' => '1',
1226 ),
1227 'email_from_name' => get_option( 'blogname' ),
1228 'email_from_address' => get_option( 'admin_email' ),
1229 'email_footer_text' => '',
1230 'earning_admin_commission' => '20',
1231 'earning_instructor_commission' => '80',
1232
1233 // Default options for tutor ecommerce.
1234 'monetize_by' => Ecommerce::MONETIZE_BY,
1235 'currency_code' => 'USD',
1236 'currency_position' => 'left',
1237 'thousand_separator' => ',',
1238 'decimal_separator' => '.',
1239 'number_of_decimals' => '2',
1240 'is_coupon_applicable' => 'on',
1241 'supported_video_sources' => array(
1242 'html5',
1243 'external_url',
1244 'youtube',
1245 'vimeo',
1246 'embedded',
1247 'shortcode',
1248 ),
1249 );
1250
1251 return $options;
1252 }
1253
1254
1255 /**
1256 * Create withdraw database
1257 *
1258 * @since 1.2.0
1259 */
1260 public static function create_withdraw_database() {
1261 global $wpdb;
1262
1263 $charset_collate = $wpdb->get_charset_collate();
1264
1265 /**
1266 * Table SQL
1267 *
1268 * {$wpdb->prefix}tutor_earnings
1269 * {$wpdb->prefix}tutor_withdraws
1270 *
1271 * @since 1.2.0
1272 */
1273
1274 $earning_table = "CREATE TABLE IF NOT EXISTS {$wpdb->prefix}tutor_earnings (
1275 earning_id bigint(20) NOT NULL AUTO_INCREMENT,
1276 user_id bigint(20) DEFAULT NULL,
1277 course_id bigint(20) DEFAULT NULL,
1278 order_id bigint(20) DEFAULT NULL,
1279 order_status varchar(50) DEFAULT NULL,
1280 course_price_total decimal(16,2) DEFAULT NULL,
1281 course_price_grand_total decimal(16,2) DEFAULT NULL,
1282 instructor_amount decimal(16,2) DEFAULT NULL,
1283 instructor_rate decimal(16,2) DEFAULT NULL,
1284 admin_amount decimal(16,2) DEFAULT NULL,
1285 admin_rate decimal(16,2) DEFAULT NULL,
1286 commission_type varchar(20) DEFAULT NULL,
1287 deduct_fees_amount decimal(16,2) DEFAULT NULL,
1288 deduct_fees_name varchar(250) DEFAULT NULL,
1289 deduct_fees_type varchar(20) DEFAULT NULL,
1290 process_by varchar(20) DEFAULT NULL,
1291 created_at datetime DEFAULT NULL,
1292 PRIMARY KEY (earning_id)
1293 ) $charset_collate;";
1294
1295 $withdraw_table = "CREATE TABLE IF NOT EXISTS {$wpdb->prefix}tutor_withdraws (
1296 withdraw_id bigint(20) NOT NULL AUTO_INCREMENT,
1297 user_id bigint(20) DEFAULT NULL,
1298 amount decimal(16,2) DEFAULT NULL,
1299 method_data text DEFAULT NULL,
1300 status varchar(50) DEFAULT NULL,
1301 updated_at datetime DEFAULT NULL,
1302 created_at datetime DEFAULT NULL,
1303 PRIMARY KEY (withdraw_id)
1304 ) $charset_collate;";
1305
1306 require_once ABSPATH . 'wp-admin/includes/upgrade.php';
1307 dbDelta( $earning_table );
1308 dbDelta( $withdraw_table );
1309
1310 /**
1311 * Setting previous dashboard to new dashboard
1312 */
1313 $previous_dashboard_page_id = (int) tutor_utils()->get_option( 'student_dashboard' );
1314 tutor_utils()->update_option( 'tutor_dashboard_page_id', $previous_dashboard_page_id );
1315 }
1316
1317 /**
1318 * Filter the wp_doing_ajax from tutor requests to get advanced
1319 * advantages from Tutor
1320 *
1321 * @since 1.3.4
1322 *
1323 * @param bool $bool default value.
1324 *
1325 * @return bool
1326 */
1327 public function wp_doing_ajax( $bool ) {
1328 // Don't use Input::has helper to avoid conflict.
1329 if ( isset( $_REQUEST['tutor_ajax_action'] ) ) {
1330 return true;
1331 }
1332 return $bool;
1333 }
1334
1335 /**
1336 * Handle plugin un-installation
1337 *
1338 * @since 2.6.2
1339 *
1340 * @return void
1341 */
1342 public static function tutor_uninstall() {
1343 self::erase_tutor_data();
1344 }
1345
1346 /**
1347 * Erase tutor data
1348 *
1349 * @since 2.6.2
1350 *
1351 * @return void
1352 */
1353 public static function erase_tutor_data() {
1354 global $wpdb;
1355
1356 $is_erase_data = tutor_utils()->get_option( 'delete_on_uninstall' );
1357 // Deleting Data.
1358
1359 if ( $is_erase_data ) {
1360 /**
1361 * Deleting Post Type, Meta Data, taxonomy
1362 */
1363 $course_post_type = tutor()->course_post_type;
1364 $lesson_post_type = tutor()->lesson_post_type;
1365
1366 $post_types = array(
1367 $course_post_type,
1368 $lesson_post_type,
1369 'tutor_quiz',
1370 'tutor_enrolled',
1371 'topics',
1372 'tutor_enrolled',
1373 'tutor_announcements',
1374 );
1375
1376 $in_clause = QueryHelper::prepare_in_clause( $post_types );
1377 $tutor_posts = $wpdb->get_col( $wpdb->prepare( "SELECT ID from {$wpdb->posts} WHERE post_type IN({$in_clause}) ;" ) ); //phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
1378
1379 if ( is_array( $tutor_posts ) && count( $tutor_posts ) ) {
1380 foreach ( $tutor_posts as $post_id ) {
1381 // Delete categories.
1382 $terms = wp_get_object_terms( $post_id, CourseModel::COURSE_CATEGORY );
1383 foreach ( $terms as $term ) {
1384 wp_remove_object_terms( $post_id, array( $term->term_id ), CourseModel::COURSE_CATEGORY );
1385 }
1386
1387 // Delete tags if available.
1388 $terms = wp_get_object_terms( $post_id, CourseModel::COURSE_TAG );
1389 foreach ( $terms as $term ) {
1390 wp_remove_object_terms( $post_id, array( $term->term_id ), CourseModel::COURSE_TAG );
1391 }
1392
1393 // Delete All Meta.
1394 $wpdb->delete( $wpdb->postmeta, array( 'post_id' => $post_id ) );
1395 $wpdb->delete( $wpdb->posts, array( 'ID' => $post_id ) );
1396 }
1397 }
1398
1399 /**
1400 * Deleting Comments (reviews, questions, quiz_answers, etc)
1401 */
1402 $tutor_comments = $wpdb->get_col( "SELECT comment_ID from {$wpdb->comments} WHERE comment_agent = 'comment_agent' ;" );
1403 if ( is_array( $tutor_comments ) && count( $tutor_comments ) ) {
1404 $in_clause = QueryHelper::prepare_in_clause( $tutor_comments );
1405 $wpdb->query( $wpdb->prepare( "DELETE from {$wpdb->commentmeta} WHERE comment_ID in({$in_clause}) " ) ); //phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
1406 }
1407 $wpdb->delete( $wpdb->comments, array( 'comment_agent' => 'comment_agent' ) );
1408
1409 /**
1410 * Delete Options
1411 */
1412
1413 delete_option( 'tutor_option' );
1414 $wpdb->delete( $wpdb->usermeta, array( 'meta_key' => '_is_tutor_student' ) );
1415 $wpdb->delete( $wpdb->usermeta, array( 'meta_key' => '_tutor_instructor_approved' ) );
1416 $wpdb->delete( $wpdb->usermeta, array( 'meta_key' => '_tutor_instructor_status' ) );
1417 $wpdb->delete( $wpdb->usermeta, array( 'meta_key' => '_is_tutor_instructor' ) );
1418 $wpdb->query( "DELETE FROM {$wpdb->usermeta} WHERE meta_key LIKE '%_tutor_completed_lesson_id_%' " );
1419
1420 // Deleting Table.
1421 $prefix = $wpdb->prefix;
1422 //phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
1423 $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 " );
1424
1425 }
1426 }
1427
1428 /**
1429 * Update instructor capability
1430 *
1431 * Remove other author items permission
1432 *
1433 * @since 4.0.5
1434 *
1435 * @since 4.0.6 read_private_{items} permissions removed
1436 */
1437 public function update_instructor_capability() {
1438 // Remove edit_others content cap from tutor_instructor role.
1439 $is_removed_edit_other_items_permissions = get_option( 'tutor_removed_edit_other_items_permission', false );
1440 $is_removed_private_items_permissions = get_option( 'tutor_removed_read_private_items_permission', false );
1441
1442 $role = get_role( tutor()->instructor_role );
1443 if ( ! $is_removed_edit_other_items_permissions ) {
1444 $role = get_role( tutor()->instructor_role );
1445
1446 $caps_to_be_removed = array(
1447 'edit_others_tutor_courses',
1448 'edit_others_tutor_lessons',
1449 'edit_others_tutor_quizzes',
1450 'edit_others_tutor_questions',
1451 'edit_others_tutor_assignments',
1452 );
1453
1454 foreach ( $caps_to_be_removed as $cap ) {
1455 if ( $role->has_cap( $cap ) ) {
1456 $role->remove_cap( $cap );
1457 }
1458 }
1459
1460 update_option( 'tutor_removed_edit_other_items_permission', true, false );
1461 }
1462
1463 // Removed private items permission @since 4.0.6.
1464 if ( ! $is_removed_private_items_permissions ) {
1465 $caps_to_be_removed = array(
1466 'read_private_tutor_courses',
1467 'read_private_tutor_lessons',
1468 'read_private_tutor_quizzes',
1469 'read_private_tutor_assignments',
1470 'read_private_tutor_questions',
1471 );
1472
1473 foreach ( $caps_to_be_removed as $cap ) {
1474 if ( $role->has_cap( $cap ) ) {
1475 $role->remove_cap( $cap );
1476 }
1477 }
1478
1479 update_option( 'tutor_removed_read_private_items_permission', true, false );
1480 }
1481 }
1482 }
1483