PluginProbe
Tutor LMS – eLearning and online course solution / 1.7.0
Tutor LMS – eLearning and online course solution v1.7.0
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 All 191 releases
← All changes | classes/Tutor.php +667 -1482 trunk1.7.0 View file →
@@ -1,1482 +1,667 @@
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 -}
1 +<?php
2 +namespace TUTOR;
3 +
4 +if ( ! defined( 'ABSPATH' ) )
5 + exit;
6 +
7 +final class Tutor{
8 + public $version = TUTOR_VERSION;
9 + public $path;
10 + public $url;
11 + public $basename;
12 +
13 + /**
14 + * The single instance of the class.
15 + *
16 + * @since v.1.2.0
17 + */
18 + protected static $_instance = null;
19 +
20 + //Components
21 + public $utils;
22 + public $admin;
23 + public $ajax;
24 + public $options;
25 + public $shortcode;
26 +
27 + private $addons;
28 + private $post_types;
29 + private $taxonomies;
30 + private $assets;
31 + private $course;
32 + private $lesson;
33 + private $rewrite_rules;
34 + private $template;
35 + private $instructor;
36 + private $student;
37 + private $q_and_a;
38 + private $quiz;
39 + private $tools;
40 + private $user;
41 + private $theme_compatibility;
42 + private $gutenberg;
43 + private $course_settings_tabs;
44 + private $withdraw;
45 +
46 + private $course_widget;
47 + private $upgrader;
48 + private $dashboard;
49 + private $form_handler;
50 + private $frontend;
51 + private $email;
52 +
53 + //Integrations
54 + private $woocommerce;
55 + private $edd;
56 +
57 + /**
58 + * @return null|Tutor
59 + *
60 + * Run the TUTOR
61 + *
62 + * @since 1.2.0
63 + */
64 + public static function instance() {
65 + if ( is_null( self::$_instance ) ) {
66 + self::$_instance = new self();
67 + }
68 + return self::$_instance;
69 + }
70 +
71 + function __construct() {
72 +
73 + $this->path = plugin_dir_path(TUTOR_FILE);
74 + $this->url = plugin_dir_url(TUTOR_FILE);
75 + $this->basename = plugin_basename(TUTOR_FILE);
76 +
77 + /**
78 + * Adding Tutor Database table to $wpdb;
79 + * @since v.1.4.2
80 + */
81 + global $wpdb;
82 + $wpdb->tutor_earnings = $wpdb->prefix.'tutor_earnings';
83 + $wpdb->tutor_gradebooks = $wpdb->prefix.'tutor_gradebooks';
84 + $wpdb->tutor_gradebooks_results = $wpdb->prefix.'tutor_gradebooks_results';
85 + $wpdb->tutor_quiz_attempts = $wpdb->prefix.'tutor_quiz_attempts';
86 + $wpdb->tutor_quiz_attempt_answers = $wpdb->prefix.'tutor_quiz_attempt_answers';
87 + $wpdb->tutor_quiz_questions = $wpdb->prefix.'tutor_quiz_questions';
88 + $wpdb->tutor_quiz_question_answers = $wpdb->prefix.'tutor_quiz_question_answers';
89 + $wpdb->tutor_withdraws = $wpdb->prefix.'tutor_withdraws';
90 +
91 + /**
92 + * Changing default wp doing ajax return based on tutor ajax action
93 + */
94 + add_filter('wp_doing_ajax', array($this, 'wp_doing_ajax'));
95 +
96 + /**
97 + * Include Files
98 + */
99 + //add_action( 'init', array( $this, 'includes' ), 11 );
100 + $this->includes();
101 +
102 + /**
103 + * Loading Autoloader
104 + */
105 +
106 + if ( function_exists( '__autoload' ) ) {
107 + spl_autoload_register( '__autoload' );
108 + }
109 + spl_autoload_register(array($this, 'loader'));
110 +
111 + do_action('tutor_before_load');
112 +
113 + $this->addons = new Addons();
114 + $this->post_types = new Post_types();
115 + $this->taxonomies = new Taxonomies();
116 + $this->assets = new Assets();
117 + $this->admin = new Admin();
118 + $this->ajax = new Ajax();
119 + $this->options = new Options();
120 + $this->shortcode = new Shortcode();
121 + $this->course = new Course();
122 + $this->lesson = new Lesson();
123 + $this->rewrite_rules = new Rewrite_Rules();
124 + $this->template = new Template();
125 + $this->instructor = new Instructor();
126 + $this->student = new Student();
127 + $this->q_and_a = new Q_and_A();
128 + $this->quiz = new Quiz();
129 + $this->tools = new Tools();
130 + $this->user = new User();
131 + $this->theme_compatibility = new Theme_Compatibility();
132 + $this->gutenberg = new Gutenberg();
133 + $this->course_settings_tabs = new Course_Settings_Tabs();
134 + $this->withdraw = new Withdraw();
135 + $this->course_widget = new Course_Widget();
136 + $this->upgrader = new Upgrader();
137 + $this->dashboard = new Dashboard();
138 + $this->form_handler = new FormHandler();
139 + $this->frontend = new Frontend();
140 + $this->email = new Email();
141 + $this->rest_api = new RestAPI();
142 + $this->setup = new Tutor_Setup();
143 +
144 + //Integrations
145 + $this->woocommerce = new WooCommerce();
146 + $this->edd = new TutorEDD();
147 +
148 + /**
149 + * Run Method
150 + * @since v.1.2.0
151 + */
152 + $this->run();
153 +
154 + do_action('tutor_loaded');
155 +
156 + add_action( 'init', array( $this, 'init_action' ) );
157 +
158 + /**
159 + * redirect to the wizard page
160 + * @since v.1.5.7
161 + *
162 + */
163 +
164 + add_action( 'activated_plugin', array( $this, 'activated_tutor' ) );
165 + }
166 +
167 + /**
168 + * @param $plugin
169 + *
170 + * redirect to the wizard page
171 + * @since v.1.5.7
172 + *
173 + */
174 + public function activated_tutor( $plugin ) {
175 + if( $plugin == tutor()->basename ) {
176 + if( (! get_option('tutor_wizard') ) && version_compare(TUTOR_VERSION, '1.5.6', '>') ) {
177 + update_option('tutor_wizard', 'active');
178 + exit(wp_redirect(admin_url('admin.php?page=tutor-setup')));
179 + }
180 + }
181 + }
182 +
183 + /**
184 + * @param $className
185 + *
186 + * Auto Load class and the files
187 + */
188 + private function loader($className) {
189 + if ( ! class_exists($className)){
190 + $className = preg_replace(
191 + array('/([a-z])([A-Z])/', '/\\\/'),
192 + array('$1$2', DIRECTORY_SEPARATOR),
193 + $className
194 + );
195 +
196 + $className = str_replace('TUTOR'.DIRECTORY_SEPARATOR, 'classes'.DIRECTORY_SEPARATOR, $className);
197 + $file_name = $this->path.$className.'.php';
198 +
199 + if (file_exists($file_name) ) {
200 + require_once $file_name;
201 + }
202 + }
203 + }
204 +
205 + public function includes(){
206 + include tutor()->path.'includes/tutor-general-functions.php';
207 + include tutor()->path.'includes/tutor-template-functions.php';
208 + include tutor()->path.'includes/tutor-template-hook.php';
209 + }
210 +
211 + //Run the TUTOR right now
212 + public function run(){
213 + do_action('tutor_before_run');
214 +
215 + do_action('tutor_after_run');
216 + }
217 +
218 + /**
219 + * Tutor Action Via do_action
220 + * @since 1.2.14
221 + */
222 + public function init_action(){
223 + if (isset($_REQUEST['tutor_action'])){
224 + do_action('tutor_action_'.$_REQUEST['tutor_action']);
225 + }
226 + }
227 +
228 + /**
229 + * Do some task during plugin activation
230 + */
231 + public static function tutor_activate(){
232 + $version = get_option('tutor_version');
233 + if ( ! function_exists('tutor_time')){
234 + include tutor()->path.'includes/tutor-general-functions.php';
235 + }
236 + //Save Option
237 + if ( ! $version ){
238 + //Create Database
239 + self::create_database();
240 +
241 + $options = self::default_options();
242 + update_option('tutor_option', $options);
243 +
244 + //Rewrite Flush
245 + update_option('required_rewrite_flush', tutor_time());
246 + self::manage_tutor_roles_and_permissions();
247 +
248 + self::save_data();//Save initial Page
249 + update_option('tutor_version', TUTOR_VERSION);
250 + }
251 +
252 + //Set Schedule
253 + if (! wp_next_scheduled ( 'tutor_once_in_day_run_schedule' )) {
254 + wp_schedule_event(tutor_time(), 'twicedaily', 'tutor_once_in_day_run_schedule');
255 + }
256 +
257 + /**
258 + * Backward Compatibility for version < 1.2.0
259 + */
260 + if (version_compare(get_option('tutor_version'), '1.2.0', '<')){
261 + /**
262 + * Creating New Database
263 + */
264 + self::create_withdraw_database();
265 + //Update the tutor version
266 + update_option('tutor_version', '1.2.0');
267 + //Rewrite Flush
268 + update_option('required_rewrite_flush', tutor_time());
269 + }
270 +
271 + /**
272 + * Backward Compatibility to < 1.3.1 for make course plural
273 + */
274 + if (version_compare(get_option('tutor_version'), '1.3.1', '<')){
275 + global $wpdb;
276 +
277 + if ( ! get_option('is_course_post_type_updated')){
278 + $wpdb->update($wpdb->posts, array('post_type' => 'courses'), array('post_type' => 'course'));
279 + update_option('is_course_post_type_updated', true);
280 + update_option('tutor_version', '1.3.1');
281 + flush_rewrite_rules();
282 + }
283 + }
284 +
285 + /**
286 + * Save First activation Time
287 + */
288 + $first_activation_date = get_option('tutor_first_activation_time');
289 + if ( ! $first_activation_date){
290 + update_option('tutor_first_activation_time', tutor_time());
291 + }
292 + }
293 +
294 + //Run task on deactivation
295 + public static function tutor_deactivation() {
296 + wp_clear_scheduled_hook('tutor_once_in_day_run_schedule');
297 + }
298 +
299 + public static function create_database(){
300 + global $wpdb;
301 +
302 + $charset_collate = $wpdb->get_charset_collate();
303 +
304 + /**
305 + * Table SQL
306 + *
307 + * {$wpdb->prefix}tutor_quiz_attempts
308 + * {$wpdb->prefix}tutor_quiz_attempt_answers
309 + * {$wpdb->prefix}tutor_quiz_questions
310 + * {$wpdb->prefix}tutor_quiz_question_answers
311 + * {$wpdb->prefix}tutor_earnings
312 + * {$wpdb->prefix}tutor_withdraws
313 + *
314 + * @since v.1.0.0
315 + */
316 + $quiz_attempts_sql = "CREATE TABLE {$wpdb->prefix}tutor_quiz_attempts (
317 + attempt_id int(11) NOT NULL AUTO_INCREMENT,
318 + course_id int(11) DEFAULT NULL,
319 + quiz_id int(11) DEFAULT NULL,
320 + user_id int(11) DEFAULT NULL,
321 + total_questions int(11) DEFAULT NULL,
322 + total_answered_questions int(11) DEFAULT NULL,
323 + total_marks decimal(9,2) DEFAULT NULL,
324 + earned_marks decimal(9,2) DEFAULT NULL,
325 + attempt_info text,
326 + attempt_status varchar(50) DEFAULT NULL,
327 + attempt_ip varchar(250) DEFAULT NULL,
328 + attempt_started_at datetime DEFAULT NULL,
329 + attempt_ended_at datetime DEFAULT NULL,
330 + is_manually_reviewed int(1) DEFAULT NULL,
331 + manually_reviewed_at datetime DEFAULT NULL,
332 + PRIMARY KEY (attempt_id)
333 + ) $charset_collate;";
334 +
335 + $quiz_attempt_answers = "CREATE TABLE {$wpdb->prefix}tutor_quiz_attempt_answers (
336 + attempt_answer_id int(11) NOT NULL AUTO_INCREMENT,
337 + user_id int(11) DEFAULT NULL,
338 + quiz_id int(11) DEFAULT NULL,
339 + question_id int(11) DEFAULT NULL,
340 + quiz_attempt_id int(11) DEFAULT NULL,
341 + given_answer longtext,
342 + question_mark decimal(8,2) DEFAULT NULL,
343 + achieved_mark decimal(8,2) DEFAULT NULL,
344 + minus_mark decimal(8,2) DEFAULT NULL,
345 + is_correct tinyint(4) DEFAULT NULL,
346 + PRIMARY KEY (attempt_answer_id)
347 + ) $charset_collate;";
348 +
349 + $tutor_quiz_questions = "CREATE TABLE {$wpdb->prefix}tutor_quiz_questions (
350 + question_id int(11) NOT NULL AUTO_INCREMENT,
351 + quiz_id int(11) DEFAULT NULL,
352 + question_title text,
353 + question_description longtext,
354 + question_type varchar(50) DEFAULT NULL,
355 + question_mark decimal(9,2) DEFAULT NULL,
356 + question_settings longtext,
357 + question_order int(11) DEFAULT NULL,
358 + PRIMARY KEY (question_id)
359 + ) $charset_collate;";
360 +
361 + $tutor_quiz_question_answers = "CREATE TABLE {$wpdb->prefix}tutor_quiz_question_answers (
362 + answer_id int(11) NOT NULL AUTO_INCREMENT,
363 + belongs_question_id int(11) DEFAULT NULL,
364 + belongs_question_type varchar(250) DEFAULT NULL,
365 + answer_title text,
366 + is_correct tinyint(4) DEFAULT NULL,
367 + image_id int(11) DEFAULT NULL,
368 + answer_two_gap_match text,
369 + answer_view_format varchar(250) DEFAULT NULL,
370 + answer_settings text,
371 + answer_order int(11) DEFAULT '0',
372 + PRIMARY KEY (answer_id)
373 + ) $charset_collate;";
374 +
375 + $earning_table = "CREATE TABLE IF NOT EXISTS {$wpdb->prefix}tutor_earnings (
376 + earning_id int(11) NOT NULL AUTO_INCREMENT,
377 + user_id int(11) DEFAULT NULL,
378 + course_id int(11) DEFAULT NULL,
379 + order_id int(11) DEFAULT NULL,
380 + order_status varchar(50) DEFAULT NULL,
381 + course_price_total decimal(16,2) DEFAULT NULL,
382 + course_price_grand_total decimal(16,2) DEFAULT NULL,
383 + instructor_amount decimal(16,2) DEFAULT NULL,
384 + instructor_rate decimal(16,2) DEFAULT NULL,
385 + admin_amount decimal(16,2) DEFAULT NULL,
386 + admin_rate decimal(16,2) DEFAULT NULL,
387 + commission_type varchar(20) DEFAULT NULL,
388 + deduct_fees_amount decimal(16,2) DEFAULT NULL,
389 + deduct_fees_name varchar(250) DEFAULT NULL,
390 + deduct_fees_type varchar(20) DEFAULT NULL,
391 + process_by varchar(20) DEFAULT NULL,
392 + created_at datetime DEFAULT NULL,
393 + PRIMARY KEY (earning_id)
394 + ) $charset_collate;";
395 +
396 + $withdraw_table = "CREATE TABLE IF NOT EXISTS {$wpdb->prefix}tutor_withdraws (
397 + withdraw_id int(11) NOT NULL AUTO_INCREMENT,
398 + user_id int(11) DEFAULT NULL,
399 + amount decimal(16,2) DEFAULT NULL,
400 + method_data text DEFAULT NULL,
401 + status varchar(50) DEFAULT NULL,
402 + updated_at datetime DEFAULT NULL,
403 + created_at datetime DEFAULT NULL,
404 + PRIMARY KEY (withdraw_id)
405 + ) $charset_collate;";
406 +
407 + require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
408 + dbDelta( $quiz_attempts_sql );
409 + dbDelta( $quiz_attempt_answers );
410 + dbDelta( $tutor_quiz_questions );
411 + dbDelta( $tutor_quiz_question_answers );
412 + dbDelta( $earning_table );
413 + dbDelta( $withdraw_table );
414 + }
415 +
416 + public static function manage_tutor_roles_and_permissions(){
417 + /**
418 + * Add role for instructor
419 + */
420 + $instructor_role = tutor()->instructor_role;
421 +
422 + remove_role($instructor_role);
423 + add_role( $instructor_role, __('Tutor Instructor', 'tutor'), array() );
424 +
425 + $custom_post_type_permission = array(
426 + //Manage Instructor
427 + 'manage_tutor_instructor',
428 +
429 + //Tutor Posts Type Permission
430 + 'edit_tutor_course',
431 + 'read_tutor_course',
432 + 'delete_tutor_course',
433 + 'delete_tutor_courses',
434 + 'edit_tutor_courses',
435 + 'edit_others_tutor_courses',
436 + 'read_private_tutor_courses',
437 + 'edit_tutor_courses',
438 +
439 + 'edit_tutor_lesson',
440 + 'read_tutor_lesson',
441 + 'delete_tutor_lesson',
442 + 'delete_tutor_lessons',
443 + 'edit_tutor_lessons',
444 + 'edit_others_tutor_lessons',
445 + 'read_private_tutor_lessons',
446 + 'edit_tutor_lessons',
447 + 'publish_tutor_lessons',
448 +
449 + 'edit_tutor_quiz',
450 + 'read_tutor_quiz',
451 + 'delete_tutor_quiz',
452 + 'delete_tutor_quizzes',
453 + 'edit_tutor_quizzes',
454 + 'edit_others_tutor_quizzes',
455 + 'read_private_tutor_quizzes',
456 + 'edit_tutor_quizzes',
457 + 'publish_tutor_quizzes',
458 +
459 + 'edit_tutor_question',
460 + 'read_tutor_question',
461 + 'delete_tutor_question',
462 + 'delete_tutor_questions',
463 + 'edit_tutor_questions',
464 + 'edit_others_tutor_questions',
465 + 'publish_tutor_questions',
466 + 'read_private_tutor_questions',
467 + 'edit_tutor_questions',
468 + );
469 +
470 + $instructor = get_role( $instructor_role );
471 + if ( $instructor ) {
472 + $instructor_cap = array (
473 + 'edit_posts',
474 + 'read',
475 + 'upload_files',
476 + );
477 +
478 + $instructor_cap = array_merge($instructor_cap, $custom_post_type_permission);
479 +
480 + $can_publish_course = (bool) tutor_utils()->get_option('instructor_can_publish_course');
481 + if ($can_publish_course){
482 + $instructor_cap[] = 'publish_tutor_courses';
483 + }
484 +
485 + foreach ($instructor_cap as $cap){
486 + $instructor->add_cap( $cap );
487 + }
488 + }
489 +
490 + $administrator = get_role( 'administrator' );
491 + if ( $administrator ) {
492 +
493 + $administrator_cap = array (
494 + 'manage_tutor',
495 + );
496 + $administrator_cap = array_merge($administrator_cap, $custom_post_type_permission);
497 + $administrator_cap[] = 'publish_tutor_courses';
498 +
499 + foreach ($administrator_cap as $cap){
500 + $administrator->add_cap( $cap );
501 + }
502 + }
503 +
504 + /**
505 + * Add Instructor role to administrator
506 + */
507 + if (current_user_can('administrator')){
508 + tutor_utils()->add_instructor_role(get_current_user_id());
509 + }
510 +
511 + }
512 +
513 + /**
514 + * Save data like page
515 + */
516 + public static function save_data(){
517 + $student_dashboard_args = array(
518 + 'post_title' => __('Dashboard', 'tutor'),
519 + 'post_content' => '',
520 + 'post_type' => 'page',
521 + 'post_status' => 'publish',
522 + );
523 + $student_dashboard_page_id = wp_insert_post( $student_dashboard_args );
524 + tutor_utils()->update_option('tutor_dashboard_page_id', $student_dashboard_page_id);
525 +
526 + $student_registration_args = array(
527 + 'post_title' => __('Student Registration', 'tutor'),
528 + 'post_content' => '[tutor_student_registration_form]',
529 + 'post_type' => 'page',
530 + 'post_status' => 'publish',
531 + );
532 + $student_register_page_id = wp_insert_post( $student_registration_args );
533 + tutor_utils()->update_option('student_register_page', $student_register_page_id);
534 +
535 + $instructor_registration_args = array(
536 + 'post_title' => __('Instructor Registration', 'tutor'),
537 + 'post_content' => '[tutor_instructor_registration_form]',
538 + 'post_type' => 'page',
539 + 'post_status' => 'publish',
540 + );
541 + $instructor_registration_id = wp_insert_post( $instructor_registration_args );
542 + tutor_utils()->update_option('instructor_register_page', $instructor_registration_id);
543 + }
544 +
545 + public static function default_options(){
546 + $options = array (
547 + 'pagination_per_page' => '20',
548 + 'load_tutor_css' => '1',
549 + 'load_tutor_js' => '1',
550 + 'course_allow_upload_private_files' => '1',
551 + 'display_course_instructors' => '1',
552 + 'enable_q_and_a_on_course' => '1',
553 + 'courses_col_per_row' => '3',
554 + 'courses_per_page' => '3',
555 + 'lesson_permalink_base' => 'lesson',
556 + 'quiz_time_limit' =>
557 + array (
558 + 'value' => '0',
559 + 'time' => 'minutes',
560 + ),
561 + 'quiz_when_time_expires' => 'autosubmit',
562 + 'quiz_attempts_allowed' => '10',
563 + 'quiz_grade_method' => 'highest_grade',
564 + 'enable_public_profile' => '1',
565 + 'email_to_students' =>
566 + array (
567 + 'quiz_completed' => '1',
568 + 'completed_course' => '1',
569 + ),
570 + 'email_to_instructors' =>
571 + array (
572 + 'a_student_enrolled_in_course' => '1',
573 + 'a_student_completed_course' => '1',
574 + 'a_student_completed_lesson' => '1',
575 + 'a_student_placed_question' => '1',
576 + ),
577 + 'email_from_name' => get_option('blogname'),
578 + 'email_from_address' => get_option('admin_email'),
579 + 'email_footer_text' => '',
580 + 'earning_admin_commission' => '20',
581 + 'earning_admin_commission' => '20',
582 + 'earning_instructor_commission' => '80'
583 + );
584 + return $options;
585 + }
586 +
587 +
588 + /**
589 + * Create withdraw database
590 + *
591 + * @since v.1.2.0
592 + */
593 + public static function create_withdraw_database(){
594 + global $wpdb;
595 +
596 + $charset_collate = $wpdb->get_charset_collate();
597 +
598 + /**
599 + * Table SQL
600 + *
601 + * {$wpdb->prefix}tutor_earnings
602 + * {$wpdb->prefix}tutor_withdraws
603 + *
604 + * @since v.1.2.0
605 + */
606 +
607 + $earning_table = "CREATE TABLE IF NOT EXISTS {$wpdb->prefix}tutor_earnings (
608 + earning_id int(11) NOT NULL AUTO_INCREMENT,
609 + user_id int(11) DEFAULT NULL,
610 + course_id int(11) DEFAULT NULL,
611 + order_id int(11) DEFAULT NULL,
612 + order_status varchar(50) DEFAULT NULL,
613 + course_price_total decimal(16,2) DEFAULT NULL,
614 + course_price_grand_total decimal(16,2) DEFAULT NULL,
615 + instructor_amount decimal(16,2) DEFAULT NULL,
616 + instructor_rate decimal(16,2) DEFAULT NULL,
617 + admin_amount decimal(16,2) DEFAULT NULL,
618 + admin_rate decimal(16,2) DEFAULT NULL,
619 + commission_type varchar(20) DEFAULT NULL,
620 + deduct_fees_amount decimal(16,2) DEFAULT NULL,
621 + deduct_fees_name varchar(250) DEFAULT NULL,
622 + deduct_fees_type varchar(20) DEFAULT NULL,
623 + process_by varchar(20) DEFAULT NULL,
624 + created_at datetime DEFAULT NULL,
625 + PRIMARY KEY (earning_id)
626 + ) $charset_collate;";
627 +
628 + $withdraw_table = "CREATE TABLE IF NOT EXISTS {$wpdb->prefix}tutor_withdraws (
629 + withdraw_id int(11) NOT NULL AUTO_INCREMENT,
630 + user_id int(11) DEFAULT NULL,
631 + amount decimal(16,2) DEFAULT NULL,
632 + method_data text DEFAULT NULL,
633 + status varchar(50) DEFAULT NULL,
634 + updated_at datetime DEFAULT NULL,
635 + created_at datetime DEFAULT NULL,
636 + PRIMARY KEY (withdraw_id)
637 + ) $charset_collate;";
638 +
639 + require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
640 + dbDelta( $earning_table );
641 + dbDelta( $withdraw_table );
642 +
643 + /**
644 + * Setting previous dashboard to new dashboard
645 + */
646 + $previous_dashboard_page_id = (int) tutor_utils()->get_option('student_dashboard');
647 + tutor_utils()->update_option('tutor_dashboard_page_id', $previous_dashboard_page_id);
648 + }
649 +
650 + /**
651 + * @param $bool
652 + *
653 + * @return bool
654 + *
655 + * Filter the wp_doing_ajax from tutor requests to get advanced advantages from Tutor
656 + *
657 + * @since v.1.3.4
658 + */
659 + public function wp_doing_ajax($bool){
660 + if (isset($_REQUEST['tutor_ajax_action'])){
661 + return true;
662 + }
663 + return $bool;
664 + }
665 +
666 +
667 +}